[
  {
    "path": ".gitattributes",
    "content": "*.html.tera linguist-language=HTML\n"
  },
  {
    "path": ".github/.well-known/funding-manifest-urls",
    "content": "https://www.sea-ql.org/funding.json\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "github: SeaQL"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.md",
    "content": "---\nname: Bug Report\nabout: Report a bug or design flaw\ntitle: \"\"\nlabels: \"\"\nassignees: \"\"\ntype: Bug\n---\n\n<!--\n\nWelcome! Thank you for reporting bugs!\n\nFirst of all, please star our repo. Your support is vital to the continued maintenance of SeaORM.\n\nWant to ask a question? You can reach us via:\n\n- Discord: https://discord.com/invite/uCPdDXzbdv\n- GitHub Discussions: https://github.com/SeaQL/sea-orm/discussions/new\n\nPlease make sure that you are not asking for a missing feature; a bug is incorrect behavior -\neither in the feature specification or implementation. Feature requests should be first raised in discussions.\n\nPlease also make sure your description is clear and precise - maintainers don't have access to your\ncode and can't see what you have seen. Please avoid vague descriptions like \"they are different\"\nor \"the program crashes\" - in either case, provide exact information.\n\nIf you are certain there is a bug, please provide a reproducible example, which helps the investigator\nto pin-point the bug and the implementor to verify that a solution is satisfactory. Bug reports without\nreproducible example may be closed or dangle forever.\n\nFinally, please search for existing issues and discussions before submission. Feel free to revive old\nthreads if you have new information to add, but please don't ask for ETA or \"+1\".\n\n-->\n\n## Description\n\n<!-- Briefly describe the bug -->\n\n## Steps to Reproduce\n\n1. <!-- First step -->\n2. <!-- Then -->\n3. <!-- And so on -->\n\n### Expected Behavior\n\n<!-- What is expected to happen? -->\n\n### Actual Behavior\n\n<!-- What actually happened? -->\n\n### Reproduces How Often\n\n<!-- Is it always reproducible? -->\n\n### Workarounds\n\n<!-- What experiments have you done to understand / workaround the bug? -->\n\n## Versions\n\n<!-- You can get this information from the output of `cargo tree | grep sea-` from the console. Also, please include the database and OS that you are running. -->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: Q & A\n    url: https://github.com/SeaQL/sea-orm/discussions/new?category=q-a\n    about: Ask a question or look for help. Try to provide sufficient context, snippets to reproduce and error messages.\n  - name: SeaQL Discord Server\n    url: https://discord.com/invite/uCPdDXzbdv\n    about: Join our Discord server to chat with others in the SeaQL community!\n  - name: Professional Support\n    url: https://github.com/sponsors/SeaQL\n    about: Startup and Enterprise-tier sponsors enjoy direct communication with the SeaQL team and professional support for SeaORM usage, data engineering, and Rust development."
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.md",
    "content": "---\nname: Feature Request\nabout: Suggest a new feature for this project\ntitle: \"\"\nlabels: \"\"\nassignees: \"\"\ntype: Feature\n---\n\n<!--\n\nWelcome! Thank you for suggesting features!\n\nFirst of all, please star our repo. Your support is vital to the continued maintenance of SeaORM.\n\nWant to ask a question? You can reach us via:\n\n- Discord: https://discord.com/invite/uCPdDXzbdv\n- GitHub Discussions: https://github.com/SeaQL/sea-orm/discussions/new\n\nMake sure you have a clear feature specification before open an issue. Alternatively, please start an \"Idea\" thread on GitHub Discussions and let's formulate the solution together.\n\n-->\n\n## Motivation\n\n<!-- what is the use case? what is the expected outcome? -->\n\n## Proposed Solutions\n\n<!-- what are the proposed solutions? how it solve the problem or achieve the goal? -->\n\n## Additional Information\n\n<!-- any other additional information that might be helpful -->\n"
  },
  {
    "path": ".github/workflows/release-bot.yml",
    "content": "name: Release Bot\n\non:\n  release:\n    types: [published]\n\njobs:\n  comment:\n    runs-on: ubuntu-latest\n    permissions:\n      issues: write\n      pull-requests: write\n    steps:\n      - name: Commenting on `${{ github.event.release.tag_name }}` release\n        uses: billy1624/release-comment-on-pr@master\n        with:\n          release-tag: ${{ github.event.release.tag_name }}\n          token: ${{ github.token }}\n          message: |\n            ### :tada: Released In [${releaseTag}](${releaseUrl}) :tada:\n            \n            Huge thanks for the contribution!\n            This feature has now been released, so it's a great time to upgrade.\n            Show some love with a ⭐ on our repo, every star counts!\n"
  },
  {
    "path": ".github/workflows/rust.yml",
    "content": "# GitHub Actions with Conditional Job Running Based on Commit Message\n#\n# --------------------------------------------------------------------------------\n#\n# Following jobs will always run\n#\n#   - `clippy`\n#   - `rustfmt`\n#   - `taplo`\n#   - `test`\n#   - `examples`\n#\n# Following jobs will be run when no keywords were found in commit message)\n#\n#   - `sqlite`\n#   - `mysql`\n#   - `mariadb`\n#   - `postgres`\n#\n# Following jobs will be run if keywords `[issues]` were found in commit message\n#\n#   - Jobs that will always run\n#   - `issues`\n#\n# Following jobs will be run if keywords `[cli]` were found in commit message\n#\n#   - Jobs that will always run\n#   - `cli`\n#\n# Following jobs will be run if keywords `[sqlite]` were found in commit message\n#\n#   - Jobs that will always run\n#   - `compile`\n#   - `sqlite`\n#\n# Following jobs will be run if keywords `[mysql]` were found in commit message\n#\n#   - Jobs that will always run\n#   - `compile`\n#   - `mysql`\n#   - `mariadb`\n#\n# Following jobs will be run if keywords `[postgres]` were found in commit message\n#\n#   - Jobs that will always run\n#   - `compile`\n#   - `postgres`\n\nname: tests\n\non:\n  pull_request:\n    paths-ignore:\n      - \"**.md\"\n      - \".github/ISSUE_TEMPLATE/**\"\n  push:\n    paths-ignore:\n      - \"**.md\"\n      - \".github/ISSUE_TEMPLATE/**\"\n    branches:\n      - master\n      - 1.*.x\n      - 0.*.x\n      - pr/**/ci\n      - ci-*\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.head_ref || github.ref || github.run_id }}\n  cancel-in-progress: true\n\nenv:\n  CARGO_TERM_COLOR: always\n  RUSTC_WRAPPER: sccache\n  SCCACHE_GHA_ENABLED: true\n  RUSTFLAGS: \"-C debuginfo=0\"\n  CARGO_INCREMENTAL: 0\n\njobs:\n  init:\n    name: Init\n    runs-on: ubuntu-latest\n    outputs:\n      run-sqlite: ${{ contains(steps.git-log.outputs.message, '[sqlite]') }}\n      run-mysql: ${{ contains(steps.git-log.outputs.message, '[mysql]') }}\n      run-postgres: ${{ contains(steps.git-log.outputs.message, '[postgres]') }}\n      run-cli: ${{ contains(steps.git-log.outputs.message, '[cli]') }}\n      run-issues: ${{ contains(steps.git-log.outputs.message, '[issues]') }}\n      run-partial: >-\n        ${{\n          contains(steps.git-log.outputs.message, '[sqlite]') ||\n          contains(steps.git-log.outputs.message, '[mysql]') ||\n          contains(steps.git-log.outputs.message, '[postgres]') ||\n          contains(steps.git-log.outputs.message, '[cli]') ||\n          contains(steps.git-log.outputs.message, '[issues]')\n        }}\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n      - id: git-log\n        run: echo \"message=$(git log --no-merges -1 --oneline)\" >> $GITHUB_OUTPUT\n\n  clippy:\n    name: Clippy\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          components: clippy\n      - uses: actions/cache@v5\n        with:\n          path: |\n            ~/.cargo/registry/index/\n            ~/.cargo/registry/cache/\n            ~/.cargo/git/db/\n          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}\n      - uses: mozilla-actions/sccache-action@v0.0.9\n      - run: cargo clippy --all -- -D warnings\n      - run: cargo clippy --all --features runtime-tokio-native-tls,sqlx-all -- -D warnings\n      - run: cargo clippy --manifest-path sea-orm-cli/Cargo.toml -- -D warnings\n      - run: cargo clippy --manifest-path sea-orm-migration/Cargo.toml -- -D warnings\n\n  rustfmt:\n    name: Rustfmt\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@nightly\n        with:\n          components: rustfmt\n      - run: cargo fmt --all -- --check\n      - run: cargo fmt --manifest-path sea-orm-cli/Cargo.toml --all -- --check\n      - run: cargo fmt --manifest-path sea-orm-migration/Cargo.toml --all -- --check\n\n  taplo:\n    name: Taplo\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@stable\n      - uses: mozilla-actions/sccache-action@v0.0.9\n      - run: cargo install --locked taplo-cli\n      - run: taplo fmt --check \n\n  compile:\n    name: Compile (${{ matrix.label }})\n    needs: init\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        include:\n          - label: build\n            kind: build\n          - label: tokio native-tls mysql\n            kind: test\n            features: sqlx-mysql,runtime-tokio-native-tls\n          - label: tokio rustls mysql\n            kind: test\n            features: sqlx-mysql,runtime-tokio-rustls\n          - label: tokio native-tls postgres\n            kind: test\n            features: sqlx-postgres,runtime-tokio-native-tls\n          - label: tokio rustls postgres\n            kind: test\n            features: sqlx-postgres,runtime-tokio-rustls\n          - label: tokio sqlite\n            kind: test\n            features: sqlx-sqlite,runtime-tokio\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@stable\n      - uses: actions/cache@v5\n        with:\n          path: |\n            ~/.cargo/registry/index/\n            ~/.cargo/registry/cache/\n            ~/.cargo/git/db/\n          key: ${{ runner.os }}-cargo-compile-${{ matrix.label }}-${{ hashFiles('**/Cargo.toml') }}\n      - uses: mozilla-actions/sccache-action@v0.0.9\n      - if: matrix.kind == 'build'\n        run: |\n          cargo build --no-default-features\n          cargo build --no-default-features --features seaography\n          cargo build --features rbac,schema-sync\n      - if: matrix.kind == 'test'\n        run: cargo test --test '*' --features tests-features,${{ matrix.features }} --no-run\n\n  test:\n    name: Unit Test\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@stable\n      - uses: actions/cache@v5\n        with:\n          path: |\n            ~/.cargo/registry/index/\n            ~/.cargo/registry/cache/\n            ~/.cargo/git/db/\n          key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.toml') }}\n      - uses: mozilla-actions/sccache-action@v0.0.9\n      - run: cargo test --workspace --no-run\n      - run: cargo test --workspace\n      - run: cargo test --lib --features rbac\n      - run: cargo test --lib --features entity-registry -- registry\n      - run: cargo test --manifest-path sea-orm-cli/Cargo.toml --no-run\n      - run: cargo test --manifest-path sea-orm-cli/Cargo.toml\n\n  cli:\n    name: CLI\n    needs: init\n    if: ${{ (needs.init.outputs.run-partial == 'true' && needs.init.outputs.run-cli == 'true') }}\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@stable\n      - run: cargo install --path sea-orm-cli --debug\n\n  examples:\n    name: Examples\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        path:\n          [\n            actix_example,\n            axum_example,\n            basic,\n            graphql_example,\n            jsonrpsee_example,\n            loco_example,\n            loco_seaography,\n            loco_starter,\n            parquet_example,\n            poem_example,\n            proxy_gluesql_example,\n            quickstart,\n            react_admin,\n            rocket_example,\n            rocket_okapi_example,\n            salvo_example,\n            seaography_example,\n            tonic_example,\n          ]\n    steps:\n      - uses: actions/checkout@v4\n      - if: ${{ contains(matrix.path, 'tonic_example') }}\n        uses: arduino/setup-protoc@v3\n      - uses: dtolnay/rust-toolchain@stable\n        with:\n          components: rustfmt\n      - uses: actions/cache@v5\n        with:\n          path: |\n            ~/.cargo/registry/index/\n            ~/.cargo/registry/cache/\n            ~/.cargo/git/db/\n          key: ${{ runner.os }}-cargo-examples-${{ matrix.path }}\n      - uses: mozilla-actions/sccache-action@v0.0.9\n      - working-directory: ./examples/\n        run: |\n          find ${{ matrix.path }} -type f -name 'Cargo.toml' -print0 | xargs -t -0 -I {} cargo fmt --manifest-path {} -- --check\n          find ${{ matrix.path }} -type f -name 'Cargo.toml' -print0 | xargs -t -0 -I {} cargo update --manifest-path {}\n          find ${{ matrix.path }} -type f -name 'Cargo.toml' -print0 | xargs -t -0 -I {} cargo test --manifest-path {}\n          ${{'! '}}${{ '[ -d \"' }}${{ matrix.path }}${{ '/api\" ]' }} || find ${{ matrix.path }}/api -type f -name 'Cargo.toml' -print0 | xargs -t -0 -I {} cargo test --manifest-path {}\n      - if: matrix.path == 'quickstart'\n        working-directory: ./examples/${{ matrix.path }}\n        run: cargo run\n\n  issues-matrix:\n    name: Issues Matrix\n    needs: init\n    if: ${{ (needs.init.outputs.run-partial == 'true' && needs.init.outputs.run-issues == 'true') }}\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - id: set-matrix\n        run: echo \"path_matrix=$(find issues -type f -name 'Cargo.toml' -printf '%P\\0' | jq -Rc '[  split(\"\\u0000\") | .[] | \"issues/\\(.)\" ]')\" >> $GITHUB_OUTPUT\n    outputs:\n      path_matrix: ${{ steps.set-matrix.outputs.path_matrix }}\n\n  issues:\n    name: Issues\n    needs:\n      - init\n      - issues-matrix\n    if: ${{ (needs.init.outputs.run-partial == 'true' && needs.init.outputs.run-issues == 'true') }}\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        path: ${{ fromJson(needs.issues-matrix.outputs.path_matrix) }}\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@stable\n      - uses: actions/cache@v5\n        with:\n          path: |\n            ~/.cargo/registry/index/\n            ~/.cargo/registry/cache/\n            ~/.cargo/git/db/\n          key: ${{ runner.os }}-cargo-issue-${{ matrix.path }}\n      - uses: mozilla-actions/sccache-action@v0.0.9\n      - run: cargo build --manifest-path ${{ matrix.path }}\n      - run: cargo test --manifest-path ${{ matrix.path }}\n\n  sqlite:\n    name: SQLite\n    needs:\n      - init\n      - compile\n    if: >-\n      ${{\n        needs.init.outputs.run-partial == 'false' ||\n        (needs.init.outputs.run-partial == 'true' && needs.init.outputs.run-sqlite == 'true')\n      }}\n    runs-on: ubuntu-latest\n    env:\n      DATABASE_URL: \"sqlite::memory:\"\n    strategy:\n      fail-fast: false\n      matrix:\n        runtime: [tokio]\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@stable\n      - uses: actions/cache@v5\n        with:\n          path: |\n            ~/.cargo/registry/index/\n            ~/.cargo/registry/cache/\n            ~/.cargo/git/db/\n          key: ${{ runner.os }}-cargo-sqlite-tests-sqlite-${{ hashFiles('**/Cargo.toml') }}\n      - uses: mozilla-actions/sccache-action@v0.0.9\n      - run: cargo test --test '*' --features tests-features,sqlx-sqlite,runtime-${{ matrix.runtime }} --no-run\n      - run: cargo test --test '*' --features tests-features,sqlx-sqlite,runtime-${{ matrix.runtime }}\n      - run: cargo test --manifest-path sea-orm-migration/Cargo.toml --test '*' --features sqlx-sqlite,runtime-${{ matrix.runtime }} --no-run\n      - run: cargo test --manifest-path sea-orm-migration/Cargo.toml --test '*' --features sqlx-sqlite,runtime-${{ matrix.runtime }}\n\n  rusqlite:\n    name: rusqlite\n    needs:\n      - init\n      - compile\n    if: >-\n      ${{\n        needs.init.outputs.run-partial == 'false' ||\n        (needs.init.outputs.run-partial == 'true' && needs.init.outputs.run-sqlite == 'true')\n      }}\n    runs-on: ubuntu-latest\n    env:\n      DATABASE_URL: \"sqlite::memory:\"\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@stable\n      - uses: actions/cache@v5\n        with:\n          path: |\n            ~/.cargo/registry/index/\n            ~/.cargo/registry/cache/\n            ~/.cargo/git/db/\n          key: ${{ runner.os }}-cargo-sqlite-tests-rusqlite-${{ hashFiles('**/Cargo.toml') }}\n      - uses: mozilla-actions/sccache-action@v0.0.9\n      - working-directory: ./sea-orm-sync\n        run: cargo test --test '*' --features tests-features,rusqlite\n      - working-directory: ./sea-orm-sync/examples/quickstart\n        run: cargo run\n      - working-directory: ./sea-orm-sync/examples/parquet_example\n        run: cargo run\n\n  mysql:\n    name: MySQL\n    needs:\n      - init\n      - compile\n    if: >-\n      ${{\n        needs.init.outputs.run-partial == 'false' ||\n        (needs.init.outputs.run-partial == 'true' && needs.init.outputs.run-mysql == 'true')\n      }}\n    runs-on: ubuntu-latest\n    env:\n      DATABASE_URL: \"mysql://root:@localhost\"\n    strategy:\n      fail-fast: false\n      matrix:\n        version: [lts, 5.7]\n        runtime: [tokio]\n        tls: [native-tls]\n    services:\n      mysql:\n        image: mysql:${{ matrix.version }}\n        env:\n          MYSQL_HOST: 127.0.0.1\n          MYSQL_DB: mysql\n          MYSQL_USER: sea\n          MYSQL_PASSWORD: sea\n          MYSQL_ALLOW_EMPTY_PASSWORD: yes\n        ports:\n          - \"3306:3306\"\n        options: >-\n          --health-cmd=\"mysqladmin ping\"\n          --health-interval=10s\n          --health-timeout=5s\n          --health-retries=3\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@stable\n      - uses: actions/cache@v5\n        with:\n          path: |\n            ~/.cargo/registry/index/\n            ~/.cargo/registry/cache/\n            ~/.cargo/git/db/\n          key: ${{ runner.os }}-cargo-mysql-tests-${{ hashFiles('**/Cargo.toml') }}\n      - uses: mozilla-actions/sccache-action@v0.0.9\n      - run: cargo test --test '*' --features tests-features,sqlx-mysql,runtime-${{ matrix.runtime }}-${{ matrix.tls }} --no-run\n      - run: cargo test --test '*' --features tests-features,sqlx-mysql,runtime-${{ matrix.runtime }}-${{ matrix.tls }}\n      - run: cargo test --manifest-path sea-orm-migration/Cargo.toml --test '*' --features sqlx-mysql,runtime-${{ matrix.runtime }}-${{ matrix.tls }} --no-run\n      - run: cargo test --manifest-path sea-orm-migration/Cargo.toml --test '*' --features sqlx-mysql,runtime-${{ matrix.runtime }}-${{ matrix.tls }}\n\n  mariadb:\n    name: MariaDB\n    needs:\n      - init\n      - compile\n    if: >-\n      ${{\n        needs.init.outputs.run-partial == 'false' ||\n        (needs.init.outputs.run-partial == 'true' && needs.init.outputs.run-mysql == 'true')\n      }}\n    runs-on: ubuntu-latest\n    env:\n      DATABASE_URL: \"mysql://root:@localhost\"\n    strategy:\n      fail-fast: false\n      matrix:\n        version: [lts]\n        runtime: [tokio]\n        tls: [native-tls]\n    services:\n      mariadb:\n        image: mariadb:${{ matrix.version }}\n        env:\n          MARIADB_HOST: 127.0.0.1\n          MARIADB_DB: mysql\n          MARIADB_USER: sea\n          MARIADB_PASSWORD: sea\n          MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: yes\n        ports:\n          - \"3306:3306\"\n        options: >-\n          --health-cmd=\"healthcheck.sh\n          --connect\n          --innodb_initialized\"\n          --health-interval=10s\n          --health-timeout=5s\n          --health-retries=3\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@stable\n      - uses: actions/cache@v5\n        with:\n          path: |\n            ~/.cargo/registry/index/\n            ~/.cargo/registry/cache/\n            ~/.cargo/git/db/\n          key: ${{ runner.os }}-cargo-mariadb-tests-${{ hashFiles('**/Cargo.toml') }}\n      - uses: mozilla-actions/sccache-action@v0.0.9\n      - run: cargo test --test '*' --features tests-features,sqlx-mysql,runtime-${{ matrix.runtime }}-${{ matrix.tls }} --no-run\n      - run: cargo test --test '*' --features tests-features,sqlx-mysql,runtime-${{ matrix.runtime }}-${{ matrix.tls }}\n\n  postgres:\n    name: Postgres\n    needs:\n      - init\n      - compile\n    if: >-\n      ${{\n        needs.init.outputs.run-partial == 'false' ||\n        (needs.init.outputs.run-partial == 'true' && needs.init.outputs.run-postgres == 'true')\n      }}\n    runs-on: ubuntu-latest\n    env:\n      DATABASE_URL: \"postgres://root:root@localhost\"\n    strategy:\n      fail-fast: false\n      matrix:\n        version: [14, 16]\n        runtime: [tokio]\n        tls: [native-tls]\n    services:\n      postgres:\n        image: postgres:${{ matrix.version }}\n        env:\n          POSTGRES_HOST: 127.0.0.1\n          POSTGRES_USER: root\n          POSTGRES_PASSWORD: root\n        ports:\n          - \"5432:5432\"\n        options: >-\n          --health-cmd pg_isready\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n    steps:\n      - uses: actions/checkout@v4\n      - uses: dtolnay/rust-toolchain@stable\n      - uses: actions/cache@v5\n        with:\n          path: |\n            ~/.cargo/registry/index/\n            ~/.cargo/registry/cache/\n            ~/.cargo/git/db/\n          key: ${{ runner.os }}-postgres-tests-${{ matrix.runtime }}-${{ matrix.tls }}-${{ hashFiles('**/Cargo.toml') }}\n      - uses: mozilla-actions/sccache-action@v0.0.9\n      - run: cargo test --test '*' --features tests-features,sqlx-postgres,runtime-${{ matrix.runtime }}-${{ matrix.tls }} --no-run\n      - run: cargo test --test '*' --features tests-features,sqlx-postgres,runtime-${{ matrix.runtime }}-${{ matrix.tls }}\n      - run: cargo test --manifest-path sea-orm-migration/Cargo.toml --test '*' --features sqlx-postgres,runtime-${{ matrix.runtime }}-${{ matrix.tls }} --no-run\n      - run: cargo test --manifest-path sea-orm-migration/Cargo.toml --test '*' --features sqlx-postgres,runtime-${{ matrix.runtime }}-${{ matrix.tls }}\n"
  },
  {
    "path": ".gitignore",
    "content": "target\nfiredbg\nCargo.lock\n*.sublime*\n.vscode\n.idea/*\n*/.idea/*\n.env.local\n.DS_Store"
  },
  {
    "path": ".rustfmt.toml",
    "content": "format_code_in_doc_comments = true\nignore = [\n    # These files are used to test the output of derive macros.\n    # Formatting them will cause the tests to fail.\n    \"sea-orm-codegen/src/tests_cfg\",\n]\n"
  },
  {
    "path": ".taplo.toml",
    "content": "include = [\"**/*.toml\"]\n\n[formatting]\nalign_entries       = true\nallowed_blank_lines = 1\narray_auto_collapse = false\nindent_string       = '    '\nreorder_keys        = true\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](http://keepachangelog.com/)\nand this project adheres to [Semantic Versioning](http://semver.org/).\n\n## 2.0.0 - pending\n\n### Release Candidates\n\n- [2.0.0-rc.37](changelog/2.0.0-rc.37.md) — ER Diagram Generation\n- [2.0.0-rc.36](changelog/2.0.0-rc.36.md) — Per-migration transaction control\n- [2.0.0-rc.35](changelog/2.0.0-rc.35.md) — SQLite transaction modes, DeriveIntoActiveModel extensions, Decimal64/Bytes, schema sync fix\n- [2.0.0-rc.34](changelog/2.0.0-rc.34.md) — Arrow/Parquet support, `try_from_u64` for DeriveValueType\n- [2.0.0-rc.32](changelog/2.0.0-rc.32.md) — `MigratorTrait` with `self`, PostgreSQL `application_name`\n- [2.0.0-rc.31](changelog/2.0.0-rc.31.md) — `ne_all`, typed `TextUuid`, COUNT overflow fix\n- [2.0.0-rc.30](changelog/2.0.0-rc.30.md) — Maintenance release, `sea-query` bump\n- [2.0.0-rc.29](changelog/2.0.0-rc.29.md) — Tracing spans, UUID-as-TEXT, relation filtering, LEFT JOIN fix\n- [2.0.0-rc.28](changelog/2.0.0-rc.28.md) — `sqlx-all` in migration, `set_if_not_equals_and`, auto_increment for String/Uuid PKs\n- [2.0.0-rc.27](changelog/2.0.0-rc.27.md) — `DeriveValueType` implements `NotU8` for PostgreSQL arrays\n- [2.0.0-rc.26](changelog/2.0.0-rc.26.md) — `postgres-use-serial-pk` feature for legacy serial PKs\n- [2.0.0-rc.25](changelog/2.0.0-rc.25.md) — Value system restoration, `sea-query` bump\n- [2.0.0-rc.24](changelog/2.0.0-rc.24.md) — `sea-query` bump to rc.27\n- [2.0.0-rc.23](changelog/2.0.0-rc.23.md) — `DeriveValueType` implements `IntoActiveValue`, remove `NotU8`\n- [2.0.0-rc.22](changelog/2.0.0-rc.22.md) — `DatabaseExecutor` unified type, value array refactor\n- [2.0.0-rc.21](changelog/2.0.0-rc.21.md) — Rusqlite / `sea-orm-sync` crate, `exists` on PaginatorTrait\n- [2.0.0-rc.20](changelog/2.0.0-rc.20.md) — Stringy newtypes, M2M self-ref, nullable columns, bug fixes\n\n### New Features\n\n* Role Based Access Control https://github.com/SeaQL/sea-orm/pull/2683\n\n  1. a hierarchical RBAC engine that is table scoped\n      + a user has 1 (and only 1) role\n      + a role has a set of permissions on a set of resources\n          + permissions here are CRUD operations and resources are tables\n          + but the engine is generic so can be used for other things\n      + roles have hierarchy, and so can inherit permissions\n      + there is a wildcard `*` to grant all permissions or resources\n      + individual users can have rules override\n  3. a set of Entities to load / store the access control rules to / from database\n  4. a query auditor that dissect queries for necessary permissions (implemented in SeaQuery)\n  5. integration of RBAC into SeaORM in form of `RestrictedConnection`.\n      it implements `ConnectionTrait`, and will audit all queries and perform permission check,\n      and reject them accordingly. all Entity operations except raw SQL are supported.\n      complex joins, insert select from, and even CTE queries are supported.\n```rust\n// load rules from database\ndb_conn.load_rbac().await?;\n\n// admin can create bakery\nlet db = db_conn.restricted_for(admin)?;\nlet seaside_bakery = bakery::ActiveModel {\n    name: Set(\"SeaSide Bakery\".to_owned()),\n    ..Default::default()\n};\nassert!(Bakery::insert(seaside_bakery).exec(&db).await.is_ok());\n\n// public cannot create bakery\nlet db = db_conn.restricted_for(public)?;\nassert!(matches!(\n    Bakery::insert(bakery::ActiveModel::default())\n        .exec(&db)\n        .await,\n    Err(DbErr::AccessDenied { .. })\n));\n```\n\n* Overhauled `Entity::insert_many`. We've made a number of changes https://github.com/SeaQL/sea-orm/pull/2628\n    1. removed APIs that can panic\n    2. new helper struct `InsertMany`, `last_insert_id` is now `Option<Value>`\n    3. on empty iterator, `None` or `vec![]` is returned on exec operations\n    4. `TryInsert` API is unchanged\n\nPreviously, `insert_many` shares the same helper struct with `insert_one`, which led to an awkard API.\n```rust\nlet res = Bakery::insert_many(std::iter::empty())\n    .on_empty_do_nothing() // <- you need to add this\n    .exec(db)\n    .await;\n\nassert!(matches!(res, Ok(TryInsertResult::Empty)));\n```\n`last_insert_id` is now `Option<Value>`:\n```rust\nstruct InsertManyResult<A: ActiveModelTrait>\n{\n    pub last_insert_id: Option<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>,\n}\n```\nWhich means the awkardness is removed:\n```rust\nlet res = Entity::insert_many::<ActiveModel, _>([]).exec(db).await;\n\nassert_eq!(res?.last_insert_id, None); // insert nothing return None\n\nlet res = Entity::insert_many([ActiveModel { id: Set(1) }, ActiveModel { id: Set(2) }])\n    .exec(db)\n    .await;\n\nassert_eq!(res?.last_insert_id, Some(2)); // insert something return Some\n```\nSame on conflict API as before:\n```rust\nlet res = Entity::insert_many([ActiveModel { id: Set(3) }, ActiveModel { id: Set(4) }])\n    .on_conflict_do_nothing()\n    .exec(db)\n    .await;\n\nassert!(matches!(conflict_insert, Ok(TryInsertResult::Conflicted)));\n```\nExec with returning now returns a `Vec<Model>`, so it feels intuitive:\n```rust\nassert!(\n    Entity::insert_many::<ActiveModel, _>([])\n        .exec_with_returning(db)\n        .await?\n        .is_empty() // no footgun, nice\n);\n\nassert_eq!(\n    Entity::insert_many([\n        ActiveModel {\n            id: NotSet,\n            value: Set(\"two\".into()),\n        }\n    ])\n    .exec_with_returning(db)\n    .await\n    .unwrap(),\n    [\n        Model {\n            id: 2,\n            value: \"two\".into(),\n        }\n    ]\n);\n```\n* Improved utility of `ActiveModel::from_json`. Consider the following Entity https://github.com/SeaQL/sea-orm/pull/2599\n```rust\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,      // <- not nullable\n    pub name: String,\n}\n```\nPreviously, the following would result in error \"missing field `id`\":\n```rust\nassert!(\n    cake::ActiveModel::from_json(json!({\n        \"name\": \"Apple Pie\",\n    })).is_err();\n);\n```\nNow, the ActiveModel will be partially filled:\n```rust\nassert_eq!(\n    cake::ActiveModel::from_json(json!({\n        \"name\": \"Apple Pie\",\n    }))\n    .unwrap(),\n    cake::ActiveModel {\n        id: NotSet,\n        name: Set(\"Apple Pie\".to_owned()),\n    }\n);\n```\n* A full `Model` can now be used as `PartialModel` in nested query https://github.com/SeaQL/sea-orm/pull/2642\n```rust\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"cake::Entity\")]\nstruct Cake {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<bakery::Model>,\n}\n\nlet cake: Cake = cake::Entity::find()\n    .left_join(bakery::Entity)\n    .order_by_asc(cake::Column::Id)\n    .into_partial_model()\n    .one(&ctx.db)\n    .await?\n    .unwrap();\n\nassert_eq!(cake.id, 13);\nassert_eq!(cake.name, \"Cheesecake\");\nassert_eq!(\n    cake.bakery.unwrap(),\n    bakery::Model {\n        id: 42,\n        name: \"cool little bakery\".to_string(),\n    }\n);\n```\n* Wrapper type derived with `DeriveValueType` can now be used as primary key https://github.com/SeaQL/sea-orm/pull/2643\n```rust\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"my_value_type\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: MyInteger,\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveValueType)]\npub struct MyInteger(pub i32);\n// only for i8 | i16 | i32 | i64 | u8 | u16 | u32 | u64\n```\n* You can now define unique keys that span multiple columns in Entity https://github.com/SeaQL/sea-orm/pull/2651\n```rust\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"lineitem\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(unique_key = \"item\")]\n    pub order_id: i32,\n    #[sea_orm(unique_key = \"item\")]\n    pub cake_id: i32,\n}\n\nlet stmts = Schema::new(backend).create_index_from_entity(lineitem::Entity);\n\nassert_eq!(\n    stmts[0],\n    Index::create()\n        .name(\"idx-lineitem-item\")\n        .table(lineitem::Entity)\n        .col(lineitem::Column::OrderId)\n        .col(lineitem::Column::CakeId)\n        .unique()\n        .take()\n);\n\nassert_eq!(\n    backend.build(stmts[0]),\n    r#\"CREATE UNIQUE INDEX \"idx-lineitem-item\" ON \"lineitem\" (\"order_id\", \"cake_id\")\"#\n);\n```\n* Overhauled `ConnectionTrait` API: `execute`, `query_one`, `query_all`, `stream` now takes in SeaQuery statement instead of raw SQL statement https://github.com/SeaQL/sea-orm/pull/2657\n```rust\n// old\nlet query: SelectStatement = Entity::find().filter(..).into_query();\nlet backend = self.db.get_database_backend();\nlet stmt = backend.build(&query);\nlet rows = self.db.query_all(stmt).await?;\n\n// new\nlet query: SelectStatement = Entity::find().filter(..).into_query();\nlet rows = self.db.query_all(&query).await?;\n```\n* Added `raw_sql` macro for ergonomic parameter injection\n```rust\n#[derive(FromQueryResult)]\nstruct Cake {\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<Bakery>,\n}\n\n#[derive(FromQueryResult)]\nstruct Bakery {\n    #[sea_orm(alias = \"bakery_name\")]\n    name: String,\n}\n\nlet cake_ids = [2, 3, 4]; // expanded by the `..` operator\n\nlet cake: Option<Cake> = Cake::find_by_statement(raw_sql!(\n    Sqlite,\n    r#\"SELECT \"cake\".\"name\", \"bakery\".\"name\" AS \"bakery_name\"\n       FROM \"cake\"\n       LEFT JOIN \"bakery\" ON \"cake\".\"bakery_id\" = \"bakery\".\"id\"\n       WHERE \"cake\".\"id\" IN ({..cake_ids})\"#\n))\n.one(db)\n.await?;\n```\n* Added `consolidate` method to `SelectThree`. This output has different shape depending on the topology of the join.\n```rust\n// Order -> Customer\n//       -> Lineitem\n\nlet items: Vec<(order::Model, Option<customer::Model>, Option<lineitem::Model>)> =\n    order::Entity::find()\n        .find_also_related(customer::Entity)\n        .find_also_related(lineitem::Entity)\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .all(&ctx.db)\n        .await?;\n\n// flat result\nassert_eq!(\n    items,\n    vec![\n        (order, Some(customer), Some(line_1)),\n        (order, Some(customer), Some(line_2)),\n    ]\n);\n\nlet items: Vec<(order::Model, Vec<customer::Model>, Vec<lineitem::Model>)> =\n    order::Entity::find()\n        .find_also_related(customer::Entity)\n        .find_also_related(lineitem::Entity)\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .consolidate() // <-\n        .all(&ctx.db)\n        .await?;\n\n// consolidated by order\nassert_eq!(\n    items,\n    vec![(\n        order,\n        vec![customer],\n        vec![line_1, line_2]\n    )]\n);\n\n// Order -> Lineitem -> Cake\nlet items: Vec<(order::Model, Option<lineitem::Model>, Option<cake::Model>)> =\n    order::Entity::find()\n        .find_also_related(lineitem::Entity)\n        .and_also_related(cake::Entity)\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .all(&ctx.db)\n        .await?;\n\n// flat result\nassert_eq!(\n    items,\n    vec![\n        (order, Some(line_1), Some(cake_1)),\n        (order, Some(line_2), Some(cake_2)),\n    ]\n);\n\nlet items: Vec<(order::Model, Vec<(lineitem::Model, Vec<cake::Model>)>)> =\n    order::Entity::find()\n        .find_also_related(lineitem::Entity)\n        .and_also_related(cake::Entity)\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .consolidate() // <-\n        .all(&ctx.db)\n        .await?;\n\n// consolidated by order first, then by line\nassert_eq!(\n    items,\n    vec![(\n        order,\n        vec![(line_1, vec![cake_1]), (line_2, vec![cake_2])]\n    )]\n);\n```\n* Added `Select::has_related`\n```rust\n// cake -> fruit: find all cakes containing mango\nassert_eq!(\n    cake::Entity::find()\n        .has_related(fruit::Entity, fruit::Column::Name.eq(\"Mango\"))\n        .build(DbBackend::Sqlite)\n        .to_string(),\n    [\n        r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n        r#\"WHERE EXISTS(SELECT 1 FROM \"fruit\"\"#,\n        r#\"WHERE \"fruit\".\"name\" = 'Mango'\"#,\n        r#\"AND \"cake\".\"id\" = \"fruit\".\"cake_id\")\"#,\n    ]\n    .join(\" \")\n);\n// cake -> cake_filling -> filling: find all cakes with orange fillings\nassert_eq!(\n    cake::Entity::find()\n        .has_related(filling::Entity, filling::Column::Name.eq(\"Marmalade\"))\n        .build(DbBackend::Sqlite)\n        .to_string(),\n    [\n        r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n        r#\"WHERE EXISTS(SELECT 1 FROM \"filling\"\"#,\n        r#\"INNER JOIN \"cake_filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n        r#\"WHERE \"filling\".\"name\" = 'Marmalade'\"#,\n        r#\"AND \"cake\".\"id\" = \"cake_filling\".\"cake_id\")\"#,\n    ]\n    .join(\" \")\n);\n```\n* Support self-referencing relations in loader\n```rust\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n#[sea_orm(table_name = \"staff\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub reports_to_id: Option<i32>,\n    #[sea_orm(self_ref, relation_enum = \"ReportsTo\", from = \"reports_to_id\", to = \"id\")]\n    pub reports_to: HasOne<Entity>,\n}\n\n// Entity Loader\nlet staff = staff::Entity::load()\n    .with(staff::Relation::ReportsTo)\n    .all(db)\n    .await?;\n\nassert_eq!(staff[0].name, \"Alan\");\nassert_eq!(staff[0].reports_to, None);\n\nassert_eq!(staff[1].name, \"Ben\");\nassert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n\nassert_eq!(staff[2].name, \"Alice\");\nassert_eq!(staff[2].reports_to.as_ref().unwrap().name, \"Alan\");\n\n// Model Loader\nlet staff = staff::Entity::find().all(db).await?;\n\nlet reports_to = staff\n    .load_self(staff::Entity, staff::Relation::ReportsTo, db)\n    .await?;\n\nassert_eq!(staff[0].name, \"Alan\");\nassert_eq!(reports_to[0], None);\n\nassert_eq!(staff[1].name, \"Ben\");\nassert_eq!(reports_to[1].unwrap().name, \"Alan\");\n\nassert_eq!(staff[2].name, \"Alice\");\nassert_eq!(reports_to[2].unwrap().name, \"Alan\");\n```\n* Strongly-typed column https://github.com/SeaQL/sea-orm/pull/2794\n```rust\n// old\nuser::Entity::find().filter(user::Column::Name.contains(\"Bob\"))\n\n// new\nuser::Entity::find().filter(user::COLUMN.name.contains(\"Bob\"))\n\n// compile error: the trait `From<{integer}>` is not implemented for `String`\nuser::Entity::find().filter(user::COLUMN.name.like(2))\n```\n* Unix timestamp column type that will be mapped to big integer in database\n```rust\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"access_log\")]\npub struct Model {\n    .. // with `chrono` crate\n    pub ts: ChronoUnixTimestamp,\n    pub ms: ChronoUnixTimestampMillis,\n    .. // with `time` crate\n    pub ts: TimeUnixTimestamp,\n    pub ms: TimeUnixTimestampMillis,\n}\n```\n* Nested ActiveModel (ActiveModelEx) and cascade operations https://github.com/SeaQL/sea-orm/pull/2818\n\n    The following operation saves a new set of user + profile + post + tag + post_tag into the database atomically:\n```rust\nlet user = user::ActiveModel::builder()\n    .set_name(\"Bob\")\n    .set_email(\"bob@sea-ql.org\")\n    .set_profile(profile::ActiveModel::builder().set_picture(\"image.jpg\"))\n    .add_post(\n        post::ActiveModel::builder()\n            .set_title(\"Nice weather\")\n            .add_tag(tag::ActiveModel::builder().set_tag(\"sunny\")),\n    )\n    .save(db)\n    .await?;\n```\n\n### Enhancements\n\n* [sea-orm-cli] Added `--column-extra-derives` https://github.com/SeaQL/sea-orm/pull/2212\n* [sea-orm-cli] Added `--big-integer-type=i32` to use i32 for bigint (for SQLite)\n* [sea-orm-cli] Fix codegen to not generate relations to filtered entities https://github.com/SeaQL/sea-orm/pull/2913\n* [sea-orm-cli] Added `--experimental-preserve-user-modifications` https://github.com/SeaQL/sea-orm/pull/2755 https://github.com/SeaQL/sea-orm/pull/2964\n* Added `Model::try_set`\n* Added new error variant `BackendNotSupported`. Previously, it panics with e.g. \"Database backend doesn't support RETURNING\" https://github.com/SeaQL/sea-orm/pull/2630\n```rust\nlet result = cake::Entity::insert_many([])\n    .exec_with_returning_keys(db)\n    .await;\n\nif db.support_returning() {\n    // Postgres and SQLite\n    assert_eq!(result.unwrap(), []);\n} else {\n    // MySQL\n    assert!(matches!(result, Err(DbErr::BackendNotSupported { .. })));\n}\n```\n* Added new error variant `PrimaryKeyNotSet`. Previously, it panics with \"PrimaryKey is not set\" https://github.com/SeaQL/sea-orm/pull/2627\n```rust\nassert!(matches!(\n    Update::one(cake::ActiveModel {\n        ..Default::default()\n    })\n    .exec(&db)\n    .await,\n    Err(DbErr::PrimaryKeyNotSet { .. })\n));\n```\n* Remove panics in `Schema::create_enum_from_active_enum` https://github.com/SeaQL/sea-orm/pull/2634\n```rust\nfn create_enum_from_active_enum<A>(&self) -> Option<TypeCreateStatement>\n// method can now return None\n```\n* Added `ColumnTrait::eq_any` as a shorthand for the ` = ANY` operator. Postgres only.\n```rust\nassert_eq!(\n    cake::Entity::find()\n        .filter(cake::Column::Id.eq_any(vec![4, 5]))\n        .build(DbBackend::Postgres)\n        .to_string(),\n    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = ANY(ARRAY [4,5])\"#\n);\n```\n* Added `ActiveModelTrait::try_set`\n```rust\npub trait ActiveModelTrait {\n    /// old: set the Value of a ActiveModel field, panic if failed\n    fn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) {\n        self.try_set(c, v).unwrap_or_else(|e| panic!(..))\n    }\n\n    /// new: same as above but non-panicking\n    fn try_set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) -> Result<(), DbErr>;\n}\n```\n* `Linked` can now be used in partial select, in case `Related` cannot be defined\n```rust\npub struct ToBakery;\nimpl Linked for ToBakery {\n    type FromEntity = super::cake::Entity;\n    type ToEntity = super::bakery::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::Bakery.def()]\n    }\n}\n\n#[derive(Debug, DerivePartialModel)]\n#[sea_orm(entity = \"cake::Entity\", into_active_model)]\nstruct Cake2 {\n    id: i32,\n    name: String,\n    #[sea_orm(nested, alias = \"r0\")]\n    bakery: Option<Bakery>,\n    #[sea_orm(skip)]\n    ignore: Ignore,\n}\n\nlet cake2: Cake2 = cake::Entity::find()\n    .left_join_linked(ToBakery)\n    .order_by_asc(cake::Column::Id)\n    .into_partial_model()\n    .one(&ctx.db)\n    .await?\n    .unwrap();\n```\n* `RelationDef` now implements `Clone`. `on_condition` is changed to `Arc` but this is a minor breaking change.\n* Added `extra` on column attribute:\n```rust\n#[cfg(feature = \"with-rust_decimal\")]\n#[sea_orm(extra = \"CHECK (price > 0)\")]\npub price: Decimal,\n\n// results in:\nColumnDef::new(\"price\")\n    .decimal()\n    .not_null()\n    .extra(\"CHECK (price > 0)\"),\n```\n* Added `ColumnTrait::avg`, in addition to `sum`, `min`, `max` etc\n```rust\nlet average: Decimal = order::Entity::find()\n    .select_only()\n    .column_as(order::Column::Total.avg(), \"avg\")\n    .into_tuple()\n    .one(&ctx.db)\n    .await?\n    .unwrap();\n```\n* `SchemaBuilder::sync` can now be used in migrations\n```rust\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        db.get_schema_builder()\n            .register(note::Entity)\n            .sync(db)\n            .await\n    }\n}\n```\n* Allowed None for `max_lifetime` and `idle_timeout` Parameters https://github.com/SeaQL/sea-orm/pull/2748\n* Try to parse `u32` in Postgres as `i32` https://github.com/SeaQL/sea-orm/pull/2753\n* `DeriveActiveEnum` now also impl `IntoActiveValue` https://github.com/SeaQL/sea-orm/issues/1972\n* `DeriveValueType` now also supports any structs that can be converted to / from string https://github.com/SeaQL/sea-orm/issues/2811\n```rust\n#[derive(Copy, Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(value_type = \"String\")]\npub struct Tag3 {\n    pub i: i64,\n}\n\nimpl std::fmt::Display for Tag3 {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", self.i)\n    }\n}\n\nimpl std::str::FromStr for Tag3 {\n    type Err = std::num::ParseIntError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        let i: i64 = s.parse()?;\n        Ok(Self { i })\n    }\n}\n```\n* Fix `DeriveIntoActiveModel` on `Option<T>` fields https://github.com/SeaQL/sea-orm/pull/2926\n```rust\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"fruit\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub cake_id: Option<i32>,\n}\n\n#[derive(DeriveIntoActiveModel)]\n#[sea_orm(active_model = \"<fruit::Entity as EntityTrait>::ActiveModel\")]\nstruct PartialFruit {\n    cake_id: Option<i32>,\n}\n\nassert_eq!(\n    PartialFruit { cake_id: Some(1) }.into_active_model(),\n    fruit::ActiveModel { id: NotSet, name: NotSet, cake_id: Set(Some(1)) }\n);\n\nassert_eq!(\n    PartialFruit { cake_id: None }.into_active_model(),\n    fruit::ActiveModel { id: NotSet, name: NotSet, cake_id: NotSet }\n);\n```\n* `FromQueryResult` now supports nullable nested model https://github.com/SeaQL/sea-orm/pull/2845\n```rust\n#[derive(FromQueryResult)]\nstruct CakeWithOptionalBakeryModel {\n    #[sea_orm(alias = \"cake_id\")]\n    id: i32,\n    #[sea_orm(alias = \"cake_name\")]\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<bakery::Model>, // can be null\n}\n```\n* Added `try_from_u64` to `DeriveValueType` https://github.com/SeaQL/sea-orm/pull/2958\n```rust\n// Test for try_from_u64 attribute with type alias\ntype UserId = i32;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(try_from_u64)]\npub struct MyUserId(pub UserId);\n```\n* Arrow / Parquet support https://github.com/SeaQL/sea-orm/pull/2957\n    + Added `ArrowSchema`, `DeriveArrowSchema`\n    + Support decimal with different formats\n    + Support timestamp with different timezone / resolution\n    + Added parquet example\n\n### Breaking Changes\n\nPlease read [SeaQuery's breaking changes](https://github.com/SeaQL/sea-query/blob/master/CHANGELOG.md#breaking-changes) as well. But for most compile errors, you can simply add `use sea_orm::ExprTrait;` in scope.\n```rust\nerror[E0599]: no method named `like` found for enum `sea_query::Expr` in the current scope\n    |\n    |         Expr::col((self.entity_name(), *self)).like(s)\n    |\n    |     fn like<L>(self, like: L) -> Expr\n    |        ---- the method is available for `sea_query::Expr` here\n    |\n    = help: items from traits can only be used if the trait is in scope\nhelp: trait `ExprTrait` which provides `like` is implemented but not in scope; perhaps you want to import it\n    |\n -> + use sea_orm::ExprTrait;\n```\n```rust\nerror[E0308]: mismatched types\n  --> src/sqlite/discovery.rs:27:57\n   |\n   |             .and_where(Expr::col(Alias::new(\"type\")).eq(\"table\"))\n   |                                                      -- ^^^^^^^ expected `&Expr`, found `&str`\n   |                                                      |\n   |                                                      arguments to this method are incorrect\n   |\n   = note: expected reference `&sea_query::Expr`\n              found reference `&'static str`\n```\n```rust\nerror[E0308]: mismatched types\n    |\n390 |             Some(Expr::col(Name).eq(PgFunc::any(query.symbol)))\n    |                                  -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&Expr`, found `FunctionCall`\n    |                                  |\n    |                                  arguments to this method are incorrect\n    |\nnote: method defined here\n   --> /rustc/6b00bc3880198600130e1cf62b8f8a93494488cc/library/core/src/cmp.rs:254:8\n```\n```rust\nerror[E0277]: the trait bound `sea_orm::Condition: From<bool>` is not satisfied\n    |\n367 |         .add_option(option)\n    |          ---------- ^^^^^^ the trait `From<bool>` is not implemented for `sea_orm::Condition`\n    |          |\n    |          required by a bound introduced by this call\n    |\n    = note: required for `bool` to implement `Into<sea_orm::Condition>`\n```\n\n* Removed `runtime-actix` feature flag. It's been an alias of `runtime-tokio` for more than a year, so there should be no impact.\n* Enabled `sqlite-use-returning-for-3_35` by default. SQLite `3.35` was released in 2021, it should be the default by now.\n* Now implemented `impl<T: ModelTrait + FromQueryResult> PartialModelTrait for T`, there may be a potential conflict https://github.com/SeaQL/sea-orm/pull/2642\n* Now `DeriveValueType` will also `TryFromU64` if applicable, there may be a potential conflict https://github.com/SeaQL/sea-orm/pull/2643\n* Now `DeriveValueType` also impl `IntoActiveValue` and `NotU8`, there may be a potential conflict\n* Added `TryIntoModel` and `Serialize` to trait bounds of `ActiveModel::from_json`. There should be no impact if your models are derived with `DeriveEntityModel` https://github.com/SeaQL/sea-orm/pull/2599\n```rust\nfn from_json(mut json: serde_json::Value) -> Result<Self, DbErr>\nwhere\n    Self: TryIntoModel<<Self::Entity as EntityTrait>::Model>,\n    <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self>,\n    for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model:\n        serde::de::Deserialize<'de> + serde::Serialize,\n```\n* `DerivePartialModel` now implement `FromQueryResult` by default, so there may be a potential conflict. Remove `FromQueryResult` in these cases https://github.com/SeaQL/sea-orm/pull/2653\n```rust\nerror[E0119]: conflicting implementations of trait `sea_orm::FromQueryResult` for type `CakeWithFruit`\n  |\n> | #[derive(DerivePartialModel, FromQueryResult)]\n  |          ------------------  ^^^^^^^^^^^^^^^ conflicting implementation for `CakeWithFruit`\n```\n* Changed `IdenStatic` and `EntityName` definition https://github.com/SeaQL/sea-orm/pull/2667\n```rust\ntrait IdenStatic {\n    fn as_str(&self) -> &'static str; // added static lifetime\n}\ntrait EntityName {\n    fn table_name(&self) -> &'static str; // added static lifetime\n}\n```\n* Removed `DeriveCustomColumn` and `default_as_str` https://github.com/SeaQL/sea-orm/pull/2667\n```rust\n// This is no longer supported:\n#[derive(Copy, Clone, Debug, EnumIter, DeriveCustomColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\nimpl IdenStatic for Column {\n    fn as_str(&self) -> &str {\n        match self {\n            Self::Name => \"my_name\",\n            _ => self.default_as_str(),\n        }\n    }\n}\n\n// Do the following instead:\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    #[sea_orm(column_name = \"my_name\")]\n    Name,\n}\n```\n* `execute`, `query_one`, `query_all`, `stream` now takes in SeaQuery statement instead of raw SQL statement. a new set of methods `execute_raw`, `query_one_raw`, `query_all_raw`, `stream_raw` is added https://github.com/SeaQL/sea-orm/pull/2657\n```rust\n  --> src/executor/paginator.rs:53:38\n   |\n>  |         let rows = self.db.query_all(stmt).await?;\n   |                            --------- ^^^^ expected `&_`, found `Statement`\n   |                            |\n   |                            arguments to this method are incorrect\n   |\n   = note: expected reference `&_`\n                 found struct `statement::Statement`\n```\n```rust\nlet backend = self.db.get_database_backend();\nlet stmt = backend.build(&query);\n// change to:\nlet rows = self.db.query_all_raw(stmt).await?;\n// if the query is a SeaQuery statement, then just do this:\nlet rows = self.db.query_all(&query).await?; // no need to build query\n```\n* `DatabaseConnection` is changed from enum to struct. The original enum is moved into `DatabaseConnection::inner`. The new enum is named `DatabaseConnectionType` https://github.com/SeaQL/sea-orm/pull/2671\n```rust\nerror[E0599]: no associated item named `Disconnected` found for struct `db_connection::DatabaseConnection` in the current scope\n   --> src/database/db_connection.rs:137:33\n    |\n>   | pub struct DatabaseConnection {\n    | ----------------------------- associated item `Disconnected` not found for this struct\n...\n>   |             DatabaseConnection::Disconnected => Err(conn_err(\"Disconnected\")),\n    |                                 ^^^^^^^^^^^^ associated item not found in `DatabaseConnection`\n```\n```rust\nmatch conn.inner {\n    DatabaseConnectionType::Disconnected => (),\n    _ => (),\n}\n```\n* `DeleteOne` and `UpdateOne` no longer implement `QueryFilter` and `QueryTrait`\n  directly. Those implementations could expose an incomplete SQL query with an\n  incomplete condition that touches too many records. To generate the right\n  condition, we must make sure that the primary key is set on the input\n  `ActiveModel`. If you need to access the generated SQL query, convert into\n  `ValidatedDeleteOne`/`ValidatedUpdateOne` first.\n```rust\nerror[E0599]: no method named `build` found for struct `query::update::UpdateOne` in the current scope\n   --> src/entity/column.rs:607:22\n    |\n  > | /                 Update::one(active_model)\n  > | |                     .build(DbBackend::Postgres)\n    | |                     -^^^^^ method not found in `UpdateOne<A>`\n    | |_____________________|\n    |\n```\nCall the `validate()` method:\n```rust\nUpdate::one(active_model)\n  + .validate()?\n    .build(DbBackend::Postgres)\n```\n* Removed `DbBackend::get_query_builder()` because `QueryBuilder` is not longer object safe.\n```rust\n  - fn get_query_builder(&self) -> Box<dyn QueryBuilder>\n```\n* A number of methods has been removed from `SelectTwoMany`: `into_partial_model`, `into_json`, `stream`. These methods are same as those in `SelectTwo`.\nPlease use `Cake::find().find_also_related(Fruit).into_json()` instead.\n* The `delete_by_id` method has changed to returning `DeleteOne` instead of `DeleteMany`. It doesn't change normal `exec` usage, but would change return type of `exec_with_returning` to `Option<Model>`\n```rust\nfn delete_by_id<T>(values: T) -> DeleteMany<Self>         // old\n\nfn delete_by_id<T>(values: T) -> ValidatedDeleteOne<Self> // new\n```\n* `DeriveActiveEnum` now also automatically impl `IntoActiveValue`, if you have a custom impl before, there would be a collision\n* `with-bigdecimal` is now removed from default features\n* `RuntimeErr::SqlxError` is now held in `Arc` to make `DbErr` clonable and smaller:\n```rust\npub enum RuntimeErr {\n    SqlxError(Arc<sqlx::error::Error>),\n```\n\n### Upgrades\n\n* Upgraded Rust Edition to 2024 https://github.com/SeaQL/sea-orm/pull/2596\n* Upgraded `strum` to `0.27`\n\n## 1.1.19 - 2025-11-11\n\n### Enhancements\n\n* Add `find_linked_recursive` method to ModelTrait https://github.com/SeaQL/sea-orm/pull/2480\n* Skip drop extension type in fresh https://github.com/SeaQL/sea-orm/pull/2716\n\n### Bug Fixes\n\n* Handle null values in `from_sqlx_*_row_to_proxy_row` functions https://github.com/SeaQL/sea-orm/pull/2744\n\n## 1.1.17 - 2025-10-09\n\n### New Features\n\n* Added `map_sqlx_mysql_opts`, `map_sqlx_postgres_opts`, `map_sqlx_sqlite_opts` to `ConnectOptions` https://github.com/SeaQL/sea-orm/pull/2731\n```rust\nlet mut opt = ConnectOptions::new(url);\nopt.map_sqlx_postgres_opts(|pg_opt: PgConnectOptions| {\n    pg_opt.ssl_mode(PgSslMode::Require)\n});\n```\n* Added `mariadb-use-returning` to use returning syntax for MariaDB https://github.com/SeaQL/sea-orm/pull/2710\n* Released `sea-orm-rocket` 0.6 https://github.com/SeaQL/sea-orm/pull/2732\n\n## 1.1.16 - 2025-09-11\n\n### Bug Fixes\n\n* Fix enum casting in DerivePartialModel https://github.com/SeaQL/sea-orm/pull/2719 https://github.com/SeaQL/sea-orm/pull/2720\n```rust\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"active_enum::Entity\", from_query_result, alias = \"zzz\")]\nstruct PartialWithEnumAndAlias {\n    #[sea_orm(from_col = \"tea\")]\n    foo: Option<Tea>,\n}\n\nlet sql = active_enum::Entity::find()\n    .into_partial_model::<PartialWithEnumAndAlias>()\n    .into_statement(DbBackend::Postgres)\n    .sql;\n\nassert_eq!(\n    sql,\n    r#\"SELECT CAST(\"zzz\".\"tea\" AS \"text\") AS \"foo\" FROM \"public\".\"active_enum\"\"#,\n);\n```\n\n### Enhancements\n\n* [sea-orm-cli] Use tokio (optional) instead of async-std https://github.com/SeaQL/sea-orm/pull/2721\n\n## 1.1.15 - 2025-08-31\n\n### Enhancements\n\n* Allow `DerivePartialModel` to have nested aliases https://github.com/SeaQL/sea-orm/pull/2686\n```rust\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"bakery::Entity\", from_query_result)]\nstruct Factory {\n    id: i32,\n    #[sea_orm(from_col = \"name\")]\n    plant: String,\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"cake::Entity\", from_query_result)]\nstruct CakeFactory {\n    id: i32,\n    name: String,\n    #[sea_orm(nested, alias = \"factory\")] // <- new\n    bakery: Option<Factory>,\n}\n```\n* Add `ActiveModelTrait::try_set` https://github.com/SeaQL/sea-orm/pull/2706\n```rust\nfn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value);\n/// New: a non-panicking version of above\nfn try_set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) -> Result<(), DbErr>;\n```\n\n### Bug Fixes\n\n* [sea-orm-cli] Fix compilation issue https://github.com/SeaQL/sea-orm/pull/2713\n\n## 1.1.14 - 2025-07-21\n\n### Enhancements\n\n* [sea-orm-cli] Mask sensitive ENV values https://github.com/SeaQL/sea-orm/pull/2658\n\n### Bug Fixes\n\n* `FromJsonQueryResult`: panic on serialization failures https://github.com/SeaQL/sea-orm/pull/2635\n```rust\n#[derive(Clone, Debug, PartialEq, Deserialize, FromJsonQueryResult)]\npub struct NonSerializableStruct;\n\nimpl Serialize for NonSerializableStruct {\n    fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: Serializer,\n    {\n        Err(serde::ser::Error::custom(\n            \"intentionally failing serialization\",\n        ))\n    }\n}\n\nlet model = Model {\n    json: Some(NonSerializableStruct),\n};\n\nlet _ = model.into_active_model().insert(&ctx.db).await; // panic here\n```\n\n## 1.1.13 - 2025-06-29\n\n### New Features\n\n* [sea-orm-cli] New `--frontend-format` flag to generate entities in pure Rust https://github.com/SeaQL/sea-orm/pull/2631\n```rust\n// for example, below is the normal (compact) Entity:\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n// this is the generated frontend model, there is no SeaORM dependency:\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]\npub struct Model {\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    pub name: Option<String> ,\n}\n```\n\n### Enhancements\n\n* Removed potential panics from `Loader` https://github.com/SeaQL/sea-orm/pull/2637\n\n## 1.1.12 - 2025-05-27\n\n### Enhancements\n\n* Make sea-orm-cli & sea-orm-migration dependencies optional https://github.com/SeaQL/sea-orm/pull/2367\n* Relax TransactionError's trait bound for errors to allow `anyhow::Error` https://github.com/SeaQL/sea-orm/pull/2602\n\n### Bug Fixes\n\n* Include custom `column_name` in DeriveColumn `Column::from_str` impl https://github.com/SeaQL/sea-orm/pull/2603\n```rust\n#[derive(DeriveEntityModel)]\npub struct Model {\n    #[sea_orm(column_name = \"lAsTnAmE\")]\n    last_name: String,\n}\n\nassert!(matches!(Column::from_str(\"lAsTnAmE\").unwrap(), Column::LastName));\n```\n\n## 1.1.11 - 2025-05-07\n\n### Enhancements\n\n* Added `ActiveModelTrait::default_values`\n```rust\nassert_eq!(\n    fruit::ActiveModel::default_values(),\n    fruit::ActiveModel {\n        id: Set(0),\n        name: Set(\"\".into()),\n        cake_id: Set(None),\n        type_without_default: NotSet,\n    },\n);\n```\n* Impl `IntoCondition` for `RelationDef` https://github.com/SeaQL/sea-orm/pull/2587\n```rust\n// This allows using `RelationDef` directly where sea-query expects an `IntoCondition`\nlet query = Query::select()\n    .from(fruit::Entity)\n    .inner_join(cake::Entity, fruit::Relation::Cake.def())\n    .to_owned();\n```\n* Loader: retain only unique key values in the query condition https://github.com/SeaQL/sea-orm/pull/2569\n* Add proxy transaction impl https://github.com/SeaQL/sea-orm/pull/2573\n* [sea-orm-cli] Fix `PgVector` codegen https://github.com/SeaQL/sea-orm/pull/2589\n\n### Bug fixes\n\n* Quote type properly in `AsEnum` casting https://github.com/SeaQL/sea-orm/pull/2570\n```rust\nassert_eq!(\n    lunch_set::Entity::find()\n        .select_only()\n        .column(lunch_set::Column::Tea)\n        .build(DbBackend::Postgres)\n        .to_string(),\n    r#\"SELECT CAST(\"lunch_set\".\"tea\" AS \"text\") FROM \"lunch_set\"\"#\n    // \"text\" is now quoted; will work for \"text\"[] as well\n);\n```\n* Fix unicode string enum https://github.com/SeaQL/sea-orm/pull/2218\n\n### Upgrades\n\n* Upgrade `heck` to `0.5` https://github.com/SeaQL/sea-orm/pull/2218\n* Upgrade `sea-query` to `0.32.5`\n* Upgrade `sea-schema` to `0.16.2`\n\n## 1.1.10 - 2025-04-14\n\n### Upgrades\n\n* Upgrade sqlx to 0.8.4 https://github.com/SeaQL/sea-orm/pull/2562\n\n## 1.1.9 - 2025-04-14\n\n### Enhancements\n\n* [sea-orm-macros] Use fully-qualified syntax for ActiveEnum associated type https://github.com/SeaQL/sea-orm/pull/2552\n* Accept `LikeExpr` in `like` and `not_like` https://github.com/SeaQL/sea-orm/pull/2549\n\n### Bug fixes\n\n* Check if url is well-formed before parsing https://github.com/SeaQL/sea-orm/pull/2558\n* `QuerySelect::column_as` method cast ActiveEnum column https://github.com/SeaQL/sea-orm/pull/2551\n\n### House keeping\n\n* Remove redundant `Expr::expr` from internal code https://github.com/SeaQL/sea-orm/pull/2554\n\n## 1.1.8 - 2025-03-30\n\n### New Features\n\n* Implement `DeriveValueType` for enum strings\n```rust\n#[derive(DeriveValueType)]\n#[sea_orm(value_type = \"String\")]\npub enum Tag {\n    Hard,\n    Soft,\n}\n\n// `from_str` defaults to `std::str::FromStr::from_str`\nimpl std::str::FromStr for Tag {\n    type Err = sea_orm::sea_query::ValueTypeErr;\n    fn from_str(s: &str) -> Result<Self, Self::Err> { .. }\n}\n\n// `to_str` defaults to `std::string::ToString::to_string`.\nimpl std::fmt::Display for Tag {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { .. }\n}\n\n// you can override from_str and to_str with custom functions\n#[derive(DeriveValueType)]\n#[sea_orm(value_type = \"String\", from_str = \"Tag::from_str\", to_str = \"Tag::to_str\")]\npub enum Tag {\n    Color,\n    Grey,\n}\n\nimpl Tag {\n    fn from_str(s: &str) -> Result<Self, ValueTypeErr> { .. }\n\n    fn to_str(&self) -> &'static str { .. }\n}\n```\n* Support Postgres Ipnetwork (under feature flag `with-ipnetwork`) https://github.com/SeaQL/sea-orm/pull/2395\n```rust\n// Model\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"host_network\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub ipaddress: IpNetwork,\n    #[sea_orm(column_type = \"Cidr\")]\n    pub network: IpNetwork,\n}\n\n// Schema\nsea_query::Table::create()\n    .table(host_network::Entity)\n    .col(ColumnDef::new(host_network::Column::Id).integer().not_null().auto_increment().primary_key())\n    .col(ColumnDef::new(host_network::Column::Ipaddress).inet().not_null())\n    .col(ColumnDef::new(host_network::Column::Network).cidr().not_null())\n    .to_owned();\n\n// CRUD\nhost_network::ActiveModel {\n    ipaddress: Set(IpNetwork::new(Ipv6Addr::new(..))),\n    network: Set(IpNetwork::new(Ipv4Addr::new(..))),\n    ..Default::default()\n}\n```\n\n### Enhancements\n\n* Added `try_getable_postgres_array!(Vec<u8>)` (to support `bytea[]`) https://github.com/SeaQL/sea-orm/pull/2503\n\n### Bug fixes\n\n* [sea-orm-codegen] Support postgres array in expanded format https://github.com/SeaQL/sea-orm/pull/2545\n\n### House keeping\n\n* Replace `once_cell` crate with `std` equivalent https://github.com/SeaQL/sea-orm/pull/2524\n(available since rust 1.80)\n\n## 1.1.7 - 2025-03-02\n\n### New Features\n\n* Support nested entities in `FromQueryResult` https://github.com/SeaQL/sea-orm/pull/2508\n```rust\n#[derive(FromQueryResult)]\nstruct Cake {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<CakeBakery>,\n}\n\n#[derive(FromQueryResult)]\nstruct CakeBakery {\n    #[sea_orm(from_alias = \"bakery_id\")]\n    id: i32,\n    #[sea_orm(from_alias = \"bakery_name\")]\n    title: String,\n}\n\nlet cake: Cake = cake::Entity::find()\n    .select_only()\n    .column(cake::Column::Id)\n    .column(cake::Column::Name)\n    .column_as(bakery::Column::Id, \"bakery_id\")\n    .column_as(bakery::Column::Name, \"bakery_name\")\n    .left_join(bakery::Entity)\n    .order_by_asc(cake::Column::Id)\n    .into_model()\n    .one(&ctx.db)\n    .await?\n    .unwrap();\n\nassert_eq!(\n    cake,\n    Cake {\n        id: 1,\n        name: \"Cake\".to_string(),\n        bakery: Some(CakeBakery {\n            id: 20,\n            title: \"Bakery\".to_string(),\n        })\n    }\n);\n```\n* Support nested entities in `DerivePartialModel` https://github.com/SeaQL/sea-orm/pull/2508\n```rust\n#[derive(DerivePartialModel)] // FromQueryResult is no longer needed\n#[sea_orm(entity = \"cake::Entity\", from_query_result)]\nstruct Cake {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<Bakery>,\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"bakery::Entity\", from_query_result)]\nstruct Bakery {\n    id: i32,\n    #[sea_orm(from_col = \"Name\")]\n    title: String,\n}\n\n// same as previous example, but without the custom selects\nlet cake: Cake = cake::Entity::find()\n    .left_join(bakery::Entity)\n    .order_by_asc(cake::Column::Id)\n    .into_partial_model()\n    .one(&ctx.db)\n    .await?\n    .unwrap();\n\nassert_eq!(\n    cake,\n    Cake {\n        id: 1,\n        name: \"Cake\".to_string(),\n        bakery: Some(CakeBakery {\n            id: 20,\n            title: \"Bakery\".to_string(),\n        })\n    }\n);\n```\n* Derive also `IntoActiveModel` with `DerivePartialModel` https://github.com/SeaQL/sea-orm/pull/2517\n```rust\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"cake::Entity\", into_active_model)]\nstruct Cake {\n    id: i32,\n    name: String,\n}\n\nassert_eq!(\n    Cake {\n        id: 12,\n        name: \"Lemon Drizzle\".to_owned(),\n    }\n    .into_active_model(),\n    cake::ActiveModel {\n        id: Set(12),\n        name: Set(\"Lemon Drizzle\".to_owned()),\n        ..Default::default()\n    }\n);\n```\n* Added `SelectThree` https://github.com/SeaQL/sea-orm/pull/2518\n```rust\n// Order -> (many) Lineitem -> Cake\nlet items: Vec<(order::Model, Option<lineitem::Model>, Option<cake::Model>)> =\n    order::Entity::find()\n        .find_also_related(lineitem::Entity)\n        .and_also_related(cake::Entity)\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .all(&ctx.db)\n        .await?;\n```\n\n### Enhancements\n\n* Support complex type path in `DeriveIntoActiveModel` https://github.com/SeaQL/sea-orm/pull/2517\n```rust\n#[derive(DeriveIntoActiveModel)]\n#[sea_orm(active_model = \"<fruit::Entity as EntityTrait>::ActiveModel\")]\nstruct Fruit {\n    cake_id: Option<Option<i32>>,\n}\n```\n* Added `DatabaseConnection::close_by_ref` https://github.com/SeaQL/sea-orm/pull/2511\n```rust\npub async fn close(self) -> Result<(), DbErr> { .. } // existing\npub async fn close_by_ref(&self) -> Result<(), DbErr> { .. } // new\n```\n\n### House Keeping\n\n* Cleanup legacy `ActiveValue::Set` https://github.com/SeaQL/sea-orm/pull/2515\n\n## 1.1.6 - 2025-02-24\n\n### New Features\n\n* Support PgVector (under feature flag `postgres-vector`) https://github.com/SeaQL/sea-orm/pull/2500\n```rust\n// Model\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"image_model\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id: i32,\n    pub embedding: PgVector,\n}\n\n// Schema\nsea_query::Table::create()\n    .table(image_model::Entity.table_ref())\n    .col(ColumnDef::new(Column::Id).integer().not_null().primary_key())\n    .col(ColumnDef::new(Column::Embedding).vector(None).not_null())\n    ..\n\n// Insert\nActiveModel {\n    id: NotSet,\n    embedding: Set(PgVector::from(vec![1., 2., 3.])),\n}\n.insert(db)\n.await?\n```\n* Added `Insert::exec_with_returning_keys` & `Insert::exec_with_returning_many` (Postgres only)\n```rust\nassert_eq!(\n    Entity::insert_many([\n        ActiveModel { id: NotSet, name: Set(\"two\".into()) },\n        ActiveModel { id: NotSet, name: Set(\"three\".into()) },\n    ])\n    .exec_with_returning_many(db)\n    .await\n    .unwrap(),\n    [\n        Model { id: 2, name: \"two\".into() },\n        Model { id: 3, name: \"three\".into() },\n    ]\n);\n\nassert_eq!(\n    cakes_bakers::Entity::insert_many([\n        cakes_bakers::ActiveModel {\n            cake_id: Set(1),\n            baker_id: Set(2),\n        },\n        cakes_bakers::ActiveModel {\n            cake_id: Set(2),\n            baker_id: Set(1),\n        },\n    ])\n    .exec_with_returning_keys(db)\n    .await\n    .unwrap(),\n    [(1, 2), (2, 1)]\n);\n```\n* Added `DeleteOne::exec_with_returning` & `DeleteMany::exec_with_returning` https://github.com/SeaQL/sea-orm/pull/2432\n\n### Enhancements\n\n* Expose underlying row types (e.g. `sqlx::postgres::PgRow`) https://github.com/SeaQL/sea-orm/pull/2265\n* [sea-orm-cli] Added `acquire-timeout` option https://github.com/SeaQL/sea-orm/pull/2461\n* [sea-orm-cli] Added `with-prelude` option https://github.com/SeaQL/sea-orm/pull/2322\n* [sea-orm-cli] Added `impl-active-model-behavior` option https://github.com/SeaQL/sea-orm/pull/2487\n\n### Bug Fixes\n\n* Fixed `seaography::register_active_enums` macro https://github.com/SeaQL/sea-orm/pull/2475\n\n### House keeping\n\n* Remove `futures` crate, replace with `futures-util` https://github.com/SeaQL/sea-orm/pull/2466\n\n## 1.1.5 - 2025-02-14\n\n### New Features\n\n* Added `Schema::json_schema_from_entity` to construct a schema description in json for the given Entity\n\n## 1.1.4 - 2025-01-10\n\n### Enhancements\n\n* Allow modifying the connection in migrations https://github.com/SeaQL/sea-orm/pull/2397\n* `DeriveRelatedEntity` proc_macro use `async-graphql` re-exported by `seaography` https://github.com/SeaQL/sea-orm/pull/2469\n\n## 1.1.3 - 2024-12-24\n\n### New Features\n\n* [sea-orm-codegen] register seaography entity modules & active enums https://github.com/SeaQL/sea-orm/pull/2403\n```rust\npub mod prelude;\n\npub mod sea_orm_active_enums;\n\npub mod baker;\npub mod bakery;\npub mod cake;\npub mod cakes_bakers;\npub mod customer;\npub mod lineitem;\npub mod order;\n\nseaography::register_entity_modules!([\n    baker,\n    bakery,\n    cake,\n    cakes_bakers,\n    customer,\n    lineitem,\n    order,\n]);\n\nseaography::register_active_enums!([\n    sea_orm_active_enums::Tea,\n    sea_orm_active_enums::Color,\n]);\n```\n\n### Enhancements\n\n* Insert many allow active models to have different column set https://github.com/SeaQL/sea-orm/pull/2433\n```rust\n// this previously panics\nlet apple = cake_filling::ActiveModel {\n    cake_id: ActiveValue::set(2),\n    filling_id: ActiveValue::NotSet,\n};\nlet orange = cake_filling::ActiveModel {\n    cake_id: ActiveValue::NotSet,\n    filling_id: ActiveValue::set(3),\n};\nassert_eq!(\n    Insert::<cake_filling::ActiveModel>::new()\n        .add_many([apple, orange])\n        .build(DbBackend::Postgres)\n        .to_string(),\n    r#\"INSERT INTO \"cake_filling\" (\"cake_id\", \"filling_id\") VALUES (2, NULL), (NULL, 3)\"#,\n);\n```\n* [sea-orm-cli] Added `MIGRATION_DIR` environment variable https://github.com/SeaQL/sea-orm/pull/2419\n* Added `ColumnDef::is_unique` https://github.com/SeaQL/sea-orm/pull/2401\n* Postgres: quote schema in `search_path` https://github.com/SeaQL/sea-orm/pull/2436\n\n### Bug Fixes\n\n* MySQL: fix transaction isolation level not respected when used with access mode https://github.com/SeaQL/sea-orm/pull/2450\n\n## 1.1.2 - 2024-12-02\n\n### Enhancements\n\n* Added `ColumnTrait::enum_type_name()` to signify enum types https://github.com/SeaQL/sea-orm/pull/2415\n* Added `DbBackend::boolean_value()` for database dependent boolean value https://github.com/SeaQL/sea-orm/pull/2415\n\n## 1.1.1 - 2024-11-04\n\n### Enhancements\n\n* [sea-orm-macros] `impl From<Model> for ActiveModel` instead of `impl From<<Entity as sea_orm::EntityTrait>::Model> for ActiveModel` https://github.com/SeaQL/sea-orm/pull/2349.\nNow the following can compile:\n```rust\nuse sea_orm::{tests_cfg::cake, Set};\n\nstruct Cake {\n    id: i32,\n    name: String,\n}\n\nimpl From<Cake> for cake::ActiveModel {\n    fn from(value: Cake) -> Self {\n        Self {\n            id: Set(value.id),\n            name: Set(value.name),\n        }\n    }\n}\n```\n\n## 1.1.0 - 2024-10-15\n\n### Versions\n\n+ `1.1.0-rc.1`: 2024-08-09\n+ `1.1.0-rc.2`: 2024-10-04\n+ `1.1.0-rc.3`: 2024-10-08\n\n### Enhancements\n\n* [sea-orm-macros] Call `EnumIter::get` using fully qualified syntax https://github.com/SeaQL/sea-orm/pull/2321\n* Construct `DatabaseConnection` directly from `sqlx::PgPool`, `sqlx::SqlitePool` and `sqlx::MySqlPool` https://github.com/SeaQL/sea-orm/pull/2348\n* [sea-orm-migration] Add `pk_uuid` schema helper https://github.com/SeaQL/sea-orm/pull/2329\n* [sea-orm-migration] Allow `custom` and `custom_null` schema helper to take column name and alias of different `IntoIden` types https://github.com/SeaQL/sea-orm/pull/2326\n* Add `ColumnDef::get_column_default` getter https://github.com/SeaQL/sea-orm/pull/2387\n\n### Upgrades\n\n* Upgrade `sqlx` to `0.8.2` https://github.com/SeaQL/sea-orm/pull/2305, https://github.com/SeaQL/sea-orm/pull/2371\n* Upgrade `bigdecimal` to `0.4` https://github.com/SeaQL/sea-orm/pull/2305\n* Upgrade `sea-query` to `0.32.0-rc` https://github.com/SeaQL/sea-orm/pull/2305\n* Upgrade `sea-query-binder` to `0.7.0-rc` https://github.com/SeaQL/sea-orm/pull/2305\n* Upgrade `sea-schema` to `0.16.0-rc` https://github.com/SeaQL/sea-orm/pull/2305\n* Upgrade `ouroboros` to `0.18` https://github.com/SeaQL/sea-orm/pull/2353\n\n### House keeping\n\n* Fix typos https://github.com/SeaQL/sea-orm/pull/2360\n* Update documentations https://github.com/SeaQL/sea-orm/pull/2345\n\n## 1.0.1 - 2024-08-26\n\n### New Features\n\n* Added `ConnectOptions::connect_lazy` for creating DB connection pools without establishing connections up front https://github.com/SeaQL/sea-orm/pull/2268\n\n### Breaking Changes\n\n* Changed `ProxyDatabaseTrait` methods to async. It's a breaking change, but it should have been part of the 1.0 release.\n    The feature is behind the feature guard `proxy`, and we believe it shouldn't impact majority of users.\n    https://github.com/SeaQL/sea-orm/pull/2278\n\n### Bug Fixes\n\n* [sea-orm-codegen] Fix `ColumnType` to Rust type resolution https://github.com/SeaQL/sea-orm/pull/2313\n\n## 1.0.0 - 2024-08-02\n\n### Versions\n\n+ `1.0.0-rc.1`: 2024-02-06\n+ `1.0.0-rc.2`: 2024-03-15\n+ `1.0.0-rc.3`: 2024-03-26\n+ `1.0.0-rc.4`: 2024-05-13\n+ `1.0.0-rc.5`: 2024-05-29\n+ `1.0.0-rc.6`: 2024-06-19\n+ `1.0.0-rc.7`: 2024-06-25\n\n### New Features\n\n* Introduce `PrimaryKeyArity` with `ARITY` constant https://github.com/SeaQL/sea-orm/pull/2185\n```rust\nfn get_arity_of<E: EntityTrait>() -> usize {\n    E::PrimaryKey::iter().count() // before; runtime\n    <<E::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY // now; compile-time\n}\n```\n* Associate `ActiveModel` to `EntityTrait` https://github.com/SeaQL/sea-orm/pull/2186\n* [sea-orm-macros] Added `rename_all` attribute to `DeriveEntityModel` & `DeriveActiveEnum` https://github.com/SeaQL/sea-orm/pull/2170\n```rust\n#[derive(DeriveEntityModel)]\n#[sea_orm(table_name = \"user\", rename_all = \"camelCase\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    id: i32,\n    first_name: String, // firstName\n    #[sea_orm(column_name = \"lAsTnAmE\")]\n    last_name: String, // lAsTnAmE\n}\n\n#[derive(EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"String\", db_type = \"String(StringLen::None)\", rename_all = \"camelCase\")]\npub enum TestEnum {\n    DefaultVariant, // defaultVariant\n    #[sea_orm(rename = \"kebab-case\")]\n    VariantKebabCase, // variant-kebab-case\n    #[sea_orm(rename = \"snake_case\")]\n    VariantSnakeCase, // variant_snake_case\n    #[sea_orm(string_value = \"CuStOmStRiNgVaLuE\")]\n    CustomStringValue, // CuStOmStRiNgVaLuE\n}\n```\n* [sea-orm-migration] schema helper https://github.com/SeaQL/sea-orm/pull/2099\n```rust\n// Remember to import `sea_orm_migration::schema::*`\nuse sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(Users::Table)\n                    .if_not_exists()\n                    .col(pk_auto(Users::Id)) // Primary key with auto-increment\n                    .col(uuid(Users::Pid)) // UUID column\n                    .col(string_uniq(Users::Email)) // String column with unique constraint\n                    .col(string(Users::Password)) // String column\n                    .col(string(Users::ApiKey).unique_key())\n                    .col(string(Users::Name))\n                    .col(string_null(Users::ResetToken)) // Nullable string column\n                    .col(timestamp_null(Users::ResetSentAt)) // Nullable timestamp column\n                    .col(string_null(Users::EmailVerificationToken))\n                    .col(timestamp_null(Users::EmailVerificationSentAt))\n                    .col(timestamp_null(Users::EmailVerifiedAt))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    // ...\n}\n```\n\n### Enhancements\n\n* Added non-TLS runtime https://github.com/SeaQL/sea-orm/pull/2256\n* Added `QuerySelect::tbl_col_as`\n* Added `Insert::on_conflict_do_nothing` https://github.com/SeaQL/sea-orm/pull/2244\n* Migration schema nullable column set NULL explicitly https://github.com/SeaQL/sea-orm/pull/2255\n* Added `ActiveValue::set_if_not_equals()` https://github.com/SeaQL/sea-orm/pull/2194\n* Added `ActiveValue::try_as_ref()` https://github.com/SeaQL/sea-orm/pull/2197\n* Added `QuerySelect::order_by_with_nulls` https://github.com/SeaQL/sea-orm/pull/2228\n* Expose `get_xxx_connection_pool` by default https://github.com/SeaQL/sea-orm/pull/2233\n* Added `QueryResult::column_names` https://github.com/SeaQL/sea-orm/pull/2148\n* [sea-orm-macro] Add `@generated` in generated code https://github.com/SeaQL/sea-orm/pull/2199\n* [sea-orm-macro] Qualify traits in `DeriveActiveModel` macro https://github.com/SeaQL/sea-orm/pull/1665\n* [sea-orm-cli] Fix `migrate generate` on empty `mod.rs` files https://github.com/SeaQL/sea-orm/pull/2064\n* `DerivePartialModel` macro attribute `entity` now supports `syn::Type` https://github.com/SeaQL/sea-orm/pull/2137\n```rust\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"<entity::Model as ModelTrait>::Entity\")]\nstruct EntityNameNotAIdent {\n    #[sea_orm(from_col = \"foo2\")]\n    _foo: i32,\n    #[sea_orm(from_col = \"bar2\")]\n    _bar: String,\n}\n```\n* Added `RelationDef::from_alias()` https://github.com/SeaQL/sea-orm/pull/2146\n```rust\nlet cf = Alias::new(\"cf\");\n\nassert_eq!(\n    cake::Entity::find()\n        .join_as(\n            JoinType::LeftJoin,\n            cake_filling::Relation::Cake.def().rev(),\n            cf.clone()\n        )\n        .join(\n            JoinType::LeftJoin,\n            cake_filling::Relation::Filling.def().from_alias(cf)\n        )\n        .build(DbBackend::MySql)\n        .to_string(),\n    [\n        \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n        \"LEFT JOIN `cake_filling` AS `cf` ON `cake`.`id` = `cf`.`cake_id`\",\n        \"LEFT JOIN `filling` ON `cf`.`filling_id` = `filling`.`id`\",\n    ]\n    .join(\" \")\n);\n```\n\n### Bug Fixes\n\n* Set schema search path in Postgres without enclosing single quote https://github.com/SeaQL/sea-orm/pull/2241\n* [sea-orm-cli] Generate `has_one` relation for foreign key of unique index / constraint https://github.com/SeaQL/sea-orm/pull/2254\n\n### Breaking changes\n\n* Renamed `ConnectOptions::pool_options()` to `ConnectOptions::sqlx_pool_options()` https://github.com/SeaQL/sea-orm/pull/2145\n* Made `sqlx_common` private, hiding `sqlx_error_to_xxx_err` https://github.com/SeaQL/sea-orm/pull/2145\n* Rework SQLite type mappings https://github.com/SeaQL/sea-orm/pull/2077, https://github.com/SeaQL/sea-orm/pull/2078\n\n### Upgrades\n\n* Upgrade `time` to `0.3.36` https://github.com/SeaQL/sea-orm/pull/2267\n* Upgrade `strum` to `0.26` https://github.com/SeaQL/sea-orm/pull/2088\n* Upgrade `sea-schema` to `0.15.0`\n* Upgrade `sea-query-binder` to `0.6.0`\n* Upgrade `sea-query` to `0.31.0`\n\n### House keeping\n\n* Reduce warnings in integration tests https://github.com/SeaQL/sea-orm/pull/2177\n* Improved Actix example to return 404 not found on unexpected inputs https://github.com/SeaQL/sea-orm/pull/2140\n* Re-enable `rocket_okapi` example https://github.com/SeaQL/sea-orm/pull/2136\n\n## 1.0.0-rc.7 - 2024-06-25\n\n### Upgrades\n\n* Upgrade `sea-query-binder` to `0.6.0-rc.4` https://github.com/SeaQL/sea-orm/pull/2267\n* Upgrade `time` to `0.3.36` https://github.com/SeaQL/sea-orm/pull/2267\n\n## 1.0.0-rc.6 - 2024-06-19\n\n### Enhancements\n\n* Added non-TLS runtime https://github.com/SeaQL/sea-orm/pull/2256\n* Added `QuerySelect::tbl_col_as`\n* Added `Insert::on_conflict_do_nothing` https://github.com/SeaQL/sea-orm/pull/2244\n* Migration schema nullable column set NULL explicitly https://github.com/SeaQL/sea-orm/pull/2255\n\n### Bug Fixes\n\n* Set schema search path in Postgres without enclosing single quote https://github.com/SeaQL/sea-orm/pull/2241\n* [sea-orm-cli] Generate `has_one` relation for foreign key of unique index / constraint https://github.com/SeaQL/sea-orm/pull/2254\n\n## 1.0.0-rc.5 - 2024-05-29\n\n### New Features\n\n* Introduce `PrimaryKeyArity` with `ARITY` constant https://github.com/SeaQL/sea-orm/pull/2185\n```rust\nfn get_arity_of<E: EntityTrait>() -> usize {\n    E::PrimaryKey::iter().count() // before; runtime\n    <<E::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY // now; compile-time\n}\n```\n* Associate `ActiveModel` to `EntityTrait` https://github.com/SeaQL/sea-orm/pull/2186\n* [sea-orm-macros] Added `rename_all` attribute to `DeriveEntityModel` & `DeriveActiveEnum` https://github.com/SeaQL/sea-orm/pull/2170\n```rust\n#[derive(DeriveEntityModel)]\n#[sea_orm(table_name = \"user\", rename_all = \"camelCase\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    id: i32,\n    first_name: String, // firstName\n    #[sea_orm(column_name = \"lAsTnAmE\")]\n    last_name: String, // lAsTnAmE\n}\n\n#[derive(EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"String\", db_type = \"String(StringLen::None)\", rename_all = \"camelCase\")]\npub enum TestEnum {\n    DefaultVariant, // defaultVariant\n    #[sea_orm(rename = \"kebab-case\")]\n    VariantKebabCase, // variant-kebab-case\n    #[sea_orm(rename = \"snake_case\")]\n    VariantSnakeCase, // variant_snake_case\n    #[sea_orm(string_value = \"CuStOmStRiNgVaLuE\")]\n    CustomStringValue, // CuStOmStRiNgVaLuE\n}\n```\n\n### Enhancements\n\n* Added `ActiveValue::set_if_not_equals()` https://github.com/SeaQL/sea-orm/pull/2194\n* Added `ActiveValue::try_as_ref()` https://github.com/SeaQL/sea-orm/pull/2197\n* Added `QuerySelect::order_by_with_nulls` https://github.com/SeaQL/sea-orm/pull/2228\n* Expose `get_xxx_connection_pool` by default https://github.com/SeaQL/sea-orm/pull/2233\n\n## 1.0.0-rc.4 - 2024-05-13\n\n### Enhancements\n\n* Added `QueryResult::column_names` https://github.com/SeaQL/sea-orm/pull/2148\n* [sea-orm-macro] Add `@generated` in generated code https://github.com/SeaQL/sea-orm/pull/2199\n\n### Upgrades\n\n* Upgrade `sea-query` to `0.31.0-rc.6`\n* Upgrade `sea-schema` to `0.15.0-rc.6`\n\n### House Keeping\n\n* Reduce warnings in integration tests https://github.com/SeaQL/sea-orm/pull/2177\n\n## 1.0.0-rc.3 - 2024-03-26\n\n### Enhancements\n\n* [sea-orm-macro] Qualify traits in `DeriveActiveModel` macro https://github.com/SeaQL/sea-orm/pull/1665\n\n## 1.0.0-rc.2 - 2024-03-15\n\n### Breaking Changes\n\n* Renamed `ConnectOptions::pool_options()` to `ConnectOptions::sqlx_pool_options()` https://github.com/SeaQL/sea-orm/pull/2145\n* Made `sqlx_common` private, hiding `sqlx_error_to_xxx_err` https://github.com/SeaQL/sea-orm/pull/2145\n\n### Enhancements\n\n* [sea-orm-cli] Fix `migrate generate` on empty `mod.rs` files https://github.com/SeaQL/sea-orm/pull/2064\n* `DerivePartialModel` macro attribute `entity` now supports `syn::Type` https://github.com/SeaQL/sea-orm/pull/2137\n```rust\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"<entity::Model as ModelTrait>::Entity\")]\nstruct EntityNameNotAIdent {\n    #[sea_orm(from_col = \"foo2\")]\n    _foo: i32,\n    #[sea_orm(from_col = \"bar2\")]\n    _bar: String,\n}\n```\n* Added `RelationDef::from_alias()` https://github.com/SeaQL/sea-orm/pull/2146\n```rust\nlet cf = Alias::new(\"cf\");\n\nassert_eq!(\n    cake::Entity::find()\n        .join_as(\n            JoinType::LeftJoin,\n            cake_filling::Relation::Cake.def().rev(),\n            cf.clone()\n        )\n        .join(\n            JoinType::LeftJoin,\n            cake_filling::Relation::Filling.def().from_alias(cf)\n        )\n        .build(DbBackend::MySql)\n        .to_string(),\n    [\n        \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n        \"LEFT JOIN `cake_filling` AS `cf` ON `cake`.`id` = `cf`.`cake_id`\",\n        \"LEFT JOIN `filling` ON `cf`.`filling_id` = `filling`.`id`\",\n    ]\n    .join(\" \")\n);\n```\n\n### Upgrades\n\n* Upgrade `sea-schema` to `0.15.0-rc.3`\n* Upgrade `strum` to `0.26` https://github.com/SeaQL/sea-orm/pull/2088\n\n### House keeping\n\n* Improved Actix example to return 404 not found on unexpected inputs https://github.com/SeaQL/sea-orm/pull/2140\n* Re-enable `rocket_okapi` example https://github.com/SeaQL/sea-orm/pull/2136\n\n## 1.0.0-rc.1 - 2024-02-06\n\n### New Features\n\n* [sea-orm-migration] schema helper https://github.com/SeaQL/sea-orm/pull/2099\n```rust\n// Remember to import `sea_orm_migration::schema::*`\nuse sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(Users::Table)\n                    .if_not_exists()\n                    .col(pk_auto(Users::Id)) // Primary key with auto-increment\n                    .col(uuid(Users::Pid)) // UUID column\n                    .col(string_uniq(Users::Email)) // String column with unique constraint\n                    .col(string(Users::Password)) // String column\n                    .col(string(Users::ApiKey).unique_key())\n                    .col(string(Users::Name))\n                    .col(string_null(Users::ResetToken)) // Nullable string column\n                    .col(timestamp_null(Users::ResetSentAt)) // Nullable timestamp column\n                    .col(string_null(Users::EmailVerificationToken))\n                    .col(timestamp_null(Users::EmailVerificationSentAt))\n                    .col(timestamp_null(Users::EmailVerifiedAt))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    // ...\n}\n```\n\n### Breaking Changes\n\n* Rework SQLite type mappings https://github.com/SeaQL/sea-orm/pull/2077, https://github.com/SeaQL/sea-orm/pull/2078\n* Updated `sea-query` to `0.31`\n\n## 0.12.14 - 2024-02-05\n\n* Added feature flag `sqlite-use-returning-for-3_35` to use SQLite's returning https://github.com/SeaQL/sea-orm/pull/2070\n* Added Loco example https://github.com/SeaQL/sea-orm/pull/2092\n\n## 0.12.12 - 2024-01-22\n\n### Bug Fixes\n\n* [sea-orm-cli] Fix entity generation for non-alphanumeric enum variants https://github.com/SeaQL/sea-orm/pull/1821\n* [sea-orm-cli] Fix entity generation for relations with composite keys https://github.com/SeaQL/sea-orm/pull/2071\n\n### Enhancements\n\n* Added `ConnectOptions::test_before_acquire`\n\n## 0.12.11 - 2024-01-14\n\n### New Features\n\n* Added `desc` to `Cursor` paginator https://github.com/SeaQL/sea-orm/pull/2037\n\n### Enhancements\n\n* Improve query performance of `Paginator`'s `COUNT` query https://github.com/SeaQL/sea-orm/pull/2030\n* Added SQLx slow statements logging to `ConnectOptions` https://github.com/SeaQL/sea-orm/pull/2055\n* Added `QuerySelect::lock_with_behavior` https://github.com/SeaQL/sea-orm/pull/1867\n\n### Bug Fixes\n\n* [sea-orm-macro] Qualify types in `DeriveValueType` macro https://github.com/SeaQL/sea-orm/pull/2054\n\n### House keeping\n\n* Fix clippy warnings on 1.75 https://github.com/SeaQL/sea-orm/pull/2057\n\n## 0.12.10 - 2023-12-14\n\n### New Features\n\n* [sea-orm-macro] Comment attribute for Entity (`#[sea_orm(comment = \"action\")]`); `create_table_from_entity` supports comment https://github.com/SeaQL/sea-orm/pull/2009\n* Added \"proxy\" (feature flag `proxy`) to database backend https://github.com/SeaQL/sea-orm/pull/1881, https://github.com/SeaQL/sea-orm/pull/2000\n\n### Enhancements\n\n* Cast enums in `is_in` and `is_not_in` https://github.com/SeaQL/sea-orm/pull/2002\n\n### Upgrades\n\n* Updated `sea-query` to `0.30.5` https://github.com/SeaQL/sea-query/releases/tag/0.30.5\n\n## 0.12.9 - 2023-12-08\n\n### Enhancements\n\n* Add source annotations to errors https://github.com/SeaQL/sea-orm/pull/1999\n\n### Upgrades\n\n* Updated `sea-query` to `0.30.4` https://github.com/SeaQL/sea-query/releases/tag/0.30.4\n\n## 0.12.8 - 2023-12-04\n\n### Enhancements\n\n* Implement `StatementBuilder` for `sea_query::WithQuery` https://github.com/SeaQL/sea-orm/issues/1960\n\n### Upgrades\n\n* Upgrade `axum` example to `0.7` https://github.com/SeaQL/sea-orm/pull/1984\n\n## 0.12.7 - 2023-11-22\n\n### Enhancements\n\n* Added method `expr_as_` that accepts `self` https://github.com/SeaQL/sea-orm/pull/1979\n\n### Upgrades\n\n* Updated `sea-query` to `0.30.3` https://github.com/SeaQL/sea-query/releases/tag/0.30.3\n\n## 0.12.6 - 2023-11-13\n\n### New Features\n\n* Added `#[sea_orm(skip)]` for `FromQueryResult` derive macro https://github.com/SeaQL/sea-orm/pull/1954\n\n## 0.12.5 - 2023-11-12\n\n### Bug Fixes\n\n* [sea-orm-cli] Fix duplicated active enum use statements on generated entities https://github.com/SeaQL/sea-orm/pull/1953\n* [sea-orm-cli] Added `--enum-extra-derives` https://github.com/SeaQL/sea-orm/pull/1934\n* [sea-orm-cli] Added `--enum-extra-attributes` https://github.com/SeaQL/sea-orm/pull/1952\n\n## 0.12.4 - 2023-10-19\n\n### New Features\n\n* Add support for root JSON arrays https://github.com/SeaQL/sea-orm/pull/1898\n    Now the following works (requires the `json-array` / `postgres-array` feature)!\n```rust\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"json_struct_vec\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Json\")]\n    pub struct_vec: Vec<JsonColumn>,\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, FromJsonQueryResult)]\npub struct JsonColumn {\n    pub value: String,\n}\n```\n\n### Enhancements\n\n* Loader: use `ValueTuple` as hash key https://github.com/SeaQL/sea-orm/pull/1868\n\n### Upgrades\n\n* Updated `sea-query` to `0.30.2` https://github.com/SeaQL/sea-query/releases/tag/0.30.2\n\n## 0.12.3 - 2023-09-22\n\n### New Features\n\n* [sea-orm-migration] Check if an index exists https://github.com/SeaQL/sea-orm/pull/1828\n* Added `cursor_by` to `SelectTwo` https://github.com/SeaQL/sea-orm/pull/1826\n\n### Enhancements\n\n* [sea-orm-cli] Support generation of related entity with composite foreign key https://github.com/SeaQL/sea-orm/pull/1693\n\n### Bug Fixes\n\n* [sea-orm-macro] Fixed `DeriveValueType` by qualifying `QueryResult` https://github.com/SeaQL/sea-orm/pull/1855\n* Fixed `Loader` panic on empty inputs\n\n### Upgrades\n\n* Upgraded `salvo` to `0.50`\n* Upgraded `chrono` to `0.4.30` https://github.com/SeaQL/sea-orm/pull/1858\n* Updated `sea-query` to `0.30.1`\n* Updated `sea-schema` to `0.14.1`\n\n### House keeping\n\n* Added test cases for `find_xxx_related/linked` https://github.com/SeaQL/sea-orm/pull/1811\n\n## 0.12.2 - 2023-08-04\n\n### Enhancements\n\n* Added support for Postgres arrays in `FromQueryResult` impl of `JsonValue` https://github.com/SeaQL/sea-orm/pull/1598\n\n### Bug fixes\n\n* Fixed `find_with_related` consolidation logic https://github.com/SeaQL/sea-orm/issues/1800\n\n## 0.12.1 - 2023-07-27\n\n+ `0.12.0-rc.1`: Yanked\n+ `0.12.0-rc.2`: 2023-05-19\n+ `0.12.0-rc.3`: 2023-06-22\n+ `0.12.0-rc.4`: 2023-07-08\n+ `0.12.0-rc.5`: 2023-07-22\n\n### New Features\n\n* Added `MigratorTrait::migration_table_name()` method to configure the name of migration table https://github.com/SeaQL/sea-orm/pull/1511\n```rust\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    // Override the name of migration table\n    fn migration_table_name() -> sea_orm::DynIden {\n        Alias::new(\"override_migration_table_name\").into_iden()\n    }\n    ...\n}\n```\n* Added option to construct chained AND / OR join on condition https://github.com/SeaQL/sea-orm/pull/1433\n```rust\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    // By default, it's\n    // `JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` AND `fruit`.`name` LIKE '%tropical%'`\n    #[sea_orm(\n        has_many = \"super::fruit::Entity\",\n        on_condition = r#\"super::fruit::Column::Name.like(\"%tropical%\")\"#\n    )]\n    TropicalFruit,\n    // Or specify `condition_type = \"any\"` to override it,\n    // `JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` OR `fruit`.`name` LIKE '%tropical%'`\n    #[sea_orm(\n        has_many = \"super::fruit::Entity\",\n        on_condition = r#\"super::fruit::Column::Name.like(\"%tropical%\")\"#\n        condition_type = \"any\",\n    )]\n    OrTropicalFruit,\n}\n```\n* Supports entity with composite primary key of arity 12 https://github.com/SeaQL/sea-orm/pull/1508\n    * `Identity` supports tuple of `DynIden` with arity up to 12\n```rust\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"primary_key_of_12\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_1: String,\n    ...\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_12: bool,\n}\n```\n* Added macro `DerivePartialModel` https://github.com/SeaQL/sea-orm/pull/1597\n```rust\n#[derive(DerivePartialModel, FromQueryResult)]\n#[sea_orm(entity = \"Cake\")]\nstruct PartialCake {\n    name: String,\n    #[sea_orm(\n        from_expr = r#\"SimpleExpr::FunctionCall(Func::upper(Expr::col((Cake, cake::Column::Name))))\"#\n    )]\n    name_upper: String,\n}\n\nassert_eq!(\n    cake::Entity::find()\n        .into_partial_model::<PartialCake>()\n        .into_statement(DbBackend::Sqlite)\n        .to_string(),\n    r#\"SELECT \"cake\".\"name\", UPPER(\"cake\".\"name\") AS \"name_upper\" FROM \"cake\"\"#\n);\n```\n* Added `DbErr::sql_err()` method to convert error into common database errors `SqlErr`, such as unique constraint or foreign key violation errors. https://github.com/SeaQL/sea-orm/pull/1707\n```rust\nassert!(matches!(\n    cake.into_active_model().insert(db).await\n        .expect_err(\"Insert a row with duplicated primary key\")\n        .sql_err(),\n    Some(SqlErr::UniqueConstraintViolation(_))\n));\n\nassert!(matches!(\n    fk_cake.insert(db).await\n        .expect_err(\"Insert a row with invalid foreign key\")\n        .sql_err(),\n    Some(SqlErr::ForeignKeyConstraintViolation(_))\n));\n```\n* Added `Select::find_with_linked`, similar to `find_with_related`: https://github.com/SeaQL/sea-orm/pull/1728, https://github.com/SeaQL/sea-orm/pull/1743\n```rust\nfn find_with_related<R>(self, r: R) -> SelectTwoMany<E, R>\n    where R: EntityTrait, E: Related<R>;\nfn find_with_linked<L, T>(self, l: L) -> SelectTwoMany<E, T>\n    where L: Linked<FromEntity = E, ToEntity = T>, T: EntityTrait;\n\n// boths yields `Vec<(E::Model, Vec<F::Model>)>`\n```\n* Added `DeriveValueType` derive macro for custom wrapper types, implementations of the required traits will be provided, you can customize the `column_type` and `array_type` if needed https://github.com/SeaQL/sea-orm/pull/1720\n```rust\n#[derive(DeriveValueType)]\n#[sea_orm(array_type = \"Int\")]\npub struct Integer(i32);\n\n#[derive(DeriveValueType)]\n#[sea_orm(column_type = \"Boolean\", array_type = \"Bool\")]\npub struct Boolbean(pub String);\n\n#[derive(DeriveValueType)]\npub struct StringVec(pub Vec<String>);\n```\n* Added `DeriveDisplay` derive macro to implements `std::fmt::Display` for enum https://github.com/SeaQL/sea-orm/pull/1726\n```rust\n#[derive(DeriveDisplay)]\nenum DisplayTea {\n    EverydayTea,\n    #[sea_orm(display_value = \"Breakfast Tea\")]\n    BreakfastTea,\n}\nassert_eq!(format!(\"{}\", DisplayTea::EverydayTea), \"EverydayTea\");\nassert_eq!(format!(\"{}\", DisplayTea::BreakfastTea), \"Breakfast Tea\");\n```\n* Added `UpdateMany::exec_with_returning()` https://github.com/SeaQL/sea-orm/pull/1677\n```rust\nlet models: Vec<Model> = Entity::update_many()\n    .col_expr(Column::Values, Expr::expr(..))\n    .exec_with_returning(db)\n    .await?;\n```\n* Supporting `default_expr` in `DeriveEntityModel` https://github.com/SeaQL/sea-orm/pull/1474\n```rust\n#[derive(DeriveEntityModel)]\n#[sea_orm(table_name = \"hello\")]\npub struct Model {\n    #[sea_orm(default_expr = \"Expr::current_timestamp()\")]\n    pub timestamp: DateTimeUtc,\n}\n\nassert_eq!(\n    Column::Timestamp.def(),\n    ColumnType::TimestampWithTimeZone.def()\n        .default(Expr::current_timestamp())\n);\n```\n* Introduced new `ConnAcquireErr` https://github.com/SeaQL/sea-orm/pull/1737\n```rust\nenum DbErr {\n    ConnectionAcquire(ConnAcquireErr),\n    ..\n}\n\nenum ConnAcquireErr {\n    Timeout,\n    ConnectionClosed,\n}\n```\n\n#### Seaography\n\nAdded Seaography integration https://github.com/SeaQL/sea-orm/pull/1599\n\n* Added `DeriveEntityRelated` macro which will implement `seaography::RelationBuilder` for `RelatedEntity` enumeration when the `seaography` feature is enabled\n* Added generation of `seaography` related information to `sea-orm-codegen`.\n\n    The `RelatedEntity` enum is added in entities files by `sea-orm-cli` when flag `seaography` is set:\n```rust\n/// SeaORM Entity\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]\npub enum RelatedEntity {\n    #[sea_orm(entity = \"super::bakery::Entity\")]\n    Bakery,\n    #[sea_orm(entity = \"super::cake_baker::Entity\")]\n    CakeBaker,\n    #[sea_orm(entity = \"super::cake::Entity\")]\n    Cake,\n}\n```\n* Added [`seaography_example`](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example)\n\n### Enhancements\n\n* Supports for partial select of `Option<T>` model field. A `None` value will be filled when the select result does not contain the `Option<T>` field without throwing an error. https://github.com/SeaQL/sea-orm/pull/1513\n* [sea-orm-cli] the `migrate init` command will create a `.gitignore` file when the migration folder reside in a Git repository https://github.com/SeaQL/sea-orm/pull/1334\n* [sea-orm-cli] Added support for generating migration of space separated name, for example executing `sea-orm-cli migrate generate \"create accounts table\"` command will create `m20230503_000000_create_accounts_table.rs` for you https://github.com/SeaQL/sea-orm/pull/1570\n* Added `Migration::name()` and `Migration::status()` getters for the name and status of `sea_orm_migration::Migration` https://github.com/SeaQL/sea-orm/pull/1519\n```rust\nlet migrations = Migrator::get_pending_migrations(db).await?;\nassert_eq!(migrations.len(), 5);\n\nlet migration = migrations.get(0).unwrap();\nassert_eq!(migration.name(), \"m20220118_000002_create_fruit_table\");\nassert_eq!(migration.status(), MigrationStatus::Pending);\n```\n* The `postgres-array` feature will be enabled when `sqlx-postgres` backend is selected https://github.com/SeaQL/sea-orm/pull/1565\n* Replace `String` parameters in API with `Into<String>` https://github.com/SeaQL/sea-orm/pull/1439\n    * Implements `IntoMockRow` for any `BTreeMap` that is indexed by string `impl IntoMockRow for BTreeMap<T, Value> where T: Into<String>`\n    * Converts any string value into `ConnectOptions` - `impl From<T> for ConnectOptions where T: Into<String>`\n    * Changed the parameter of method `ConnectOptions::new(T) where T: Into<String>` to takes any string SQL\n    * Changed the parameter of method `Statement::from_string(DbBackend, T) where T: Into<String>` to takes any string SQL\n    * Changed the parameter of method `Statement::from_sql_and_values(DbBackend, T, I) where I: IntoIterator<Item = Value>, T: Into<String>` to takes any string SQL\n    * Changed the parameter of method `Transaction::from_sql_and_values(DbBackend, T, I) where I: IntoIterator<Item = Value>, T: Into<String>` to takes any string SQL\n    * Changed the parameter of method `ConnectOptions::set_schema_search_path(T) where T: Into<String>` to takes any string\n    * Changed the parameter of method `ColumnTrait::like()`, `ColumnTrait::not_like()`, `ColumnTrait::starts_with()`, `ColumnTrait::ends_with()` and `ColumnTrait::contains()` to takes any string\n* Added `sea_query::{DynIden, RcOrArc, SeaRc}` to entity prelude https://github.com/SeaQL/sea-orm/pull/1661\n* Added `expr`, `exprs` and `expr_as` methods to `QuerySelect` trait https://github.com/SeaQL/sea-orm/pull/1702\n* Added `DatabaseConnection::ping` https://github.com/SeaQL/sea-orm/pull/1627\n```rust\n|db: DatabaseConnection| {\n    assert!(db.ping().await.is_ok());\n    db.clone().close().await;\n    assert!(matches!(db.ping().await, Err(DbErr::ConnectionAcquire)));\n}\n```\n* Added `TryInsert` that does not panic on empty inserts https://github.com/SeaQL/sea-orm/pull/1708\n```rust\n// now, you can do:\nlet res = Bakery::insert_many(std::iter::empty())\n    .on_empty_do_nothing()\n    .exec(db)\n    .await;\n\nassert!(matches!(res, Ok(TryInsertResult::Empty)));\n```\n* Insert on conflict do nothing to return Ok https://github.com/SeaQL/sea-orm/pull/1712\n```rust\nlet on = OnConflict::column(Column::Id).do_nothing().to_owned();\n\n// Existing behaviour\nlet res = Entity::insert_many([..]).on_conflict(on).exec(db).await;\nassert!(matches!(res, Err(DbErr::RecordNotInserted)));\n\n// New API; now you can:\nlet res =\nEntity::insert_many([..]).on_conflict(on).do_nothing().exec(db).await;\nassert!(matches!(res, Ok(TryInsertResult::Conflicted)));\n```\n\n### Bug Fixes\n\n* Fixed `DeriveActiveEnum` throwing errors because `string_value` consists non-UAX#31 compliant characters https://github.com/SeaQL/sea-orm/pull/1374\n```rust\n#[derive(EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"String\", db_type = \"String(None)\")]\npub enum StringValue {\n    #[sea_orm(string_value = \"\")]\n    Member1,\n    #[sea_orm(string_value = \"$$\")]\n    Member2,\n}\n// will now produce the following enum:\npub enum StringValueVariant {\n    __Empty,\n    _0x240x24,\n}\n```\n* [sea-orm-cli] Fix Postgres enum arrays https://github.com/SeaQL/sea-orm/pull/1678\n* [sea-orm-cli] The implementation of `Related<R>` with `via` and `to` methods will not be generated if there exists multiple paths via an intermediate table https://github.com/SeaQL/sea-orm/pull/1435\n* [sea-orm-cli] fixed entity generation includes partitioned tables https://github.com/SeaQL/sea-orm/issues/1582, https://github.com/SeaQL/sea-schema/pull/105\n* Fixed `ActiveEnum::db_type()` return type does not implement `ColumnTypeTrait` https://github.com/SeaQL/sea-orm/pull/1576\n* Resolved `insert_many` failing if the models iterator is empty https://github.com/SeaQL/sea-orm/issues/873\n\n### Breaking changes\n\n* Supports for partial select of `Option<T>` model field. A `None` value will be filled when the select result does not contain the `Option<T>` field instead of throwing an error. https://github.com/SeaQL/sea-orm/pull/1513\n* Replaced `sea-strum` dependency with upstream `strum` in `sea-orm` https://github.com/SeaQL/sea-orm/pull/1535\n    * Added `derive` and `strum` features to `sea-orm-macros`\n    * The derive macro `EnumIter` is now shipped by `sea-orm-macros`\n* Added a new variant `Many` to `Identity` https://github.com/SeaQL/sea-orm/pull/1508\n* Enabled `hashable-value` feature in SeaQuery, thus `Value::Float(NaN) == Value::Float(NaN)` would be true https://github.com/SeaQL/sea-orm/pull/1728, https://github.com/SeaQL/sea-orm/pull/1743\n* The `DeriveActiveEnum` derive macro no longer implement `std::fmt::Display`. You can use the new `DeriveDisplay` macro https://github.com/SeaQL/sea-orm/pull/1726\n* `sea-query/derive` is no longer enabled by `sea-orm`, as such, `Iden` no longer works as a derive macro (it's still a trait). Instead, we are shipping a new macro `DeriveIden` https://github.com/SeaQL/sea-orm/pull/1740 https://github.com/SeaQL/sea-orm/pull/1755\n```rust\n// then:\n\n#[derive(Iden)]\n#[iden = \"category\"]\npub struct CategoryEnum;\n\n#[derive(Iden)]\npub enum Tea {\n    Table,\n    #[iden = \"EverydayTea\"]\n    EverydayTea,\n}\n\n// now:\n\n#[derive(DeriveIden)]\n#[sea_orm(iden = \"category\")]\npub struct CategoryEnum;\n\n#[derive(DeriveIden)]\npub enum Tea {\n    Table,\n    #[sea_orm(iden = \"EverydayTea\")]\n    EverydayTea,\n}\n```\n* Definition of `DbErr::ConnectionAcquire` changed to `ConnectionAcquire(ConnAcquireErr)` https://github.com/SeaQL/sea-orm/pull/1737\n* `FromJsonQueryResult` removed from entity prelude\n\n### Upgrades\n\n* Upgraded `sqlx` to `0.7` https://github.com/SeaQL/sea-orm/pull/1742\n* Upgraded `sea-query` to `0.30` https://github.com/SeaQL/sea-orm/pull/1742\n* Upgraded `sea-schema` to `0.14` https://github.com/SeaQL/sea-orm/pull/1742\n* Upgraded `syn` to `2` https://github.com/SeaQL/sea-orm/pull/1713\n* Upgraded `heck` to `0.4` https://github.com/SeaQL/sea-orm/pull/1520, https://github.com/SeaQL/sea-orm/pull/1544\n* Upgraded `strum` to `0.25` https://github.com/SeaQL/sea-orm/pull/1752\n* Upgraded `clap` to `4.3` https://github.com/SeaQL/sea-orm/pull/1468\n* Upgraded `ouroboros` to `0.17` https://github.com/SeaQL/sea-orm/pull/1724\n\n### House keeping\n\n* Replaced `bae` with `sea-bae` https://github.com/SeaQL/sea-orm/pull/1739\n\n**Full Changelog**: https://github.com/SeaQL/sea-orm/compare/0.11.1...0.12.1\n\n## 0.11.3 - 2023-04-24\n\n### Enhancements\n\n* Re-export `sea_orm::ConnectionTrait` in `sea_orm_migration::prelude` https://github.com/SeaQL/sea-orm/pull/1577\n* Support generic structs in `FromQueryResult` derive macro https://github.com/SeaQL/sea-orm/pull/1464, https://github.com/SeaQL/sea-orm/pull/1603\n```rust\n#[derive(FromQueryResult)]\nstruct GenericTest<T: TryGetable> {\n    foo: i32,\n    bar: T,\n}\n```\n```rust\ntrait MyTrait {\n    type Item: TryGetable;\n}\n\n#[derive(FromQueryResult)]\nstruct TraitAssociateTypeTest<T>\nwhere\n    T: MyTrait,\n{\n    foo: T::Item,\n}\n```\n\n### Bug Fixes\n\n* Fixed https://github.com/SeaQL/sea-orm/issues/1608 by pinning the version of `tracing-subscriber` dependency to 0.3.17 https://github.com/SeaQL/sea-orm/pull/1609\n\n## 0.11.2 - 2023-03-25\n\n### Enhancements\n\n* Enable required `syn` features https://github.com/SeaQL/sea-orm/pull/1556\n* Re-export `sea_query::BlobSize` in `sea_orm::entity::prelude` https://github.com/SeaQL/sea-orm/pull/1548\n\n## 0.11.1 - 2023-03-10\n\n### Bug Fixes\n\n* Fixes `DeriveActiveEnum` (by qualifying `ColumnTypeTrait::def`) https://github.com/SeaQL/sea-orm/issues/1478\n* The CLI command `sea-orm-cli generate entity -u '<DB-URL>'` will now generate the following code for each `Binary` or `VarBinary` columns in compact format https://github.com/SeaQL/sea-orm/pull/1529\n```rust\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n#[sea_orm(table_name = \"binary\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Binary(BlobSize::Blob(None))\")]\n    pub binary: Vec<u8>,\n    #[sea_orm(column_type = \"Binary(BlobSize::Blob(Some(10)))\")]\n    pub binary_10: Vec<u8>,\n    #[sea_orm(column_type = \"Binary(BlobSize::Tiny)\")]\n    pub binary_tiny: Vec<u8>,\n    #[sea_orm(column_type = \"Binary(BlobSize::Medium)\")]\n    pub binary_medium: Vec<u8>,\n    #[sea_orm(column_type = \"Binary(BlobSize::Long)\")]\n    pub binary_long: Vec<u8>,\n    #[sea_orm(column_type = \"VarBinary(10)\")]\n    pub var_binary: Vec<u8>,\n}\n```\n* The CLI command `sea-orm-cli generate entity -u '<DB-URL>' --expanded-format` will now generate the following code for each `Binary` or `VarBinary` columns in expanded format https://github.com/SeaQL/sea-orm/pull/1529\n```rust\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Binary => ColumnType::Binary(sea_orm::sea_query::BlobSize::Blob(None)).def(),\n            Self::Binary10 => {\n                ColumnType::Binary(sea_orm::sea_query::BlobSize::Blob(Some(10u32))).def()\n            }\n            Self::BinaryTiny => ColumnType::Binary(sea_orm::sea_query::BlobSize::Tiny).def(),\n            Self::BinaryMedium => ColumnType::Binary(sea_orm::sea_query::BlobSize::Medium).def(),\n            Self::BinaryLong => ColumnType::Binary(sea_orm::sea_query::BlobSize::Long).def(),\n            Self::VarBinary => ColumnType::VarBinary(10u32).def(),\n        }\n    }\n}\n```\n* Fix missing documentation on type generated by derive macros https://github.com/SeaQL/sea-orm/pull/1522, https://github.com/SeaQL/sea-orm/pull/1531\n\n## 0.11.0 - 2023-02-07\n\n+ 2023-02-02: `0.11.0-rc.1`\n+ 2023-02-04: `0.11.0-rc.2`\n\n### New Features\n\n#### SeaORM Core\n\n* Simple data loader https://github.com/SeaQL/sea-orm/pull/1238, https://github.com/SeaQL/sea-orm/pull/1443\n* Transactions Isolation level and Access mode https://github.com/SeaQL/sea-orm/pull/1230\n* Support various UUID formats that are available in `uuid::fmt` module https://github.com/SeaQL/sea-orm/pull/1325\n* Support Vector of enum for Postgres https://github.com/SeaQL/sea-orm/pull/1210\n* Support `ActiveEnum` field as primary key https://github.com/SeaQL/sea-orm/pull/1414\n* Casting columns as a different data type on select, insert and update https://github.com/SeaQL/sea-orm/pull/1304\n* Methods of `ActiveModelBehavior` receive db connection as a parameter https://github.com/SeaQL/sea-orm/pull/1145, https://github.com/SeaQL/sea-orm/pull/1328\n* Added `execute_unprepared` method to `DatabaseConnection` and `DatabaseTransaction` https://github.com/SeaQL/sea-orm/pull/1327\n* Added `Select::into_tuple` to select rows as tuples (instead of defining a custom Model) https://github.com/SeaQL/sea-orm/pull/1311\n\n#### SeaORM CLI\n\n* Generate `#[serde(skip_deserializing)]` for primary key columns https://github.com/SeaQL/sea-orm/pull/846, https://github.com/SeaQL/sea-orm/pull/1186, https://github.com/SeaQL/sea-orm/pull/1318\n* Generate `#[serde(skip)]` for hidden columns https://github.com/SeaQL/sea-orm/pull/1171, https://github.com/SeaQL/sea-orm/pull/1320\n* Generate entity with extra derives and attributes for model struct https://github.com/SeaQL/sea-orm/pull/1124, https://github.com/SeaQL/sea-orm/pull/1321\n\n#### SeaORM Migration\n\n* Migrations are now performed inside a transaction for Postgres https://github.com/SeaQL/sea-orm/pull/1379\n\n### Enhancements\n\n* Refactor schema module to expose functions for database alteration https://github.com/SeaQL/sea-orm/pull/1256\n* Generate compact entity with `#[sea_orm(column_type = \"JsonBinary\")]` macro attribute https://github.com/SeaQL/sea-orm/pull/1346\n* `MockDatabase::append_exec_results()`, `MockDatabase::append_query_results()`, `MockDatabase::append_exec_errors()` and `MockDatabase::append_query_errors()` take any types implemented `IntoIterator` trait https://github.com/SeaQL/sea-orm/pull/1367\n* `find_by_id` and `delete_by_id` take any `Into` primary key value https://github.com/SeaQL/sea-orm/pull/1362\n* `QuerySelect::offset` and `QuerySelect::limit` takes in `Into<Option<u64>>` where `None` would reset them https://github.com/SeaQL/sea-orm/pull/1410\n* Added `DatabaseConnection::close` https://github.com/SeaQL/sea-orm/pull/1236\n* Added `is_null` getter for `ColumnDef` https://github.com/SeaQL/sea-orm/pull/1381\n* Added `ActiveValue::reset` to convert `Unchanged` into `Set` https://github.com/SeaQL/sea-orm/pull/1177\n* Added `QueryTrait::apply_if` to optionally apply a filter https://github.com/SeaQL/sea-orm/pull/1415\n* Added the `sea-orm-internal` feature flag to expose some SQLx types\n    * Added `DatabaseConnection::get_*_connection_pool()` for accessing the inner SQLx connection pool https://github.com/SeaQL/sea-orm/pull/1297\n    * Re-exporting SQLx errors https://github.com/SeaQL/sea-orm/pull/1434\n\n### Upgrades\n\n* Upgrade `axum` to `0.6.1` https://github.com/SeaQL/sea-orm/pull/1285\n* Upgrade `sea-query` to `0.28` https://github.com/SeaQL/sea-orm/pull/1366\n* Upgrade `sea-query-binder` to `0.3` https://github.com/SeaQL/sea-orm/pull/1366\n* Upgrade `sea-schema` to `0.11` https://github.com/SeaQL/sea-orm/pull/1366\n\n### House Keeping\n\n* Fixed all clippy warnings as of `1.67.0` https://github.com/SeaQL/sea-orm/pull/1426\n* Removed dependency where not needed https://github.com/SeaQL/sea-orm/pull/1213\n* Disabled default features and enabled only the needed ones https://github.com/SeaQL/sea-orm/pull/1300\n* Cleanup panic and unwrap https://github.com/SeaQL/sea-orm/pull/1231\n* Cleanup the use of `vec!` macro https://github.com/SeaQL/sea-orm/pull/1367\n\n### Bug Fixes\n\n* [sea-orm-cli] Propagate error on the spawned child processes https://github.com/SeaQL/sea-orm/pull/1402\n    * Fixes sea-orm-cli errors exit with error code 0 https://github.com/SeaQL/sea-orm/issues/1342\n* Fixes `DeriveColumn` (by qualifying `IdenStatic::as_str`) https://github.com/SeaQL/sea-orm/pull/1280\n* Prevent returning connections to pool with a positive transaction depth https://github.com/SeaQL/sea-orm/pull/1283\n* Postgres insert many will throw `RecordNotInserted` error if non of them are being inserted https://github.com/SeaQL/sea-orm/pull/1021\n    * Fixes inserting active models by `insert_many` with `on_conflict` and `do_nothing` panics if no rows are inserted on Postgres https://github.com/SeaQL/sea-orm/issues/899\n* Don't call `last_insert_id` if not needed https://github.com/SeaQL/sea-orm/pull/1403\n    * Fixes hitting 'negative last_insert_rowid' panic with Sqlite https://github.com/SeaQL/sea-orm/issues/1357\n* Noop when update without providing any values https://github.com/SeaQL/sea-orm/pull/1384\n    * Fixes Syntax Error when saving active model that sets nothing https://github.com/SeaQL/sea-orm/pull/1376\n\n### Breaking Changes\n\n* [sea-orm-cli] Enable --universal-time by default https://github.com/SeaQL/sea-orm/pull/1420\n* Added `RecordNotInserted` and `RecordNotUpdated` to `DbErr`\n* Added `ConnectionTrait::execute_unprepared` method https://github.com/SeaQL/sea-orm/pull/1327\n* As part of https://github.com/SeaQL/sea-orm/pull/1311, the required method of `TryGetable` changed:\n```rust\n// then\nfn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError>;\n// now; ColIdx can be `&str` or `usize`\nfn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError>;\n```\nSo if you implemented it yourself:\n```patch\nimpl TryGetable for XXX {\n-   fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {\n+   fn try_get_by<I: sea_orm::ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n-       let value: YYY = res.try_get(pre, col).map_err(TryGetError::DbErr)?;\n+       let value: YYY = res.try_get_by(idx).map_err(TryGetError::DbErr)?;\n        ..\n    }\n}\n```\n* The `ActiveModelBehavior` trait becomes async trait https://github.com/SeaQL/sea-orm/pull/1328.\nIf you overridden the default `ActiveModelBehavior` implementation:\n```rust\n#[async_trait::async_trait]\nimpl ActiveModelBehavior for ActiveModel {\n    async fn before_save<C>(self, db: &C, insert: bool) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        // ...\n    }\n\n    // ...\n}\n```\n* `DbErr::RecordNotFound(\"None of the database rows are affected\")` is moved to a dedicated error variant `DbErr::RecordNotUpdated` https://github.com/SeaQL/sea-orm/pull/1425\n```rust\nlet res = Update::one(cake::ActiveModel {\n        name: Set(\"Cheese Cake\".to_owned()),\n        ..model.into_active_model()\n    })\n    .exec(&db)\n    .await;\n\n// then\nassert_eq!(\n    res,\n    Err(DbErr::RecordNotFound(\n        \"None of the database rows are affected\".to_owned()\n    ))\n);\n\n// now\nassert_eq!(res, Err(DbErr::RecordNotUpdated));\n```\n* `sea_orm::ColumnType` was replaced by `sea_query::ColumnType` https://github.com/SeaQL/sea-orm/pull/1395\n    * Method `ColumnType::def` was moved to `ColumnTypeTrait`\n    * `ColumnType::Binary` becomes a tuple variant which takes in additional option `sea_query::BlobSize`\n    * `ColumnType::Custom` takes a `sea_query::DynIden` instead of `String` and thus a new method `custom` is added (note the lowercase)\n```diff\n// Compact Entity\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"fruit\")]\npub struct Model {\n-   #[sea_orm(column_type = r#\"Custom(\"citext\".to_owned())\"#)]\n+   #[sea_orm(column_type = r#\"custom(\"citext\")\"#)]\n    pub column: String,\n}\n```\n```diff\n// Expanded Entity\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n-           Self::Column => ColumnType::Custom(\"citext\".to_owned()).def(),\n+           Self::Column => ColumnType::custom(\"citext\").def(),\n        }\n    }\n}\n```\n\n### Miscellaneous\n\n* Fixed a small typo https://github.com/SeaQL/sea-orm/pull/1391\n* `axum` example should use tokio runtime https://github.com/SeaQL/sea-orm/pull/1428\n\n**Full Changelog**: https://github.com/SeaQL/sea-orm/compare/0.10.0...0.11.0\n\n## 0.10.7 - 2023-01-19\n\n### Bug Fixes\n\n* Inserting active models by `insert_many` with `on_conflict` and `do_nothing` panics if no rows are inserted on Postgres https://github.com/SeaQL/sea-orm/issues/899\n* Hitting 'negative last_insert_rowid' panic with Sqlite https://github.com/SeaQL/sea-orm/issues/1357\n\n## 0.10.6 - 2022-12-23\n\n### Enhancements\n\n* Cast enum values when constructing update many query https://github.com/SeaQL/sea-orm/pull/1178\n\n### Bug Fixes\n\n* Fixes `DeriveColumn` (by qualifying `IdenStatic::as_str`) https://github.com/SeaQL/sea-orm/pull/1280\n* Prevent returning connections to pool with a positive transaction depth https://github.com/SeaQL/sea-orm/pull/1283\n* [sea-orm-codegen] Skip implementing Related if the same related entity is being referenced by a conjunct relation https://github.com/SeaQL/sea-orm/pull/1298\n* [sea-orm-cli] CLI depends on codegen of the same version https://github.com/SeaQL/sea-orm/pull/1299/\n\n## 0.10.5 - 2022-12-02\n\n### New Features\n\n* Add `QuerySelect::columns` method - select multiple columns https://github.com/SeaQL/sea-orm/pull/1264\n* Transactions Isolation level and Access mode https://github.com/SeaQL/sea-orm/pull/1230\n\n### Bug Fixes\n\n* `DeriveEntityModel` derive macro: when parsing field type, always treat field with `Option<T>` as nullable column https://github.com/SeaQL/sea-orm/pull/1257\n\n### Enhancements\n\n* [sea-orm-cli] Generate `Related` implementation for many-to-many relation with extra columns https://github.com/SeaQL/sea-orm/pull/1260\n* Optimize the default implementation of `TryGetableFromJson::try_get_from_json()` - deserializing into `Self` directly without the need of a intermediate `serde_json::Value` https://github.com/SeaQL/sea-orm/pull/1249\n\n## 0.10.4 - 2022-11-24\n\n### Bug Fixes\n\n* Fix DeriveActiveEnum expand enum variant starts with number https://github.com/SeaQL/sea-orm/pull/1219\n* [sea-orm-cli] Generate entity file for specified tables only https://github.com/SeaQL/sea-orm/pull/1245\n* Support appending `DbErr` to `MockDatabase` https://github.com/SeaQL/sea-orm/pull/1241\n\n### Enhancements\n\n* Filter rows with `IS IN` enum values expression https://github.com/SeaQL/sea-orm/pull/1183\n* [sea-orm-cli] Generate entity with relation variant order by name of reference table https://github.com/SeaQL/sea-orm/pull/1229\n\n## 0.10.3 - 2022-11-14\n\n### Bug Fixes\n\n* [sea-orm-cli] Set search path when initializing Postgres connection for CLI generate entity https://github.com/SeaQL/sea-orm/pull/1212\n* [sea-orm-cli] Generate `_` prefix to enum variant starts with number https://github.com/SeaQL/sea-orm/pull/1211\n* Fix composite key cursor pagination https://github.com/SeaQL/sea-orm/pull/1216\n    + The logic for single-column primary key was correct, but for composite keys the logic was incorrect\n\n### Enhancements\n\n* Added `Insert::exec_without_returning` https://github.com/SeaQL/sea-orm/pull/1208\n\n### House Keeping\n\n* Remove dependency when not needed https://github.com/SeaQL/sea-orm/pull/1207\n\n## 0.10.2 - 2022-11-06\n\n### Enhancements\n\n* [sea-orm-rocket] added `sqlx_logging` to `Config` https://github.com/SeaQL/sea-orm/pull/1192\n* Collecting metrics for `query_one/all` https://github.com/SeaQL/sea-orm/pull/1165\n* Use GAT to elide `StreamTrait` lifetime https://github.com/SeaQL/sea-orm/pull/1161\n\n### Bug Fixes\n\n* corrected the error name `UpdateGetPrimaryKey` https://github.com/SeaQL/sea-orm/pull/1180\n\n### Upgrades\n\n* Update MSRV to 1.65\n\n## 0.10.1 - 2022-10-27\n\n### Enhancements\n\n* [sea-orm-cli] Escape module name defined with Rust keywords https://github.com/SeaQL/sea-orm/pull/1052\n* [sea-orm-cli] Check to make sure migration name doesn't contain hyphen `-` in it https://github.com/SeaQL/sea-orm/pull/879, https://github.com/SeaQL/sea-orm/pull/1155\n* Support `time` crate for SQLite https://github.com/SeaQL/sea-orm/pull/995\n\n### Bug Fixes\n\n* [sea-orm-cli] Generate `Related` for m-to-n relation https://github.com/SeaQL/sea-orm/pull/1075\n* [sea-orm-cli] Generate model entity with Postgres Enum field https://github.com/SeaQL/sea-orm/pull/1153\n* [sea-orm-cli] Migrate up command apply all pending migrations https://github.com/SeaQL/sea-orm/pull/1010\n* [sea-orm-cli] Conflicting short flag `-u` when executing `migrate generate` command https://github.com/SeaQL/sea-orm/pull/1157\n* Prefix the usage of types with `sea_orm::` inside `DeriveActiveEnum` derive macros https://github.com/SeaQL/sea-orm/pull/1146, https://github.com/SeaQL/sea-orm/pull/1154\n* [sea-orm-cli] Generate model with `Vec<f32>` or `Vec<f64>` should not derive `Eq` on the model struct https://github.com/SeaQL/sea-orm/pull/1158\n\n### House Keeping\n\n* [sea-orm-cli] [sea-orm-migration] Add `cli` feature to optionally include dependencies that are required by the CLI https://github.com/SeaQL/sea-orm/pull/978\n\n### Upgrades\n\n* Upgrade `sea-schema` to 0.10.2 https://github.com/SeaQL/sea-orm/pull/1153\n\n## 0.10.0 - 2022-10-23\n\n### New Features\n\n* Better error types (carrying SQLx Error) https://github.com/SeaQL/sea-orm/pull/1002\n* Support array datatype in PostgreSQL https://github.com/SeaQL/sea-orm/pull/1132\n* [sea-orm-cli] Generate entity files as a library or module https://github.com/SeaQL/sea-orm/pull/953\n* [sea-orm-cli] Generate a new migration template with name prefix of unix timestamp https://github.com/SeaQL/sea-orm/pull/947\n* [sea-orm-cli] Generate migration in modules https://github.com/SeaQL/sea-orm/pull/933\n* [sea-orm-cli] Generate `DeriveRelation` on empty `Relation` enum https://github.com/SeaQL/sea-orm/pull/1019\n* [sea-orm-cli] Generate entity derive `Eq` if possible https://github.com/SeaQL/sea-orm/pull/988\n* [sea-orm-cli] Run migration on any PostgreSQL schema https://github.com/SeaQL/sea-orm/pull/1056\n\n### Enhancements\n\n* Support `distinct` & `distinct_on` expression https://github.com/SeaQL/sea-orm/pull/902\n* `fn column()` also handle enum type https://github.com/SeaQL/sea-orm/pull/973\n* Added `acquire_timeout` on `ConnectOptions` https://github.com/SeaQL/sea-orm/pull/897\n* [sea-orm-cli] `migrate fresh` command will drop all PostgreSQL types https://github.com/SeaQL/sea-orm/pull/864, https://github.com/SeaQL/sea-orm/pull/991\n* Better compile error for entity without primary key https://github.com/SeaQL/sea-orm/pull/1020\n* Added blanket implementations of `IntoActiveValue` for `Option` values https://github.com/SeaQL/sea-orm/pull/833\n* Added `into_model` & `into_json` to `Cursor` https://github.com/SeaQL/sea-orm/pull/1112\n* Added `set_schema_search_path` method to `ConnectOptions` for setting schema search path of PostgreSQL connection https://github.com/SeaQL/sea-orm/pull/1056\n* Serialize `time` types as `serde_json::Value` https://github.com/SeaQL/sea-orm/pull/1042\n* Implements `fmt::Display` for `ActiveEnum` https://github.com/SeaQL/sea-orm/pull/986\n* Implements `TryFrom<ActiveModel>` for `Model` https://github.com/SeaQL/sea-orm/pull/990\n\n### Bug Fixes\n\n* Trim spaces when paginating raw SQL https://github.com/SeaQL/sea-orm/pull/1094\n\n### Breaking Changes\n\n* Replaced `usize` with `u64` in `PaginatorTrait` https://github.com/SeaQL/sea-orm/pull/789\n* Type signature of `DbErr` changed as a result of https://github.com/SeaQL/sea-orm/pull/1002\n* `ColumnType::Enum` structure changed:\n```rust\nenum ColumnType {\n    // then\n    Enum(String, Vec<String>)\n\n    // now\n    Enum {\n        /// Name of enum\n        name: DynIden,\n        /// Variants of enum\n        variants: Vec<DynIden>,\n    }\n    ...\n}\n\n// example\n\n#[derive(Iden)]\nenum TeaEnum {\n    #[iden = \"tea\"]\n    Enum,\n    #[iden = \"EverydayTea\"]\n    EverydayTea,\n    #[iden = \"BreakfastTea\"]\n    BreakfastTea,\n}\n\n// then\nColumnDef::new(active_enum_child::Column::Tea)\n    .enumeration(\"tea\", vec![\"EverydayTea\", \"BreakfastTea\"])\n\n// now\nColumnDef::new(active_enum_child::Column::Tea)\n    .enumeration(TeaEnum::Enum, [TeaEnum::EverydayTea, TeaEnum::BreakfastTea])\n```\n\n* A new method `array_type` was added to `ValueType`:\n```rust\nimpl sea_orm::sea_query::ValueType for MyType {\n    fn array_type() -> sea_orm::sea_query::ArrayType {\n        sea_orm::sea_query::ArrayType::TypeName\n    }\n    ...\n}\n```\n\n* `ActiveEnum::name()` changed return type to `DynIden`:\n```rust\n#[derive(Debug, Iden)]\n#[iden = \"category\"]\npub struct CategoryEnum;\n\nimpl ActiveEnum for Category {\n    // then\n    fn name() -> String {\n        \"category\".to_owned()\n    }\n\n    // now\n    fn name() -> DynIden {\n        SeaRc::new(CategoryEnum)\n    }\n    ...\n}\n```\n\n### House Keeping\n\n* Documentation grammar fixes https://github.com/SeaQL/sea-orm/pull/1050\n* Replace `dotenv` with `dotenvy` in examples https://github.com/SeaQL/sea-orm/pull/1085\n* Exclude test_cfg module from SeaORM https://github.com/SeaQL/sea-orm/pull/1077\n\n### Integration\n\n* Support `rocket_okapi` https://github.com/SeaQL/sea-orm/pull/1071\n\n### Upgrades\n\n* Upgrade `sea-query` to 0.26 https://github.com/SeaQL/sea-orm/pull/985\n\n**Full Changelog**: https://github.com/SeaQL/sea-orm/compare/0.9.0...0.10.0\n\n## 0.9.3 - 2022-09-30\n\n### Enhancements\n\n* `fn column()` also handle enum type https://github.com/SeaQL/sea-orm/pull/973\n* Generate migration in modules https://github.com/SeaQL/sea-orm/pull/933\n* Generate `DeriveRelation` on empty `Relation` enum https://github.com/SeaQL/sea-orm/pull/1019\n* Documentation grammar fixes https://github.com/SeaQL/sea-orm/pull/1050\n\n### Bug Fixes\n\n* Implement `IntoActiveValue` for `time` types https://github.com/SeaQL/sea-orm/pull/1041\n* Fixed module import for `FromJsonQueryResult` derive macro https://github.com/SeaQL/sea-orm/pull/1081\n\n## 0.9.2 - 2022-08-20\n\n### Enhancements\n\n* [sea-orm-cli] Migrator CLI handles init and generate commands https://github.com/SeaQL/sea-orm/pull/931\n* [sea-orm-cli] added `with-copy-enums` flag to conditional derive `Copy` on `ActiveEnum` https://github.com/SeaQL/sea-orm/pull/936\n\n### House Keeping\n\n* Exclude `chrono` default features https://github.com/SeaQL/sea-orm/pull/950\n* Set minimal rustc version to `1.60` https://github.com/SeaQL/sea-orm/pull/938\n* Update `sea-query` to `0.26.3`\n\n### Notes\n\nIn this minor release, we removed `time` v0.1 from the dependency graph\n\n## 0.9.1 - 2022-07-22\n\n### Enhancements\n\n* [sea-orm-cli] Codegen support for `VarBinary` column type https://github.com/SeaQL/sea-orm/pull/746\n* [sea-orm-cli] Generate entity for SYSTEM VERSIONED tables on MariaDB https://github.com/SeaQL/sea-orm/pull/876\n\n### Bug Fixes\n\n* `RelationDef` & `RelationBuilder` should be `Send` & `Sync` https://github.com/SeaQL/sea-orm/pull/898\n\n### House Keeping\n\n* Remove unnecessary `async_trait` https://github.com/SeaQL/sea-orm/pull/737\n\n## 0.9.0 - 2022-07-17\n\n### New Features\n\n* Cursor pagination https://github.com/SeaQL/sea-orm/pull/822\n* Custom join on conditions https://github.com/SeaQL/sea-orm/pull/793\n* `DeriveMigrationName` and `sea_orm_migration::util::get_file_stem` https://github.com/SeaQL/sea-orm/pull/736\n* `FromJsonQueryResult` for deserializing `Json` from query result https://github.com/SeaQL/sea-orm/pull/794\n\n### Enhancements\n\n* Added `sqlx_logging_level` to `ConnectOptions` https://github.com/SeaQL/sea-orm/pull/800\n* Added `num_items_and_pages` to `Paginator` https://github.com/SeaQL/sea-orm/pull/768\n* Added `TryFromU64` for `time` https://github.com/SeaQL/sea-orm/pull/849\n* Added `Insert::on_conflict` https://github.com/SeaQL/sea-orm/pull/791\n* Added `QuerySelect::join_as` and `QuerySelect::join_as_rev` https://github.com/SeaQL/sea-orm/pull/852\n* Include column name in `TryGetError::Null` https://github.com/SeaQL/sea-orm/pull/853\n* [sea-orm-cli] Improve logging https://github.com/SeaQL/sea-orm/pull/735\n* [sea-orm-cli] Generate enum with numeric like variants https://github.com/SeaQL/sea-orm/pull/588\n* [sea-orm-cli] Allow old pending migration to be applied https://github.com/SeaQL/sea-orm/pull/755\n* [sea-orm-cli] Skip generating entity for ignored tables https://github.com/SeaQL/sea-orm/pull/837\n* [sea-orm-cli] Generate code for `time` crate https://github.com/SeaQL/sea-orm/pull/724\n* [sea-orm-cli] Add various blob column types https://github.com/SeaQL/sea-orm/pull/850\n* [sea-orm-cli] Generate entity files with Postgres's schema name https://github.com/SeaQL/sea-orm/pull/422\n\n### Upgrades\n\n* Upgrade `clap` to 3.2 https://github.com/SeaQL/sea-orm/pull/706\n* Upgrade `time` to 0.3 https://github.com/SeaQL/sea-orm/pull/834\n* Upgrade `sqlx` to 0.6 https://github.com/SeaQL/sea-orm/pull/834\n* Upgrade `uuid` to 1.0 https://github.com/SeaQL/sea-orm/pull/834\n* Upgrade `sea-query` to 0.26 https://github.com/SeaQL/sea-orm/pull/834\n* Upgrade `sea-schema` to 0.9 https://github.com/SeaQL/sea-orm/pull/834\n\n### House Keeping\n\n* Refactor stream metrics https://github.com/SeaQL/sea-orm/pull/778\n\n### Bug Fixes\n\n* [sea-orm-cli] skip checking connection string for credentials https://github.com/SeaQL/sea-orm/pull/851\n\n### Breaking Changes\n\n* `SelectTwoMany::one()` has been dropped https://github.com/SeaQL/sea-orm/pull/813, you can get `(Entity, Vec<RelatedEntity>)` by first querying a single model from Entity, then use [`ModelTrait::find_related`] on the model.\n* #### Feature flag revamp\n    We now adopt the [weak dependency](https://blog.rust-lang.org/2022/04/07/Rust-1.60.0.html#new-syntax-for-cargo-features) syntax in Cargo. That means the flags `[\"sqlx-json\", \"sqlx-chrono\", \"sqlx-decimal\", \"sqlx-uuid\", \"sqlx-time\"]` are not needed and now removed. Instead, `with-time` will enable `sqlx?/time` only if `sqlx` is already enabled. As a consequence, now the features `with-json`, `with-chrono`, `with-rust_decimal`, `with-uuid`, `with-time` will not be enabled as a side-effect of enabling `sqlx`.\n\n**Full Changelog**: https://github.com/SeaQL/sea-orm/compare/0.8.0...0.9.0\n\n## sea-orm-migration 0.8.3\n\n* Removed `async-std` from dependency https://github.com/SeaQL/sea-orm/pull/758\n\n## 0.8.0 - 2022-05-10\n\n### New Features\n* [sea-orm-cli] `sea migrate generate` to generate a new, empty migration file https://github.com/SeaQL/sea-orm/pull/656\n\n### Enhancements\n* Add `max_connections` option to CLI https://github.com/SeaQL/sea-orm/pull/670\n* Derive `Eq`, `Clone` for `DbErr` https://github.com/SeaQL/sea-orm/pull/677\n* Add `is_changed` to `ActiveModelTrait` https://github.com/SeaQL/sea-orm/pull/683\n\n### Bug Fixes\n* Fix `DerivePrimaryKey` with custom primary key column name https://github.com/SeaQL/sea-orm/pull/694\n* Fix `DeriveEntityModel` macros override column name https://github.com/SeaQL/sea-orm/pull/695\n* Fix Insert with no value supplied using `DEFAULT` https://github.com/SeaQL/sea-orm/pull/589\n\n### Breaking Changes\n* Migration utilities are moved from sea-schema to sea-orm repo, under a new sub-crate `sea-orm-migration`. `sea_schema::migration::prelude` should be replaced by `sea_orm_migration::prelude` in all migration files\n\n### Upgrades\n* Upgrade `sea-query` to 0.24.x, `sea-schema` to 0.8.x\n* Upgrade example to Actix Web 4, Actix Web 3 remains https://github.com/SeaQL/sea-orm/pull/638\n* Added Tonic gRPC example https://github.com/SeaQL/sea-orm/pull/659\n* Upgrade GraphQL example to use axum 0.5.x\n* Upgrade axum example to 0.5.x\n\n### Fixed Issues\n* Failed to insert row with only default values https://github.com/SeaQL/sea-orm/issues/420\n* Reduce database connections to 1 during codegen https://github.com/SeaQL/sea-orm/issues/511\n* Column names with single letters separated by underscores are concatenated https://github.com/SeaQL/sea-orm/issues/630\n* Update Actix Web examples https://github.com/SeaQL/sea-orm/issues/639\n* Lower function missing https://github.com/SeaQL/sea-orm/issues/672\n* is_changed on active_model https://github.com/SeaQL/sea-orm/issues/674\n* Failing find_with_related with column_name attribute https://github.com/SeaQL/sea-orm/issues/693\n\n**Full Changelog**: https://github.com/SeaQL/sea-orm/compare/0.7.1...0.8.0\n\n## 0.7.1 - 2022-03-26\n\n* Fix sea-orm-cli error\n* Fix sea-orm cannot build without `with-json`\n\n## 0.7.0 - 2022-03-26\n\n### New Features\n* Update ActiveModel by JSON by @billy1624 in https://github.com/SeaQL/sea-orm/pull/492\n* Supports `time` crate by @billy1624 https://github.com/SeaQL/sea-orm/pull/602\n* Allow for creation of indexes for PostgreSQL and SQLite @nickb937 https://github.com/SeaQL/sea-orm/pull/593\n* Added `delete_by_id` @ShouvikGhosh2048 https://github.com/SeaQL/sea-orm/pull/590\n* Implement `PaginatorTrait` for `SelectorRaw` @shinbunbun https://github.com/SeaQL/sea-orm/pull/617\n\n### Enhancements\n* Added axum graphql example by @aaronleopold in https://github.com/SeaQL/sea-orm/pull/587\n* Add example for integrate with jsonrpsee by @hunjixin https://github.com/SeaQL/sea-orm/pull/632\n* Codegen add serde derives to enums, if specified by @BenJeau https://github.com/SeaQL/sea-orm/pull/463\n* Codegen Unsigned Integer by @billy1624 https://github.com/SeaQL/sea-orm/pull/397\n* Add `Send` bound to `QueryStream` and `TransactionStream` by @sebpuetz https://github.com/SeaQL/sea-orm/pull/471\n* Add `Send` to `StreamTrait` by @nappa85 https://github.com/SeaQL/sea-orm/pull/622\n* `sea` as an alternative bin name to `sea-orm-cli` by @ZhangHanDong https://github.com/SeaQL/sea-orm/pull/558\n\n### Bug Fixes\n* Fix codegen with Enum in expanded format by @billy1624 https://github.com/SeaQL/sea-orm/pull/624\n* Fixing and testing into_json of various field types by @billy1624 https://github.com/SeaQL/sea-orm/pull/539\n\n### Breaking Changes\n* Exclude `mock` from default features by @billy1624 https://github.com/SeaQL/sea-orm/pull/562\n* `create_table_from_entity` will no longer create index for MySQL, please use the new method `create_index_from_entity`\n\n### Documentations\n* Describe default value of ActiveValue on document by @Ken-Miura in https://github.com/SeaQL/sea-orm/pull/556\n* community: add axum-book-management by @lz1998 in https://github.com/SeaQL/sea-orm/pull/564\n* Add Backpack to project showcase by @JSH32 in https://github.com/SeaQL/sea-orm/pull/567\n* Add mediarepo to showcase by @Trivernis in https://github.com/SeaQL/sea-orm/pull/569\n* COMMUNITY: add a link to Svix to showcase by @tasn in https://github.com/SeaQL/sea-orm/pull/537\n* Update COMMUNITY.md by @naryand in https://github.com/SeaQL/sea-orm/pull/570\n* Update COMMUNITY.md by @BobAnkh in https://github.com/SeaQL/sea-orm/pull/568\n* Update COMMUNITY.md by @KaniyaSimeji in https://github.com/SeaQL/sea-orm/pull/566\n* Update COMMUNITY.md by @aaronleopold in https://github.com/SeaQL/sea-orm/pull/565\n* Update COMMUNITY.md by @gudaoxuri in https://github.com/SeaQL/sea-orm/pull/572\n* Update Wikijump's entry in COMMUNITY.md by @ammongit in https://github.com/SeaQL/sea-orm/pull/573\n* Update COMMUNITY.md by @koopa1338 in https://github.com/SeaQL/sea-orm/pull/574\n* Update COMMUNITY.md by @gengteng in https://github.com/SeaQL/sea-orm/pull/580\n* Update COMMUNITY.md by @Yama-Tomo in https://github.com/SeaQL/sea-orm/pull/582\n* add oura-postgres-sink to COMMUNITY.md by @rvcas in https://github.com/SeaQL/sea-orm/pull/594\n* Add rust-example-caster-api to COMMUNITY.md by @bkonkle in https://github.com/SeaQL/sea-orm/pull/623\n\n### Fixed Issues\n* orm-cli generated incorrect type for #[sea_orm(primary_key)]. Should be u64. Was i64. https://github.com/SeaQL/sea-orm/issues/295\n* how to update dynamically from json value https://github.com/SeaQL/sea-orm/issues/346\n* Make `DatabaseConnection` `Clone` with the default features enabled https://github.com/SeaQL/sea-orm/issues/438\n* Updating multiple fields in a Model by passing a reference https://github.com/SeaQL/sea-orm/issues/460\n* SeaORM CLI not adding serde derives to Enums https://github.com/SeaQL/sea-orm/issues/461\n* sea-orm-cli generates wrong data type for nullable blob https://github.com/SeaQL/sea-orm/issues/490\n* Support the time crate in addition (instead of?) chrono https://github.com/SeaQL/sea-orm/issues/499\n* PaginatorTrait for SelectorRaw https://github.com/SeaQL/sea-orm/issues/500\n* sea_orm::DatabaseConnection should implement `Clone` by default https://github.com/SeaQL/sea-orm/issues/517\n* How do you seed data in migrations using ActiveModels? https://github.com/SeaQL/sea-orm/issues/522\n* Datetime fields are not serialized by `.into_json()` on queries https://github.com/SeaQL/sea-orm/issues/530\n* Update / Delete by id https://github.com/SeaQL/sea-orm/issues/552\n* `#[sea_orm(indexed)]` only works for MySQL https://github.com/SeaQL/sea-orm/issues/554\n* `sea-orm-cli generate --with-serde` does not work on Postgresql custom type https://github.com/SeaQL/sea-orm/issues/581\n* `sea-orm-cli generate --expanded-format` panic when postgres table contains enum type https://github.com/SeaQL/sea-orm/issues/614\n* UUID fields are not serialized by `.into_json()` on queries https://github.com/SeaQL/sea-orm/issues/619\n\n**Full Changelog**: https://github.com/SeaQL/sea-orm/compare/0.6.0...0.7.0\n\n## 0.6.0 - 2022-02-07\n\n### New Features\n* Migration Support by @billy1624 in https://github.com/SeaQL/sea-orm/pull/335\n* Support `DateTime<Utc>` & `DateTime<Local>` by @billy1624 in https://github.com/SeaQL/sea-orm/pull/489\n* Add `max_lifetime` connection option by @billy1624 in https://github.com/SeaQL/sea-orm/pull/493\n\n### Enhancements\n* Model with Generics by @billy1624 in https://github.com/SeaQL/sea-orm/pull/400\n* Add Poem example by @sunli829 in https://github.com/SeaQL/sea-orm/pull/446\n* Codegen `column_name` proc_macro attribute by @billy1624 in https://github.com/SeaQL/sea-orm/pull/433\n* Easy joins with MockDatabase #447 by @cemoktra in https://github.com/SeaQL/sea-orm/pull/455\n\n### Bug Fixes\n* CLI allow generate entity with url without password by @billy1624 in https://github.com/SeaQL/sea-orm/pull/436\n* Support up to 6-ary composite primary key by @billy1624 in https://github.com/SeaQL/sea-orm/pull/423\n* Fix FromQueryResult when Result is redefined by @tasn in https://github.com/SeaQL/sea-orm/pull/495\n* Remove `r#` prefix when deriving `FromQueryResult` by @smrtrfszm in https://github.com/SeaQL/sea-orm/pull/494\n\n### Breaking Changes\n* Name conflict of foreign key constraints when two entities have more than one foreign keys by @billy1624 in https://github.com/SeaQL/sea-orm/pull/417\n\n### Fixed Issues\n* Is it possible to have 4 values Composite Key? https://github.com/SeaQL/sea-orm/issues/352\n* Support `DateTime<Utc>` & `DateTime<Local>` https://github.com/SeaQL/sea-orm/issues/381\n* Codegen `column_name` proc_macro attribute if column name isn't in snake case https://github.com/SeaQL/sea-orm/issues/395\n* Model with Generics https://github.com/SeaQL/sea-orm/issues/402\n* Foreign key constraint collision when multiple keys exist between the same two tables https://github.com/SeaQL/sea-orm/issues/405\n* sea-orm-cli passwordless database user causes \"No password was found in the database url\" error https://github.com/SeaQL/sea-orm/issues/435\n* Testing joins with MockDatabase https://github.com/SeaQL/sea-orm/issues/447\n* Surface max_lifetime connection option https://github.com/SeaQL/sea-orm/issues/475\n\n**Full Changelog**: https://github.com/SeaQL/sea-orm/compare/0.5.0...0.6.0\n\n## 0.5.0 - 2022-01-01\n\n### Fixed Issues\n* Why insert, update, etc return an ActiveModel instead of Model? https://github.com/SeaQL/sea-orm/issues/289\n* Rework `ActiveValue` https://github.com/SeaQL/sea-orm/issues/321\n* Some missing ActiveEnum utilities https://github.com/SeaQL/sea-orm/issues/338\n\n### Merged PRs\n* First metric and tracing implementation by @nappa85 in https://github.com/SeaQL/sea-orm/pull/373\n* Update sea-orm to depends on SeaQL/sea-query#202 by @billy1624 in https://github.com/SeaQL/sea-orm/pull/370\n* Codegen ActiveEnum & Create Enum From ActiveEnum by @billy1624 in https://github.com/SeaQL/sea-orm/pull/348\n* Axum example: update to Axum v0.4.2 by @ttys3 in https://github.com/SeaQL/sea-orm/pull/383\n* Fix rocket version by @Gabriel-Paulucci in https://github.com/SeaQL/sea-orm/pull/384\n* Insert & Update Return `Model` by @billy1624 in https://github.com/SeaQL/sea-orm/pull/339\n* Rework `ActiveValue` by @billy1624 in https://github.com/SeaQL/sea-orm/pull/340\n* Add wrapper method `ModelTrait::delete` by @billy1624 in https://github.com/SeaQL/sea-orm/pull/396\n* Add docker create script for contributors to setup databases locally by @billy1624 in https://github.com/SeaQL/sea-orm/pull/378\n* Log with tracing-subscriber by @billy1624 in https://github.com/SeaQL/sea-orm/pull/399\n* Codegen SQLite by @billy1624 in https://github.com/SeaQL/sea-orm/pull/386\n* PR without clippy warnings in file changed tab by @billy1624 in https://github.com/SeaQL/sea-orm/pull/401\n* Rename `sea-strum` lib back to `strum` by @billy1624 in https://github.com/SeaQL/sea-orm/pull/361\n\n### Breaking Changes\n* `ActiveModel::insert` and `ActiveModel::update` return `Model` instead of `ActiveModel`\n* Method `ActiveModelBehavior::after_save` takes `Model` as input instead of `ActiveModel`\n* Rename method `sea_orm::unchanged_active_value_not_intended_for_public_use` to `sea_orm::Unchanged`\n* Rename method `ActiveValue::unset` to `ActiveValue::not_set`\n* Rename method `ActiveValue::is_unset` to `ActiveValue::is_not_set`\n* `PartialEq` of `ActiveValue` will also check the equality of state instead of just checking the equality of value\n\n**Full Changelog**: https://github.com/SeaQL/sea-orm/compare/0.4.2...0.5.0\n\n## 0.4.2 - 2021-12-12\n\n### Fixed Issues\n* Delete::many() doesn't work when schema_name is defined https://github.com/SeaQL/sea-orm/issues/362\n* find_with_related panic https://github.com/SeaQL/sea-orm/issues/374\n* How to define the rust type of TIMESTAMP? https://github.com/SeaQL/sea-orm/issues/344\n* Add Table on the generated Column enum https://github.com/SeaQL/sea-orm/issues/356\n\n### Merged PRs\n* `Delete::many()` with `TableRef` by @billy1624 in https://github.com/SeaQL/sea-orm/pull/363\n* Fix related & linked with enum columns by @billy1624 in https://github.com/SeaQL/sea-orm/pull/376\n* Temporary Fix: Handling MySQL & SQLite timestamp columns by @billy1624 in https://github.com/SeaQL/sea-orm/pull/379\n* Add feature to generate table Iden by @Sytten in https://github.com/SeaQL/sea-orm/pull/360\n\n## 0.4.1 - 2021-12-05\n\n### Fixed Issues\n* Is it possible to have 4 values Composite Key? https://github.com/SeaQL/sea-orm/issues/352\n* [sea-orm-cli] Better handling of relation generations https://github.com/SeaQL/sea-orm/issues/239\n\n### Merged PRs\n* Add TryFromU64 trait for `DateTime<FixedOffset>`. by @kev0960 in https://github.com/SeaQL/sea-orm/pull/331\n* add offset and limit by @lz1998 in https://github.com/SeaQL/sea-orm/pull/351\n* For some reason the `axum_example` fail to compile by @billy1624 in https://github.com/SeaQL/sea-orm/pull/355\n* Support Up to 6 Values Composite Primary Key by @billy1624 in https://github.com/SeaQL/sea-orm/pull/353\n* Codegen Handle Self Referencing & Multiple Relations to the Same Related Entity by @billy1624 in https://github.com/SeaQL/sea-orm/pull/347\n\n## 0.4.0 - 2021-11-19\n\n### Fixed Issues\n* Disable SQLx query logging https://github.com/SeaQL/sea-orm/issues/290\n* Code generated by `sea-orm-cli` cannot pass clippy https://github.com/SeaQL/sea-orm/issues/296\n* Should return detailed error message for connection failure https://github.com/SeaQL/sea-orm/issues/310\n* `DateTimeWithTimeZone` does not implement `Serialize` and `Deserialize` https://github.com/SeaQL/sea-orm/issues/319\n* Support returning clause to avoid database hits https://github.com/SeaQL/sea-orm/issues/183\n\n### Merged PRs\n* chore: update to Rust 2021 Edition by @sno2 in https://github.com/SeaQL/sea-orm/pull/273\n* Enumeration - 3 by @billy1624 in https://github.com/SeaQL/sea-orm/pull/274\n* Enumeration - 2 by @billy1624 in https://github.com/SeaQL/sea-orm/pull/261\n* Codegen fix clippy warnings by @billy1624 in https://github.com/SeaQL/sea-orm/pull/303\n* Add axum example by @YoshieraHuang in https://github.com/SeaQL/sea-orm/pull/297\n* Enumeration by @billy1624 in https://github.com/SeaQL/sea-orm/pull/258\n* Add `PaginatorTrait` and `CountTrait` for more constraints by @YoshieraHuang in https://github.com/SeaQL/sea-orm/pull/306\n* Continue `PaginatorTrait` by @billy1624 in https://github.com/SeaQL/sea-orm/pull/307\n* Refactor `Schema` by @billy1624 in https://github.com/SeaQL/sea-orm/pull/309\n* Detailed connection errors by @billy1624 in https://github.com/SeaQL/sea-orm/pull/312\n* Suppress `ouroboros` missing docs warnings by @billy1624 in https://github.com/SeaQL/sea-orm/pull/288\n* `with-json` feature requires `chrono/serde` by @billy1624 in https://github.com/SeaQL/sea-orm/pull/320\n* Pass the argument `entity.table_ref()` instead of just `entity`. by @josh-codes in https://github.com/SeaQL/sea-orm/pull/318\n* Unknown types could be a newtypes instead of `ActiveEnum` by @billy1624 in https://github.com/SeaQL/sea-orm/pull/324\n* Returning by @billy1624 in https://github.com/SeaQL/sea-orm/pull/292\n\n### Breaking Changes\n* Refactor `paginate()` & `count()` utilities into `PaginatorTrait`. You can use the paginator as usual but you might need to import `PaginatorTrait` manually when upgrading from the previous version.\n    ```rust\n    use futures::TryStreamExt;\n    use sea_orm::{entity::*, query::*, tests_cfg::cake};\n\n    let mut cake_stream = cake::Entity::find()\n        .order_by_asc(cake::Column::Id)\n        .paginate(db, 50)\n        .into_stream();\n\n    while let Some(cakes) = cake_stream.try_next().await? {\n        // Do something on cakes: Vec<cake::Model>\n    }\n    ```\n* The helper struct `Schema` converting `EntityTrait` into different `sea-query` statements now has to be initialized with `DbBackend`.\n    ```rust\n    use sea_orm::{tests_cfg::*, DbBackend, Schema};\n    use sea_orm::sea_query::TableCreateStatement;\n\n    // 0.3.x\n    let _: TableCreateStatement = Schema::create_table_from_entity(cake::Entity);\n\n    // 0.4.x\n    let schema: Schema = Schema::new(DbBackend::MySql);\n    let _: TableCreateStatement = schema.create_table_from_entity(cake::Entity);\n    ```\n* When performing insert or update operation on `ActiveModel` against PostgreSQL, `RETURNING` clause will be used to perform select in a single SQL statement.\n    ```rust\n    // For PostgreSQL\n    cake::ActiveModel {\n        name: Set(\"Apple Pie\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&postgres_db)\n    .await?;\n\n    assert_eq!(\n        postgres_db.into_transaction_log(),\n        vec![Transaction::from_sql_and_values(\n            DbBackend::Postgres,\n            r#\"INSERT INTO \"cake\" (\"name\") VALUES ($1) RETURNING \"id\", \"name\"\"#,\n            vec![\"Apple Pie\".into()]\n        )]);\n    ```\n    ```rust\n    // For MySQL & SQLite\n    cake::ActiveModel {\n        name: Set(\"Apple Pie\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&other_db)\n    .await?;\n\n    assert_eq!(\n        other_db.into_transaction_log(),\n        vec![\n            Transaction::from_sql_and_values(\n                DbBackend::MySql,\n                r#\"INSERT INTO `cake` (`name`) VALUES (?)\"#,\n                vec![\"Apple Pie\".into()]\n            ),\n            Transaction::from_sql_and_values(\n                DbBackend::MySql,\n                r#\"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = ? LIMIT ?\"#,\n                vec![15.into(), 1u64.into()]\n            )]);\n    ```\n\n**Full Changelog**: https://github.com/SeaQL/sea-orm/compare/0.3.2...0.4.0\n\n## 0.3.2 - 2021-11-03\n\n### Fixed Issues\n* Support for BYTEA Postgres primary keys https://github.com/SeaQL/sea-orm/issues/286\n\n### Merged PRs\n* Documentation for sea-orm by @charleschege in https://github.com/SeaQL/sea-orm/pull/280\n* Support `Vec<u8>` primary key by @billy1624 in https://github.com/SeaQL/sea-orm/pull/287\n\n## 0.3.1 - 2021-10-23\n\n(We are changing our Changelog format from now on)\n\n### Fixed Issues\n* Align case transforms across derive macros https://github.com/SeaQL/sea-orm/issues/262\n* Added `is_null` and `is_not_null` to `ColumnTrait` https://github.com/SeaQL/sea-orm/issues/267\n\n(The following is generated by GitHub)\n\n### Merged PRs\n* Changed manual url parsing to use Url crate by @AngelOnFira in https://github.com/SeaQL/sea-orm/pull/253\n* Test self referencing relation by @billy1624 in https://github.com/SeaQL/sea-orm/pull/256\n* Unify case-transform using the same crate by @billy1624 in https://github.com/SeaQL/sea-orm/pull/264\n* CI cleaning by @AngelOnFira in https://github.com/SeaQL/sea-orm/pull/263\n* CI install sea-orm-cli in debug mode by @billy1624 in https://github.com/SeaQL/sea-orm/pull/265\n\n## 0.3.0 - 2021-10-15\n\nhttps://www.sea-ql.org/SeaORM/blog/2021-10-15-whats-new-in-0.3.0\n\n- Built-in Rocket support\n- `ConnectOptions`\n\n```rust\nlet mut opt = ConnectOptions::new(\"protocol://username:password@host/database\".to_owned());\nopt.max_connections(100)\n    .min_connections(5)\n    .connect_timeout(Duration::from_secs(8))\n    .idle_timeout(Duration::from_secs(8));\nlet db = Database::connect(opt).await?;\n```\n\n- [[#211]] Throw error if none of the db rows are affected\n\n```rust\nassert_eq!(\n    Update::one(cake::ActiveModel {\n        name: Set(\"Cheese Cake\".to_owned()),\n        ..model.into_active_model()\n    })\n    .exec(&db)\n    .await,\n    Err(DbErr::RecordNotFound(\n        \"None of the database rows are affected\".to_owned()\n    ))\n);\n\n// update many remains the same\nassert_eq!(\n    Update::many(cake::Entity)\n        .col_expr(cake::Column::Name, Expr::value(\"Cheese Cake\".to_owned()))\n        .filter(cake::Column::Id.eq(2))\n        .exec(&db)\n        .await,\n    Ok(UpdateResult { rows_affected: 0 })\n);\n```\n\n- [[#223]] `ActiveValue::take()` & `ActiveValue::into_value()` without `unwrap()`\n- [[#205]] Drop `Default` trait bound of `PrimaryKeyTrait::ValueType`\n- [[#222]] Transaction & streaming\n- [[#210]] Update `ActiveModelBehavior` API\n- [[#240]] Add derive `DeriveIntoActiveModel` and `IntoActiveValue` trait\n- [[#237]] Introduce optional serde support for model code generation\n- [[#246]] Add `#[automatically_derived]` to all derived implementations\n\n[#211]: https://github.com/SeaQL/sea-orm/pull/211\n[#223]: https://github.com/SeaQL/sea-orm/pull/223\n[#205]: https://github.com/SeaQL/sea-orm/pull/205\n[#222]: https://github.com/SeaQL/sea-orm/pull/222\n[#210]: https://github.com/SeaQL/sea-orm/pull/210\n[#240]: https://github.com/SeaQL/sea-orm/pull/240\n[#237]: https://github.com/SeaQL/sea-orm/pull/237\n[#246]: https://github.com/SeaQL/sea-orm/pull/246\n\n**Full Changelog**: https://github.com/SeaQL/sea-orm/compare/0.2.6...0.3.0\n\n## 0.2.6 - 2021-10-09\n\n- [[#224]] [sea-orm-cli] Date & Time column type mapping\n- Escape rust keywords with `r#` raw identifier\n\n[#224]: https://github.com/SeaQL/sea-orm/pull/224\n\n## 0.2.5 - 2021-10-06\n\n- [[#227]] Resolve \"Inserting actual none value of Option<Date> results in panic\"\n- [[#219]] [sea-orm-cli] Add `--tables` option\n- [[#189]] Add `debug_query` and `debug_query_stmt` macro\n\n[#227]: https://github.com/SeaQL/sea-orm/issues/227\n[#219]: https://github.com/SeaQL/sea-orm/pull/219\n[#189]: https://github.com/SeaQL/sea-orm/pull/189\n\n## 0.2.4 - 2021-10-01\n\nhttps://www.sea-ql.org/SeaORM/blog/2021-10-01-whats-new-in-0.2.4\n\n- [[#186]] [sea-orm-cli] Foreign key handling\n- [[#191]] [sea-orm-cli] Unique key handling\n- [[#182]] `find_linked` join with alias\n- [[#202]] Accept both `postgres://` and `postgresql://`\n- [[#208]] Support fetching T, (T, U), (T, U, P) etc\n- [[#209]] Rename column name & column enum variant\n- [[#207]] Support `chrono::NaiveDate` & `chrono::NaiveTime`\n- Support `Condition::not` (from sea-query)\n\n[#186]: https://github.com/SeaQL/sea-orm/issues/186\n[#191]: https://github.com/SeaQL/sea-orm/issues/191\n[#182]: https://github.com/SeaQL/sea-orm/pull/182\n[#202]: https://github.com/SeaQL/sea-orm/pull/202\n[#208]: https://github.com/SeaQL/sea-orm/pull/208\n[#209]: https://github.com/SeaQL/sea-orm/pull/209\n[#207]: https://github.com/SeaQL/sea-orm/pull/207\n\n## 0.2.3 - 2021-09-22\n\n- [[#152]] DatabaseConnection impl `Clone`\n- [[#175]] Impl `TryGetableMany` for different types of generics\n- Codegen `TimestampWithTimeZone` fixup\n\n[#152]: https://github.com/SeaQL/sea-orm/issues/152\n[#175]: https://github.com/SeaQL/sea-orm/issues/175\n\n## 0.2.2 - 2021-09-18\n\n- [[#105]] Compact entity format\n- [[#132]] Add ActiveModel `insert` & `update`\n- [[#129]] Add `set` method to `UpdateMany`\n- [[#118]] Initial lock support\n- [[#167]] Add `FromQueryResult::find_by_statement`\n\n[#105]: https://github.com/SeaQL/sea-orm/issues/105\n[#132]: https://github.com/SeaQL/sea-orm/issues/132\n[#129]: https://github.com/SeaQL/sea-orm/issues/129\n[#118]: https://github.com/SeaQL/sea-orm/issues/118\n[#167]: https://github.com/SeaQL/sea-orm/issues/167\n\n## 0.2.1 - 2021-09-04\n\n- Update dependencies\n\n## 0.2.0 - 2021-09-03\n\n- [[#37]] Rocket example\n- [[#114]] `log` crate and `env-logger`\n- [[#103]] `InsertResult` to return the primary key's type\n- [[#89]] Represent several relations between same types by `Linked`\n- [[#59]] Transforming an Entity into `TableCreateStatement`\n\n[#37]: https://github.com/SeaQL/sea-orm/issues/37\n[#114]: https://github.com/SeaQL/sea-orm/issues/114\n[#103]: https://github.com/SeaQL/sea-orm/issues/103\n[#89]: https://github.com/SeaQL/sea-orm/issues/89\n[#59]: https://github.com/SeaQL/sea-orm/issues/59\n\n**Full Changelog**: https://github.com/SeaQL/sea-orm/compare/0.1.3...0.2.0\n\n## 0.1.3 - 2021-08-30\n\n- [[#108]] Remove impl TryGetable for Option<T>\n\n[#108]: https://github.com/SeaQL/sea-orm/issues/108\n\n## 0.1.2 - 2021-08-23\n\n- [[#68]] Added `DateTimeWithTimeZone` as supported attribute type\n- [[#70]] Generate arbitrary named entity\n- [[#80]] Custom column name\n- [[#81]] Support join on multiple columns\n- [[#99]] Implement FromStr for ColumnTrait\n\n[#68]: https://github.com/SeaQL/sea-orm/issues/68\n[#70]: https://github.com/SeaQL/sea-orm/issues/70\n[#80]: https://github.com/SeaQL/sea-orm/issues/80\n[#81]: https://github.com/SeaQL/sea-orm/issues/81\n[#99]: https://github.com/SeaQL/sea-orm/issues/99\n\n## 0.1.1 - 2021-08-08\n\n- Early release of SeaORM\n"
  },
  {
    "path": "CLAUDE.md",
    "content": "# SeaORM Project Guidelines\n\nThis project uses **SeaORM 2.0**. AI models likely have SeaORM 1.0 in their training data -- some patterns have changed. Always follow the 2.0 patterns shown below.\n\n## Quick Reference Links\n\n- [Walk-through of SeaORM 2.0](https://www.sea-ql.org/blog/2025-12-05-sea-orm-2.0/)\n- [Migration Guide (1.0 to 2.0)](https://www.sea-ql.org/blog/2026-01-12-sea-orm-2.0/)\n- [New Entity Format](https://www.sea-ql.org/blog/2025-10-20-sea-orm-2.0/)\n- [Strongly-Typed Column](https://www.sea-ql.org/blog/2025-11-11-sea-orm-2.0/)\n- [Nested ActiveModel](https://www.sea-ql.org/blog/2025-11-25-sea-orm-2.0/)\n- [Entity First Workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/)\n\n## Entity Definition (2.0 Format)\n\nIn SeaORM 2.0, entities use `#[sea_orm::model]` with relations defined directly on the `Model` struct. This replaces the 1.0 pattern of separate `Relation` enums and `Related` trait impls.\n\n```rust\nmod user {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"user\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n        #[sea_orm(unique)]\n        pub email: String,\n        #[sea_orm(has_one)]\n        pub profile: HasOne<super::profile::Entity>,\n        #[sea_orm(has_many)]\n        pub posts: HasMany<super::post::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n```\n\n### Relation Attributes\n\n```rust\n// Has-One\n#[sea_orm(has_one)]\npub profile: HasOne<super::profile::Entity>,\n\n// Has-Many\n#[sea_orm(has_many)]\npub posts: HasMany<super::post::Entity>,\n\n// Belongs-To (explicit foreign key mapping)\n#[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\npub user: HasOne<super::user::Entity>,\n\n// Many-to-Many via junction table\n#[sea_orm(has_many, via = \"post_tag\")]\npub tags: HasMany<super::tag::Entity>,\n\n// Self-referential\n#[sea_orm(self_ref, via = \"user_follower\", from = \"User\", to = \"Follower\")]\npub followers: HasMany<Entity>,\n```\n\n### Junction Table (Composite Primary Key)\n\n```rust\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n#[sea_orm(table_name = \"post_tag\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub post_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub tag_id: i32,\n    #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n    pub post: Option<super::post::Entity>,\n    #[sea_orm(belongs_to, from = \"tag_id\", to = \"id\")]\n    pub tag: Option<super::tag::Entity>,\n}\n```\n\n## Strongly-Typed Columns (2.0)\n\nUse `COLUMN` constant with typed fields instead of the untyped `Column` enum:\n\n```rust\n// 2.0 (preferred) -- compile-time type safety\nuser::Entity::find().filter(user::COLUMN.name.contains(\"Bob\"))\n\n// 1.0 (outdated) -- still works but prefer COLUMN\nuser::Entity::find().filter(user::Column::Name.contains(\"Bob\"))\n```\n\n## ActiveModel Builder Pattern (2.0)\n\n```rust\n// Create with nested relations\nlet bob = user::ActiveModel::builder()\n    .set_name(\"Bob\")\n    .set_email(\"bob@sea-ql.org\")\n    .set_profile(profile::ActiveModel::builder().set_picture(\"Tennis\"))\n    .insert(db)\n    .await?;\n\n// Add has-many children\nlet mut bob = bob.into_active_model();\nbob.posts.push(\n    post::ActiveModel::builder().set_title(\"My first post\")\n);\nbob.save(db).await?;\n\n// Many-to-many\nlet post = post::ActiveModel::builder()\n    .set_title(\"A sunny day\")\n    .set_user_id(bob.id)\n    .add_tag(existing_tag)\n    .add_tag(tag::ActiveModel::builder().set_tag(\"outdoor\"))\n    .save(db)\n    .await?;\n```\n\n## Entity Loader API (2.0)\n\n```rust\n// Load with relations in a single query\nlet bob = user::Entity::load()\n    .filter_by_email(\"bob@sea-ql.org\")\n    .with(profile::Entity)\n    .with(post::Entity)\n    .one(db)\n    .await?\n    .expect(\"Not found\");\n\n// Nested relations (post -> comments)\nlet user = user::Entity::load()\n    .filter_by_id(12)\n    .with(profile::Entity)\n    .with((post::Entity, comment::Entity))\n    .one(db)\n    .await?;\n```\n\n## Schema Registry (Entity-First Workflow)\n\n```rust\n// Auto-create tables from entity definitions (dev/testing)\ndb.get_schema_registry(\"my_crate::*\")\n    .sync(db)\n    .await?;\n```\n\n## Anti-Patterns -- DO NOT DO THESE\n\n### 1. Do not specify `column_type` on custom wrapper types\n\nWhen using `DeriveValueType` for custom types, the column type is inferred automatically from the inner type. Adding `column_type` is redundant and incorrect:\n\n```rust\n// WRONG -- do not annotate column_type on custom types\n#[sea_orm(column_type = \"Decimal(Some((10, 4)))\")]\npub speed: Speed,\n\n// CORRECT -- SeaORM infers the column type from the DeriveValueType inner type\npub speed: Speed,\n\n#[derive(Clone, Debug, PartialEq, DeriveValueType)]\npub struct Speed(Decimal);\n```\n\n### 2. Use `Text` or explicit max length for long strings on MySQL/MSSQL\n\nOn MySQL and MSSQL, `String` maps to `VARCHAR(255)` by default. For strings that may exceed 255 characters, use `Text` or specify `StringLen::Max`:\n\n```rust\n// WRONG on MySQL/MSSQL -- silently truncates at 255 chars\npub description: String,\n\n// CORRECT -- use column_type for longer strings\n#[sea_orm(column_type = \"Text\")]\npub description: String,\n\n// Also correct -- explicit max length\n#[sea_orm(column_type = \"String(StringLen::Max)\")]\npub event_type: String,\n```\n\nNote: Postgre / SQLite uses unbounded string by default, so this is primarily a MySQL/MSSQL concern.\n\n### 3. Missing `ExprTrait` import\n\nMethods like `.eq()`, `.like()`, `.contains()` on `Expr` require the trait import in 2.0:\n\n```rust\nuse sea_orm::ExprTrait; // required in 2.0\n\nExpr::col((self.entity_name(), *self)).like(s)\n```\n\n### 4. Do not use removed or renamed APIs\n\n| 1.0 (removed/renamed) | 2.0 (correct) |\n|---|---|\n| `.into_condition()` | `.into()` |\n| `db.execute(Statement::from_sql_and_values(..))` | `db.execute_raw(Statement::from_sql_and_values(..))` |\n| `db.query_all(backend.build(&query))` | `db.query_all(&query)` |\n| `Alias::new(\"col\")` for static strings | `Expr::col(\"col\")` directly |\n| `insert_many(..).on_empty_do_nothing()` | `insert_many([])` returns `None` safely |\n\n### 5. Do not manually impl traits that `DeriveValueType` now generates\n\nIn 2.0, `DeriveValueType` auto-generates `NotU8`, `IntoActiveValue`, and `TryFromU64`. Remove manual implementations to avoid conflicts.\n\n### 6. PostgreSQL: `serial` is no longer the default\n\nAuto-increment columns now use `GENERATED BY DEFAULT AS IDENTITY`. If you need legacy `serial` behavior, use feature flag `option-postgres-use-serial` or `.custom(\"serial\")`.\n\n### 7. SQLite: integer type mapping changed\n\nBoth `Integer` and `BigInteger` map to `integer` in 2.0. The entity generator produces `i64` by default. Override with `sea-orm-cli --big-integer-type=i32` if needed.\n"
  },
  {
    "path": "COMMUNITY.md",
    "content": "# Community\n\n## Built with SeaORM\n\nIf you have built an app using SeaORM and want to showcase it, feel free to open a PR and add it to the list below!\n\n### Startups\n\n- [Caido](https://caido.io/) | A lightweight web security auditing toolkit\n- [FirstLook.gg](https://firstlook.gg/) | A platform to onboard, understand, and reward players | DB: Postgres\n- [Lapdev](https://lap.dev/) [![GitHub stars](https://img.shields.io/github/stars/lapce/lapdev.svg?style=social)](https://github.com/lapce/lapdev) | Self-hosted remote development enviroment | DB: Postgres\n- [OpenObserve](https://openobserve.ai/) [![GitHub stars](https://img.shields.io/github/stars/openobserve/openobserve.svg?style=social)](https://github.com/openobserve/openobserve) | Open-source observability platform | DB: MySQL, Postgres, SQLite\n- [My Data My Consent](https://mydatamyconsent.com/) | Online data sharing for people and businesses simplified\n- [Prefix.dev](https://prefix.dev/) | Conda Package Search, Environment Management and Deployment built for mamba  | DB: Postgres, SQLite\n- [RisingWave](https://risingwave.com/) [![GitHub stars](https://img.shields.io/github/stars/risingwavelabs/risingwave.svg?style=social)](https://github.com/risingwavelabs/risingwave) | Stream processing and management platform | DB: MySQL, Postgres, SQLite\n- [Svix](https://www.svix.com/) [![GitHub stars](https://img.shields.io/github/stars/svix/svix-webhooks.svg?style=social)](https://github.com/svix/svix-webhooks) | The enterprise ready webhooks service | DB: Postgres\n- [System Initiative](https://www.systeminit.com/) [![GitHub stars](https://img.shields.io/github/stars/systeminit/si.svg?style=social)](https://github.com/systeminit/si) | DevOps Automation Platform | DB: Postgres\n- [UpVPN](https://upvpn.app) [![GitHub stars](https://img.shields.io/github/stars/upvpn/upvpn-app.svg?style=social)](https://github.com/upvpn/upvpn-app) | Serverless VPN on WireGuard® | DB: SQLite, Postgres\n- [Zed](https://zed.dev/) [![GitHub stars](https://img.shields.io/github/stars/zed-industries/zed.svg?style=social)](https://github.com/zed-industries/zed) | A high-performance, multiplayer code editor | DB: Postgres\n\n### Open Source Projects\n\n#### CMS\n\n- [Backpack](https://github.com/JSH32/Backpack) | Open source self hosted file sharing platform on crack | DB: MySQL, Postgres, SQLite\n- [Dev Board](https://github.com/goto-eof/dev_board_api_rust) | A dashboard for organizing software development tasks implemented in Rust\n- [Iron Guard](https://github.com/AfaanBilal/iron-guard-server) | An inventory management system HTTP REST API server built with Rocket and SeaORM | DB: MySQL\n- [mediarepo](https://mediarepo.trivernis.dev) ([repository](https://github.com/Trivernis/mediarepo)) | A tag-based media management application | DB: SQLite\n- [mugen](https://github.com/koopa1338/mugen-dms) | DMS written in 🦀 | DB: Postgres\n- [OctoBase](https://github.com/toeverything/OctoBase) ![GitHub stars](https://img.shields.io/github/stars/toeverything/OctoBase.svg?style=social) | A light-weight, scalable, offline collaborative data backend | DB: MySQL, Postgres, SQLite\n- [Ryot](https://ryot.io/) ([repository](https://github.com/IgnisDa/ryot)) ![GitHub stars](https://img.shields.io/github/stars/ignisda/ryot.svg?style=social) | The only self hosted tracker you will ever need | DB: MySQL, Postgres, SQLite\n- [Wikijump](https://github.com/scpwiki/wikijump) ([repository](https://github.com/scpwiki/wikijump/tree/develop/deepwell)) | API service for Wikijump, a fork of Wikidot | DB: Postgres\n- [sero](https://github.com/clowzed/sero): Host static sites with custom subdomains as surge.sh does. But with full control and cool new features. DB: Postgres\n\n#### Game\n- [Ceobe Canteen Serve](https://github.com/Enraged-Dun-Cookie-Development-Team/Ceobe-Canteen-Serve) | A tool based on Arknights mobile game, using axum as web framework | DB: MySQL\n- [KongYing Tavern Backend](https://github.com/kongying-tavern/genshin-cloud-rust) | The community map navigation tool for Genshin Impact | DB: Postgres\n- [Pocket Relay](https://github.com/PocketRelay/Server) | Mass Effect 3 multiplayer private server emulator | DB: MySQL, SQLite\n- [seichi-portal-backend](https://github.com/GiganticMinecraft/seichi-portal-backend) | Backend server(REST API) of [seichi-portal](https://github.com/GiganticMinecraft/seichi-portal) | DB: MySQL\n- [thrpg](https://github.com/thrpg/thrpg) | Touhou Project's secondary creative games | DB: Postgres\n\n#### Social\n- [aeroFans](https://github.com/naryand/aerofans) | Full stack forum-like social media platform in Rust and WebAssembly | DB: Postgres\n- [Crab Fit](https://crab.fit) | Align your schedules to find the perfect time that works for everyone. | DB: MySQL, Postgres, SQLite\n- [Hatsu](https://github.com/importantimport/hatsu) | 🩵 Self-hosted & Fully-automated ActivityPub Bridge for Static Sites. | DB: SQLite, Postgres\n- [JinShu](https://github.com/gengteng/jinshu) | A cross-platform **I**nstant **M**essaging system written in 🦀 | DB: MySQL, Postgres\n- [Portfolio](https://github.com/admisio/Portfolio) | Encrypted high school 🏫 admissions service | DB: Postgres, SQLite\n- [THUBurrow](https://github.com/BobAnkh/THUBurrow) | A campus forum built by Next.js and Rocket | DB: Postgres\n- [playa](https://github.com/whizzes/playa) | 🏖️ Decentralized Social Platform powered by Rust and Whizzes Contributors\n\n#### Bots\n- [bulbbot-gw](https://github.com/TeamBulbbot/bulbbot-gw) | The gateway code for the Discord bot Bulbbot | DB: Postgres\n- [Fikabot](https://github.com/sousandrei/fikabot) | A slack bot to schedule coffee breaks (Fika in swedish) in slack channels | DB: MySQL\n- [remindee-bot](https://github.com/magnickolas/remindee-bot) | Telegram bot for managing reminders | DB: SQLite\n- [SophyCore](https://github.com/FarDragi/SophyCore) | Main system that centralizes all rules, to be used by both the discord bot and the future site | DB: Postgres\n- [Rustify](https://github.com/vtvz/rustify) | Telegram bot for Spotify with multi-source lyrics, AI analysis, real-time profanity detection and auto-skip | DB: Postgres\n\n#### Crypto\n- [MoonRamp](https://github.com/MoonRamp/MoonRamp) | A free and open source crypto payment gateway | DB: MySQL, Postgres, SQLite\n- [Oura Postgres Sink](https://github.com/dcSpark/oura-postgres-sink) | Sync a postgres database with the cardano blockchain using Oura | DB: Postgres\n- [RGB Lib](https://github.com/RGB-Tools/rgb-lib) | A library to manage wallets for RGB assets | DB: MySQL, Postgres, SQLite\n- [Sensei](https://github.com/L2-Technology/sensei) | A Bitcoin lightning node implementation | DB: MySQL, Postgres, SQLite\n\n#### Dev Tools\n- [CodeCTRL](https://codectrl.authentura.com) ([repository](https://github.com/Authentura/codectrl)) | A self-hostable code logging platform | DB: SQLite\n- [Crosup](https://github.com/tsirysndr/crosup) | Quickly setup your development environment on your Chromebook/ChromeOS or any Linux distribution | DB: SQLite\n- [CyberAPI](https://github.com/vicanso/cyberapi) API tool client for developer. | DB: SQLite\n- [nitro_repo](https://github.com/wyatt-herkamp/nitro_repo) | An OpenSource, lightweight, and fast artifact manager. | DB: MySQL, SQLite\n- [Notifico](https://notifico.tech) ([repository](https://github.com/notificohq/notifico)) | An advanced omni-channel notification server. | DB: MySQL, Postgres, SQLite\n- [Orca](https://github.com/workfoxes/orca) | An No-code Test Automation platform using Actix, SeaORM, React. runs on the desktop and cloud | DB: Postgres\n\n#### System\n- [Email view tracker](https://github.com/friedemannsommer/email-view-tracker) | Simple web UI to create tracking URLs for HTML emails. | DB: MySQL, Postgres\n- [LLDAP](https://github.com/nitnelave/lldap) ![GitHub stars](https://img.shields.io/github/stars/nitnelave/lldap.svg?style=social) | A light LDAP server for user management | DB: MySQL, Postgres, SQLite\n- [RSS aggregator](https://github.com/fistons/rss-aggregator)| A small RSS aggregator and API using Actix Web and SeaORM | DB: Postgres\n- [ruuth](https://github.com/outurnate/ruuth) ([repository](https://github.com/outurnate/ruuth)) | A simple nginx auth_request backend providing MFA and lockout mechanisms | DB: MySQL, Postgres, SQLite\n- [snmp-sim-rust](https://github.com/sonalake/snmp-sim-rust) | SNMP Simulator | DB: SQLite\n- [Wikipedia Speedrun](https://wikipediaspeedrun.com) ([repository](https://github.com/hut8/wikipedia-speedrun)) | Finds shortest paths between Wikipedia articles | DB: SQLite\n\n#### Url Shortener\n- [Dinoly](https://github.com/ippsav/Dinoly) | An url shortener using Axum web framework and SeaORM | DB: Postgres\n- [SlashURL](https://github.com/henriquekirchheck/slashurl) | A url shortener using Rust designed to be implemented anywhere | DB: PostgreSQL\n- [url_shortener](https://github.com/michidk/url_shortener) | A simple self-hosted URL shortener written in Rust | DB: MySQL, Postgres, SQLite\n\n#### Desktop / CLI Apps\n\n- [pansy](https://github.com/niuhuan/pansy) | An illustration app using SeaORM, SQLite, flutter. runs on the desktop and mobile terminals | DB: SQLite\n- [Spyglass](https://www.spyglass.fyi/) ([repository](https://github.com/a5huynh/spyglass)) ![GitHub stars](https://img.shields.io/github/stars/a5huynh/spyglass.svg?style=social) | 🔭 A personal search engine that indexes what you want w/ a simple set of rules. | DB: SQLite\n- [todo-rs](https://github.com/anshulxyz/todo-rs/) | A TUI ToDo-app written in Rust using Cursive library and SeaORM for SQLite | DB: SQLite\n- [Warpgate](https://github.com/warp-tech/warpgate) ![GitHub stars](https://img.shields.io/github/stars/warp-tech/warpgate.svg?style=social) | Smart SSH bastion that works with any SSH client | DB: SQLite\n\n#### Audio and Music\n\n- [Deaftone](https://deaftone.org) ([repository](https://github.com/Ortygia/Deaftone)) | Lightweight music server. With a clean and simple API | DB: SQLite\n- [Music Player](https://github.com/tsirysndr/music-player) ![GitHub stars](https://img.shields.io/github/stars/tsirysndr/music-player.svg?style=social) | An extensible music server written in Rust 🚀🎵✨ | DB: SQLite\n\n#### Embedded\n\n- [rj45less-server](https://github.com/pmnxis/rj45less-server) | A simple unique number allocator for custom router | DB: SQLite\n\n### Programming Libraries\n\n- [logic-lock](https://github.com/nappa85/logic-lock) | MySQL logic locks implemented over sea-orm | DB: MySQL\n- [sea-orm-adapter](https://github.com/ZihanType/sea-orm-adapter) | Sea ORM adapter for casbin-rs | DB: MySQL, Postgres, SQLite\n- [symbols](https://github.com/nappa85/symbols) | A proc-macro utility to populates enum variants with primary keys values\n\n### Frameworks\n\n- [actix-admin](https://github.com/mgugger/actix-admin) | An admin panel for Actix Web built with Tera, HTMX and SeaOrm | DB: MySQL, Postgres, SQLite\n- [poem_admin](https://github.com/lingdu1234/poem_admin) | An admin panel built with poems, SeaORM and Vue 3. | DB: MySQL, Postgres, SQLite\n- [Loco.rs](https://github.com/loco-rs/loco) | A full stack Web and API productivity framework similar to Rails, based on SeaORM with db tooling and migrations code generation | DB: Postgres, SQLite\n- [tardis](https://github.com/ideal-world/tardis) | Elegant, Clean Rust development framework🛸 | DB: MySQL, Postgres, SQLite\n- [spring-rs](https://github.com/spring-rs/spring-rs) | A application framework written in rust inspired by java's spring-boot🍃 | DB: MySQL, Postgres, SQLite\n- [qiluo-admin](https://github.com/chelunfu/qiluo_admin) | Axum + SeaORM + JWT + Scheduled + Tasks + SnowId + Redis + Memory + VUE3 | DB: MySQL, Postgres, SQLite\n\n### Scaffolding\n\n- [actix-react-starter-template](https://github.com/aslamplr/actix-react-starter-template) | Actix Web + SeaORM + React + Redux + Redux Saga project starter template | DB: Postgres\n- [Adta](https://github.com/aaronleopold/adta) | Adta is **A**nother **D**amn **T**odo **A**pp, fun little side project | DB: MySQL, Postgres, SQLite\n- [Axum Book Management](https://github.com/lz1998/axum-book-management) | CRUD system of book-management with ORM and JWT for educational purposes | DB: MySQL\n- [BookStore](https://github.com/AfaanBilal/bookstore) | A bookstore manegement system HTTP REST API using Rocket, SeaORM and JWT. | DB: MySQL\n- [crud-rs](https://github.com/onichandame/crud-rs) | A framework combining async-graphql and SeaORM\n- [http-api-rs](https://github.com/daniel-samson/http-api-rs) | Template project for creating REST API's in rust with swagger ui\n- [oxide_todo](https://github.com/TheAwiteb/oxide_todo) | RESTful Todo built with Actix, swagger-ui and SeaORM, tested by rstest. | DB: SQLite\n- [Rust Async-GraphQL Example: Caster API](https://github.com/bkonkle/rust-example-caster-api) | A demo GraphQL API using Tokio, Warp, async-graphql, and SeaORM | DB: Postgres\n- [rust-juniper-playground](https://github.com/Yama-Tomo/rust-juniper-playground) | juniper with SeaORM example | DB: MySQL\n- [service_auth](https://github.com/shorii/service_auth) | A simple JWT authentication web-application | DB: Postgres\n- [Super Toolbox](https://github.com/atopx/toolbox) | micro-service best practices: use go-gin and rust-tonic | DB: mysql\n- [rsapi](https://github.com/atopx/rsapi) | A lightweight REST API template, Axum + SeaORM + JWT Middleware + Mini DockerFile | DB: Postgres\n\n## Learning Resources\n\nIf you have an article, tutorial, podcast or video related to SeaORM and want to share it with the community, feel free to submit a PR and add it to the list below!\n\n- A video course on Axum and SeaORM: [Youtube Playlist](https://www.youtube.com/playlist?list=PLrmY5pVcnuE-_CP7XZ_44HN-mDrLQV4nS), [GitHub Code](https://github.com/brooks-builds/full-stack-todo-rust-course/tree/main/backend/rust/axum) by [\nBrooks Builds](https://github.com/brooks-builds)\n- Async GraphQL with Rust: [Part 1](https://konkle.us/async-graphql-rust-1-introduction/), [Part 2](https://konkle.us/async-graphql-with-rust-part-two/), [Part 3](https://konkle.us/async-graphql-with-rust-part-three/) by [Brandon Konkle](https://github.com/bkonkle)\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to SeaORM\n\nThank you for taking the time to read this. First of all, star ALL our repos!\n\nSeaORM is a community driven project. We welcome you to participate, contribute and together build for SeaQL's future.\n\n## Code of Conduct\n\nThis project is governed by the [SeaQL Code of Conduct](https://github.com/SeaQL/.github/blob/master/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.\n\n## I have a question\n\nIf you have a question to ask, please do not open an issue for it. It's quicker to ask us on [SeaQL Discord Server](https://discord.com/invite/uCPdDXzbdv) or open a [GitHub Discussion](https://docs.github.com/en/discussions/quickstart#creating-a-new-discussion) on the corresponding repository.\n\n## I need a feature\n\nFeature requests from anyone is definitely welcomed! Actually, since 0.2, many features are proposed and/or contributed by non-core members, e.g. [#105](https://github.com/SeaQL/sea-orm/issues/105), [#142](https://github.com/SeaQL/sea-orm/issues/142), [#252](https://github.com/SeaQL/sea-orm/issues/252), with various degrees of involvement. We will implement feature proposals if it benefits everyone, but of course code contributions will more likely be accepted.\n\n## I want to support\n\nAwesome! The best way to support us is to recommend it to your classmates/colleagues/friends, write blog posts and tutorials on SeaQL projects and help out other users in the community. It is difficult enough to keep an open source afloat, so every little help matters, especially if it can directly/indirectly lighten the core team's mental load.\n\n## I want to join\n\nWe are always looking for long-term contributors. If you want to commit longer-term to SeaQL's open source effort, definitely talk with us! There may be various forms of \"grant\" to compensate for your devotion. Although at this stage we are not resourceful enough to offer a stable stream of income to contributors.\n\n## I want to sponsor\n\nIf you don't have time to contribute but would like to support the organization, a financial contribution via [GitHub sponsor](https://github.com/sponsors/SeaQL) is a great way to support us.\n\n## I want to setup my machine for development and testing\n\nThanks for the time and effort to compose a PR! You are always welcomed to contact us via [Discord](https://discord.com/invite/uCPdDXzbdv) or GitHub if you need any help when contributing. Feel free to open draft PR and ask for review and guidance.\n\n### Unit Test\n\nWithout involving a live database, you can run unit tests on your machine with the command below:\n\n- Unit testing `sea-orm`, `sea-orm-macros`, `sea-orm-codegen`\n    ```sh\n    cargo test --workspace\n    ```\n- Unit testing `sea-orm-cli`\n    ```sh\n    cargo test --manifest-path sea-orm-cli/Cargo.toml\n    ```\n- Unit testing `sea-orm-rocket`\n    ```sh\n    cargo test --manifest-path sea-orm-rocket/Cargo.toml\n    ```\n\n### Integration Test\n\nNext, if you want to run integration tests on a live database. We recommend using Docker to spawn your database instance, you can refer to [this](build-tools/docker-compose.yml) docker compose file for reference.\n\nRunning integration tests on a live database:\n- SQLite\n    ```sh\n    DATABASE_URL=\"sqlite::memory:\" cargo test --all --features default,sqlx-sqlite,runtime-async-std-native-tls\n    ```\n- MySQL / MariaDB\n    ```sh\n    DATABASE_URL=\"mysql://root:root@localhost\" cargo test --all --features default,sqlx-mysql,runtime-async-std-rustls\n    ```\n- PostgreSQL\n    ```sh\n    DATABASE_URL=\"postgres://root:root@localhost\" cargo test --all --features default,sqlx-postgres,runtime-async-std-native-tls\n    ```\n\n### Running `sea-orm-cli` from source code\n\nYou can either run the follow command at root:\n\n```sh\ncargo run --manifest-path sea-orm-cli/Cargo.toml -- <command & arguments for sea-orm-cli>\n# E.g.\ncargo run --manifest-path sea-orm-cli/Cargo.toml -- migrate init\n```\n\nOr, you `cd` into `sea-orm-cli` directory and simply execute:\n\n```sh\ncargo run -- <command & arguments for sea-orm-cli>\n# E.g.\ncargo run -- migrate init\n```\n\n### Installing `sea-orm-cli` from source code\n\nYou can either run the follow command at root:\n\n```sh\ncargo install --force --path sea-orm-cli\n```\n\nOr, you `cd` into `sea-orm-cli` directory and simply execute:\n\n```sh\ncargo install --force --path .\n```\n\nOr, you install `sea-orm-cli` from GitHub:\n\n```sh\ncargo install sea-orm-cli --force --git https://github.com/SeaQL/sea-orm --branch <GIT_BRANCH>\n```\n\n### TOML formatting \n\nWe use `taplo` to format and lint TOML files across the repository.\n\n```sh\ncargo install --locked taplo-cli\ntaplo fmt --check \n```\n\n"
  },
  {
    "path": "Cargo.toml",
    "content": "[workspace]\nmembers = [\".\", \"sea-orm-macros\", \"sea-orm-codegen\", \"sea-orm-arrow\"]\n\n[package]\nauthors       = [\"Chris Tsang <chris.2y3@outlook.com>\"]\ncategories    = [\"database\"]\ndescription   = \"🐚 An async & dynamic ORM for Rust\"\ndocumentation = \"https://docs.rs/sea-orm\"\nedition       = \"2024\"\nhomepage      = \"https://www.sea-ql.org/SeaORM\"\nkeywords      = [\"async\", \"orm\", \"mysql\", \"postgres\", \"sqlite\"]\nlicense       = \"MIT OR Apache-2.0\"\nname          = \"sea-orm\"\nrepository    = \"https://github.com/SeaQL/sea-orm\"\nrust-version  = \"1.85.0\"\nversion       = \"2.0.0-rc.37\"\n\n[package.metadata.docs.rs]\nfeatures = [\n    \"default\",\n    \"sqlx-all\",\n    \"mock\",\n    \"proxy\",\n    \"rbac\",\n    \"schema-sync\",\n    \"tracing-spans\",\n    \"runtime-tokio-native-tls\",\n    \"postgres-array\",\n    \"postgres-vector\",\n    \"with-ipnetwork\",\n    \"with-arrow\",\n]\nrustdoc-args = [\"--cfg\", \"docsrs\"]\n\n[lib]\nname = \"sea_orm\"\npath = \"src/lib.rs\"\n\n[dependencies]\nasync-stream = { version = \"0.3\", default-features = false }\nasync-trait = { version = \"0.1\", default-features = false }\nbigdecimal = { version = \"0.4\", default-features = false, features = [\n    \"std\",\n], optional = true }\nchrono = { version = \"0.4.30\", default-features = false, optional = true }\nderive_more = { version = \"2\", features = [\"debug\"] }\nfutures-util = { version = \"0.3\", default-features = false, features = [\n    \"std\",\n] }\ninventory = { version = \"0.3\", optional = true }\nipnetwork = { version = \"0.20\", default-features = false, optional = true }\nitertools = \"0.14.0\"\nlog = { version = \"0.4\", default-features = false }\nmac_address = { version = \"1.1\", default-features = false, optional = true }\nouroboros = { version = \"0.18\", default-features = false }\npgvector = { version = \"~0.4\", default-features = false, optional = true }\nrust_decimal = { version = \"1\", default-features = false, features = [\n    \"std\",\n], optional = true }\nsea-orm-arrow = { version = \"2.0.0-rc\", path = \"sea-orm-arrow\", default-features = false, optional = true }\nsea-orm-macros = { version = \"~2.0.0-rc.37\", path = \"sea-orm-macros\", default-features = false, features = [\n    \"async\",\n    \"strum\",\n] }\nsea-query = { version = \"=1.0.0-rc.32\", default-features = false, features = [\n    \"thread-safe\",\n    \"hashable-value\",\n    \"backend-mysql\",\n    \"backend-postgres\",\n    \"backend-sqlite\",\n    \"sea-orm\",\n] }\nsea-query-sqlx = { version = \"=0.8.0-rc.14\", default-features = false, optional = true }\nsea-schema = { version = \"0.17.0-rc.15\", default-features = false, features = [\n    \"discovery\",\n    \"writer\",\n    \"probe\",\n], optional = true }\nserde = { version = \"1.0\", default-features = false }\nserde_json = { version = \"1.0\", default-features = false, optional = true }\nsqlx = { version = \"0.8.4\", default-features = false, optional = true }\nstrum = { version = \"0.28\", default-features = false }\nthiserror = { version = \"2\", default-features = false }\ntime = { version = \"0.3.36\", default-features = false, optional = true }\ntracing = { version = \"0.1\", default-features = false, features = [\n    \"attributes\",\n    \"log\",\n] }\nurl = { version = \"2.2\", default-features = false }\nuuid = { version = \"1\", default-features = false, optional = true }\n\n[dev-dependencies]\ndotenv = \"0.15\"\nmaplit = { version = \"1\" }\npretty_assertions = { version = \"0.7\" }\nsea-orm = { path = \".\", features = [\n    \"debug-print\",\n    \"mock\",\n    \"postgres-array\",\n    \"tests-cfg\",\n] }\nsmol = { version = \"1.2\" }\nsmol-potat = { version = \"1.1\" }\ntime = { version = \"0.3.36\", features = [\"macros\"] }\ntokio = { version = \"1.6\", features = [\"full\"] }\ntracing-subscriber = { version = \"0.3.17\", features = [\"env-filter\"] }\nuuid = { version = \"1\", features = [\"v4\"] }\n\n[features]\ndebug-print = []\ndefault = [\n    \"macros\",\n    \"with-json\",\n    \"with-chrono\",\n    \"with-rust_decimal\",\n    \"with-uuid\",\n    \"with-time\",\n    \"sqlite-use-returning-for-3_35\",\n]\nentity-registry = [\"inventory\", \"sea-orm-macros/entity-registry\"]\njson-array = [\n    \"postgres-array\",\n] # this does not actually enable sqlx-postgres, but only a few traits to support array in sea-query\nmacros = [\"sea-orm-macros/derive\"]\nmariadb-use-returning = []\nmock = []\npostgres-array = [\n    \"sea-query/postgres-array\",\n    \"sea-orm-macros/postgres-array\",\n    \"sea-query-sqlx?/postgres-array\",\n]\npostgres-use-serial-pk = [\"sea-query/option-postgres-use-serial\"]\npostgres-vector = [\n    \"pgvector\",\n    \"sea-query/postgres-vector\",\n    \"sea-query-sqlx?/postgres-vector\",\n]\nproxy = [\"serde/derive\"]\nrbac = [\"sea-query/audit\", \"macros\"]\nruntime-async-std = [\"sqlx?/runtime-async-std\"]\nruntime-async-std-native-tls = [\n    \"sqlx?/runtime-async-std-native-tls\",\n    \"runtime-async-std\",\n]\nruntime-async-std-rustls = [\n    \"sqlx?/runtime-async-std-rustls\",\n    \"runtime-async-std\",\n]\nruntime-tokio = [\"sqlx?/runtime-tokio\"]\nruntime-tokio-native-tls = [\"sqlx?/runtime-tokio-native-tls\", \"runtime-tokio\"]\nruntime-tokio-rustls = [\"sqlx?/runtime-tokio-rustls\", \"runtime-tokio\"]\nrusqlite = []\nschema-sync = [\"sea-schema\"]\nsea-orm-internal = []\nseaography = [\"sea-orm-macros/seaography\"]\nsqlite-no-row-value-before-3_15 = []\nsqlite-use-returning-for-3_35 = []\nsqlx-all = [\"sqlx-mysql\", \"sqlx-postgres\", \"sqlx-sqlite\"]\nsqlx-dep = [\"sqlx\"]\nsqlx-mysql = [\n    \"sqlx-dep\",\n    \"sea-query-sqlx/sqlx-mysql\",\n    \"sea-schema?/sqlx-mysql\",\n]\nsqlx-postgres = [\n    \"sqlx-dep\",\n    \"sea-query-sqlx/sqlx-postgres\",\n    \"postgres-array\",\n    \"sea-schema?/sqlx-postgres\",\n]\nsqlx-sqlite = [\n    \"sqlx-dep\",\n    \"sea-query-sqlx/sqlx-sqlite\",\n    \"sea-schema?/sqlx-sqlite\",\n]\nsync = []\ntests-cfg = [\"serde/derive\"]\ntests-features = [\n    \"default\",\n    \"postgres-array\",\n    \"rbac\",\n    \"schema-sync\",\n    \"with-arrow\",\n    \"with-bigdecimal\",\n    \"with-ipnetwork\",\n]\ntracing-spans = []\nwith-arrow = [\"sea-orm-arrow\", \"sea-orm-macros/with-arrow\"]\nwith-bigdecimal = [\n    \"bigdecimal\",\n    \"sea-query/with-bigdecimal\",\n    \"sea-query-sqlx?/with-bigdecimal\",\n    \"sea-orm-arrow?/with-bigdecimal\",\n]\nwith-chrono = [\n    \"chrono\",\n    \"sea-query/with-chrono\",\n    \"sea-query-sqlx?/with-chrono\",\n    \"sea-orm-arrow?/with-chrono\",\n]\nwith-ipnetwork = [\n    \"ipnetwork\",\n    \"sea-query/with-ipnetwork\",\n    \"sea-query-sqlx?/with-ipnetwork\",\n]\nwith-json = [\n    \"serde_json\",\n    \"sea-query/with-json\",\n    \"sea-orm-macros/with-json\",\n    \"chrono?/serde\",\n    \"rust_decimal?/serde\",\n    \"bigdecimal?/serde\",\n    \"uuid?/serde\",\n    \"time?/serde\",\n    \"mac_address?/serde\",\n    \"pgvector?/serde\",\n    \"sea-query-sqlx?/with-json\",\n]\nwith-mac_address = [\n    \"mac_address\",\n    \"sea-query/with-mac_address\",\n    \"sea-query-sqlx?/with-mac_address\",\n]\nwith-rust_decimal = [\n    \"rust_decimal\",\n    \"sea-query/with-rust_decimal\",\n    \"sea-query-sqlx?/with-rust_decimal\",\n    \"sea-orm-arrow?/with-rust_decimal\",\n]\nwith-time = [\n    \"time\",\n    \"sea-query/with-time\",\n    \"sea-query-sqlx?/with-time\",\n    \"sea-orm-arrow?/with-time\",\n]\nwith-uuid = [\"uuid\", \"sea-query/with-uuid\", \"sea-query-sqlx?/with-uuid\"]\n\n# This allows us to develop using a local version of sea-query\n[patch.crates-io]\n# sea-query = { path = \"../sea-query\" }\n# sea-query = { git = \"https://github.com/SeaQL/sea-query\", branch = \"master\" }\n"
  },
  {
    "path": "DEVELOPMENT.md",
    "content": "## Use a local SeaORM version\n\nAdd this to your `Cargo.toml` for you local project to test out your changes:\n\n```toml\n[patch.crates-io]\nsea-orm = { path = \"../sea-orm\" }\n```\n\n## Before submitting PR\n\n### Run `clippy` and `fmt`\n\nWe need nightly to do the formatting,\n\n```sh\ncargo +nightly fmt\n```\n\nIf you don't have nightly then at least run:\n\n```sh\ncargo fmt && git checkout -- ./sea-orm-codegen/src/tests_cfg/\n```\n\nWe use latest stable clippy:\n\n```sh\ncargo clippy --all\n```\n\n### Running unit tests\n\nJust do:\n\n```sh\ncargo test --lib\ncargo test --doc\n```\n\n### Launch some databases\n\nThere is a docker compose under `build-tools`, but usually I just pick the ones I need from `build-tools/docker-crete.sh`:\n\n```sh\ndocker run \\\n    --name \"postgres-14\" \\\n    --env POSTGRES_USER=\"sea\" \\\n    --env POSTGRES_PASSWORD=\"sea\" \\\n    -d -p 5432:5432 postgres:14\n```\n\n### Running integration tests\n\nYou need to supply the right feature flags to run integration tests:\n\n```sh\nDATABASE_URL=\"sqlite::memory:\"              cargo test --features sqlx-sqlite,runtime-tokio              --test crud_tests\nDATABASE_URL=\"mysql://sea:sea@localhost\"    cargo test --features sqlx-mysql,runtime-tokio-native-tls    --test crud_tests\nDATABASE_URL=\"postgres://sea:sea@localhost\" cargo test --features sqlx-postgres,runtime-tokio-native-tls --test crud_tests\n```\n\nOr use `--tests` to run all tests, which can take a while.\n"
  },
  {
    "path": "LICENSE-APACHE",
    "content": "                              Apache License\n                        Version 2.0, January 2004\n                     http://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n   \"License\" shall mean the terms and conditions for use, reproduction,\n   and distribution as defined by Sections 1 through 9 of this document.\n\n   \"Licensor\" shall mean the copyright owner or entity authorized by\n   the copyright owner that is granting the License.\n\n   \"Legal Entity\" shall mean the union of the acting entity and all\n   other entities that control, are controlled by, or are under common\n   control with that entity. For the purposes of this definition,\n   \"control\" means (i) the power, direct or indirect, to cause the\n   direction or management of such entity, whether by contract or\n   otherwise, or (ii) ownership of fifty percent (50%) or more of the\n   outstanding shares, or (iii) beneficial ownership of such entity.\n\n   \"You\" (or \"Your\") shall mean an individual or Legal Entity\n   exercising permissions granted by this License.\n\n   \"Source\" form shall mean the preferred form for making modifications,\n   including but not limited to software source code, documentation\n   source, and configuration files.\n\n   \"Object\" form shall mean any form resulting from mechanical\n   transformation or translation of a Source form, including but\n   not limited to compiled object code, generated documentation,\n   and conversions to other media types.\n\n   \"Work\" shall mean the work of authorship, whether in Source or\n   Object form, made available under the License, as indicated by a\n   copyright notice that is included in or attached to the work\n   (an example is provided in the Appendix below).\n\n   \"Derivative Works\" shall mean any work, whether in Source or Object\n   form, that is based on (or derived from) the Work and for which the\n   editorial revisions, annotations, elaborations, or other modifications\n   represent, as a whole, an original work of authorship. For the purposes\n   of this License, Derivative Works shall not include works that remain\n   separable from, or merely link (or bind by name) to the interfaces of,\n   the Work and Derivative Works thereof.\n\n   \"Contribution\" shall mean any work of authorship, including\n   the original version of the Work and any modifications or additions\n   to that Work or Derivative Works thereof, that is intentionally\n   submitted to Licensor for inclusion in the Work by the copyright owner\n   or by an individual or Legal Entity authorized to submit on behalf of\n   the copyright owner. For the purposes of this definition, \"submitted\"\n   means any form of electronic, verbal, or written communication sent\n   to the Licensor or its representatives, including but not limited to\n   communication on electronic mailing lists, source code control systems,\n   and issue tracking systems that are managed by, or on behalf of, the\n   Licensor for the purpose of discussing and improving the Work, but\n   excluding communication that is conspicuously marked or otherwise\n   designated in writing by the copyright owner as \"Not a Contribution.\"\n\n   \"Contributor\" shall mean Licensor and any individual or Legal Entity\n   on behalf of whom a Contribution has been received by Licensor and\n   subsequently incorporated within the Work.\n\n2. Grant of Copyright License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   copyright license to reproduce, prepare Derivative Works of,\n   publicly display, publicly perform, sublicense, and distribute the\n   Work and such Derivative Works in Source or Object form.\n\n3. Grant of Patent License. Subject to the terms and conditions of\n   this License, each Contributor hereby grants to You a perpetual,\n   worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n   (except as stated in this section) patent license to make, have made,\n   use, offer to sell, sell, import, and otherwise transfer the Work,\n   where such license applies only to those patent claims licensable\n   by such Contributor that are necessarily infringed by their\n   Contribution(s) alone or by combination of their Contribution(s)\n   with the Work to which such Contribution(s) was submitted. If You\n   institute patent litigation against any entity (including a\n   cross-claim or counterclaim in a lawsuit) alleging that the Work\n   or a Contribution incorporated within the Work constitutes direct\n   or contributory patent infringement, then any patent licenses\n   granted to You under this License for that Work shall terminate\n   as of the date such litigation is filed.\n\n4. Redistribution. You may reproduce and distribute copies of the\n   Work or Derivative Works thereof in any medium, with or without\n   modifications, and in Source or Object form, provided that You\n   meet the following conditions:\n\n   (a) You must give any other recipients of the Work or\n       Derivative Works a copy of this License; and\n\n   (b) You must cause any modified files to carry prominent notices\n       stating that You changed the files; and\n\n   (c) You must retain, in the Source form of any Derivative Works\n       that You distribute, all copyright, patent, trademark, and\n       attribution notices from the Source form of the Work,\n       excluding those notices that do not pertain to any part of\n       the Derivative Works; and\n\n   (d) If the Work includes a \"NOTICE\" text file as part of its\n       distribution, then any Derivative Works that You distribute must\n       include a readable copy of the attribution notices contained\n       within such NOTICE file, excluding those notices that do not\n       pertain to any part of the Derivative Works, in at least one\n       of the following places: within a NOTICE text file distributed\n       as part of the Derivative Works; within the Source form or\n       documentation, if provided along with the Derivative Works; or,\n       within a display generated by the Derivative Works, if and\n       wherever such third-party notices normally appear. The contents\n       of the NOTICE file are for informational purposes only and\n       do not modify the License. You may add Your own attribution\n       notices within Derivative Works that You distribute, alongside\n       or as an addendum to the NOTICE text from the Work, provided\n       that such additional attribution notices cannot be construed\n       as modifying the License.\n\n   You may add Your own copyright statement to Your modifications and\n   may provide additional or different license terms and conditions\n   for use, reproduction, or distribution of Your modifications, or\n   for any such Derivative Works as a whole, provided Your use,\n   reproduction, and distribution of the Work otherwise complies with\n   the conditions stated in this License.\n\n5. Submission of Contributions. Unless You explicitly state otherwise,\n   any Contribution intentionally submitted for inclusion in the Work\n   by You to the Licensor shall be under the terms and conditions of\n   this License, without any additional terms or conditions.\n   Notwithstanding the above, nothing herein shall supersede or modify\n   the terms of any separate license agreement you may have executed\n   with Licensor regarding such Contributions.\n\n6. Trademarks. This License does not grant permission to use the trade\n   names, trademarks, service marks, or product names of the Licensor,\n   except as required for reasonable and customary use in describing the\n   origin of the Work and reproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty. Unless required by applicable law or\n   agreed to in writing, Licensor provides the Work (and each\n   Contributor provides its Contributions) on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n   implied, including, without limitation, any warranties or conditions\n   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n   PARTICULAR PURPOSE. You are solely responsible for determining the\n   appropriateness of using or redistributing the Work and assume any\n   risks associated with Your exercise of permissions under this License.\n\n8. Limitation of Liability. In no event and under no legal theory,\n   whether in tort (including negligence), contract, or otherwise,\n   unless required by applicable law (such as deliberate and grossly\n   negligent acts) or agreed to in writing, shall any Contributor be\n   liable to You for damages, including any direct, indirect, special,\n   incidental, or consequential damages of any character arising as a\n   result of this License or out of the use or inability to use the\n   Work (including but not limited to damages for loss of goodwill,\n   work stoppage, computer failure or malfunction, or any and all\n   other commercial damages or losses), even if such Contributor\n   has been advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability. While redistributing\n   the Work or Derivative Works thereof, You may choose to offer,\n   and charge a fee for, acceptance of support, warranty, indemnity,\n   or other liability obligations and/or rights consistent with this\n   License. However, in accepting such obligations, You may act only\n   on Your own behalf and on Your sole responsibility, not on behalf\n   of any other Contributor, and only if You agree to indemnify,\n   defend, and hold each Contributor harmless for any liability\n   incurred by, or claims asserted against, such Contributor by reason\n   of your accepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work.\n\n   To apply the Apache License to your work, attach the following\n   boilerplate notice, with the fields enclosed by brackets \"[]\"\n   replaced with your own identifying information. (Don't include\n   the brackets!)  The text should be enclosed in the appropriate\n   comment syntax for the file format. We also recommend that a\n   file or class name and description of purpose be included on the\n   same \"printed page\" as the copyright notice for easier\n   identification within third-party archives.\n\nCopyright [yyyy] [name of copyright owner]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\thttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
  },
  {
    "path": "LICENSE-MIT",
    "content": "Copyright (c) 2023 Seafire Software Limited\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the\nSoftware without restriction, including without\nlimitation the rights to use, copy, modify, merge,\npublish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software\nis furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice\nshall be included in all copies or substantial portions\nof the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF\nANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\nTO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\nSHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR\nIN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE."
  },
  {
    "path": "README-zh.md",
    "content": "<div align=\"center\">\n\n  <img alt=\"SeaORM\" src=\"https://www.sea-ql.org/blog/img/SeaORM 2.0 Banner.png\"/>\n\n  <h1></h1>\n  <h3>一个强大且动态的 Rust ORM</h3>\n\n  [![crate](https://img.shields.io/crates/v/sea-orm.svg)](https://crates.io/crates/sea-orm)\n  [![build status](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml/badge.svg)](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml)\n  [![GitHub stars](https://img.shields.io/github/stars/SeaQL/sea-orm.svg?style=social&label=Star&maxAge=1)](https://github.com/SeaQL/sea-orm/stargazers/)\n  <br>请给我们一个 ⭐ 以支持我们！\n\n</div>\n\n# 🐚 SeaORM\n\nSeaORM 是一个关系型 ORM，帮助你在 Rust 中构建 Web 服务，同时提供动态语言的使用体验。\n\n### 高级关系\n\n以高层次、概念化的方式建模复杂关系：一对一、一对多、多对多，甚至自引用。\n\n### 熟悉的概念\n\n受 Ruby、Python 和 Node.js 生态系统中流行 ORM 的启发，SeaORM 提供的开发体验让你感觉似曾相识。\n\n### 功能丰富\n\nSeaORM 是一个功能齐全的 ORM，内置过滤、分页和嵌套查询，加速构建 REST、GraphQL 和 gRPC API。\n\n### 生产就绪\n\nSeaORM 周下载量超过 25 万次，已被全球的初创企业和大型企业采用，适用于生产环境。\n\n## 快速开始\n\n[![Discord](https://img.shields.io/discord/873880840487206962?label=Discord)](https://discord.com/invite/uCPdDXzbdv)\n加入我们的 Discord 服务器，与其他成员交流！\n\n+ [中文文档](https://www.sea-ql.org/SeaORM/zh-CN/docs/index/)\n\n集成示例：\n\n+ [Actix 示例](https://github.com/SeaQL/sea-orm/tree/master/examples/actix_example)\n+ [Axum 示例](https://github.com/SeaQL/sea-orm/tree/master/examples/axum_example)\n+ [GraphQL 示例](https://github.com/SeaQL/sea-orm/tree/master/examples/graphql_example)\n+ [jsonrpsee 示例](https://github.com/SeaQL/sea-orm/tree/master/examples/jsonrpsee_example)\n+ [Loco 示例](https://github.com/SeaQL/sea-orm/tree/master/examples/loco_example) / [Loco REST 入门](https://github.com/SeaQL/sea-orm/tree/master/examples/loco_starter)\n+ [Poem 示例](https://github.com/SeaQL/sea-orm/tree/master/examples/poem_example)\n+ [Rocket 示例](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_example) / [Rocket OpenAPI 示例](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_okapi_example)\n+ [Salvo 示例](https://github.com/SeaQL/sea-orm/tree/master/examples/salvo_example)\n+ [Tonic 示例](https://github.com/SeaQL/sea-orm/tree/master/examples/tonic_example)\n+ [Seaography 示例 (Bakery)](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) / [Seaography 示例 (Sakila)](https://github.com/SeaQL/seaography/tree/main/examples/sqlite)\n\n如果你想要一个简洁的单文件示例来展示 SeaORM 的精华，可以试试：\n+ [快速入门](https://github.com/SeaQL/sea-orm/blob/master/examples/quickstart/src/main.rs)\n\n让我们快速了解一下 SeaORM 的独特功能。\n\n## 灵活的实体格式\n你不需要手写这些！实体文件可以使用 `sea-orm-cli` 从现有数据库生成，\n以下代码通过 `--entity-format dense` 生成 *(2.0 新增)*。\n```rust\nmod user {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"user\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n        #[sea_orm(unique)]\n        pub email: String,\n        #[sea_orm(has_one)]\n        pub profile: HasOne<super::profile::Entity>,\n        #[sea_orm(has_many)]\n        pub posts: HasMany<super::post::Entity>,\n    }\n}\nmod post {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"post\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub user_id: i32,\n        pub title: String,\n        #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n        pub author: HasOne<super::user::Entity>,\n        #[sea_orm(has_many, via = \"post_tag\")] // 多对多关系，使用中间表\n        pub tags: HasMany<super::tag::Entity>,\n    }\n}\n```\n\n## 智能实体加载器\n实体加载器智能地对一对一关系使用 join，对一对多关系使用 data loader，\n即使在执行嵌套查询时也能消除 N+1 问题。\n```rust\n// 加载路径:\n// user -> profile\n// user -> post\n//         post -> post_tag -> tag\nlet smart_user = user::Entity::load()\n    .filter_by_id(42) // 等价于 .filter(user::COLUMN.id.eq(42))\n    .with(profile::Entity) // 一对一使用 join\n    .with((post::Entity, tag::Entity)) // 一对多使用 data loader\n    .one(db)\n    .await?\n    .unwrap();\n\n// 底层执行 3 个查询:\n// 1. SELECT FROM user JOIN profile WHERE id = $\n// 2. SELECT FROM post WHERE user_id IN (..)\n// 3. SELECT FROM tag JOIN post_tag WHERE post_id IN (..)\n\nsmart_user\n    == user::ModelEx {\n        id: 42,\n        name: \"Bob\".into(),\n        email: \"bob@sea-ql.org\".into(),\n        profile: HasOne::Loaded(\n            profile::ModelEx {\n                picture: \"image.jpg\".into(),\n            }\n            .into(),\n        ),\n        posts: HasMany::Loaded(vec![post::ModelEx {\n            title: \"Nice weather\".into(),\n            tags: HasMany::Loaded(vec![tag::ModelEx {\n                tag: \"sunny\".into(),\n            }]),\n        }]),\n    };\n```\n\n## ActiveModel：简化嵌套持久化\n通过流畅的 builder API，在单次操作中持久化整个对象图：用户、个人资料（一对一）、\n帖子（一对多）和标签（多对多）。SeaORM 自动确定依赖关系，\n以正确的顺序插入或删除对象。\n\n```rust\n// 创建上面展示的嵌套对象:\nlet user = user::ActiveModel::builder()\n    .set_name(\"Bob\")\n    .set_email(\"bob@sea-ql.org\")\n    .set_profile(profile::ActiveModel::builder().set_picture(\"image.jpg\"))\n    .add_post(\n        post::ActiveModel::builder()\n            .set_title(\"Nice weather\")\n            .add_tag(tag::ActiveModel::builder().set_tag(\"sunny\")),\n    )\n    .save(db)\n    .await?;\n```\n\n## Schema 优先还是实体优先？你的选择\n\nSeaORM 提供了强大的迁移系统，让你轻松创建表、修改 Schema 和填充数据。\n\nSeaORM 2.0 还提供了一流的[实体优先工作流](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/)：\n只需定义新实体或向现有实体添加列，\nSeaORM 将自动检测变更并创建新的表、列、唯一键和外键。\n\n```rust\n// SeaORM 解析外键依赖，按拓扑顺序创建表。\n// 需要 `entity-registry` 和 `schema-sync` feature flags。\ndb.get_schema_registry(\"my_crate::entity::*\").sync(db).await;\n```\n\n## 简洁的原生 SQL\n\n让 SeaORM 处理 95% 的事务查询。\n对于过于复杂而难以表达的剩余情况，\nSeaORM 仍然提供便捷的原生 SQL 支持。\n```rust\nlet user = Item { name: \"Bob\" }; // 嵌套参数访问\nlet ids = [2, 3, 4]; // 通过 `..` 运算符展开\n\nlet user: Option<user::Model> = user::Entity::find()\n    .from_raw_sql(raw_sql!(\n        Sqlite,\n        r#\"SELECT \"id\", \"name\" FROM \"user\"\n           WHERE \"name\" LIKE {user.name}\n           AND \"id\" in ({..ids})\n        \"#\n    ))\n    .one(db)\n    .await?;\n```\n\n## 同步支持\n\n[`sea-orm-sync`](https://crates.io/crates/sea-orm-sync) 提供完整的 SeaORM API，无需异步运行时，非常适合使用 SQLite 的轻量级 CLI 程序。\n\n参见[快速入门示例](https://github.com/SeaQL/sea-orm/blob/master/sea-orm-sync/examples/quickstart/src/main.rs)了解用法。\n\n## 基础操作\n\n### 查询\nSeaORM 在实体层面建模一对多和多对多关系，\n让你通过中间表在一次调用中遍历多对多链接。\n```rust\n// 查找所有模型\nlet cakes: Vec<cake::Model> = Cake::find().all(db).await?;\n\n// 查找并过滤\nlet chocolate: Vec<cake::Model> = Cake::find()\n    .filter(Cake::COLUMN.name.contains(\"chocolate\"))\n    .all(db)\n    .await?;\n\n// 查找单个模型\nlet cheese: Option<cake::Model> = Cake::find_by_id(1).one(db).await?;\nlet cheese: cake::Model = cheese.unwrap();\n\n// 查找关联模型（惰性）\nlet fruit: Option<fruit::Model> = cheese.find_related(Fruit).one(db).await?;\n\n// 查找关联模型（急切加载）：用于一对一关系\nlet cake_with_fruit: Vec<(cake::Model, Option<fruit::Model>)> =\n    Cake::find().find_also_related(Fruit).all(db).await?;\n\n// 查找关联模型（急切加载）：同时适用于一对多和多对多关系\nlet cake_with_fillings: Vec<(cake::Model, Vec<filling::Model>)> = Cake::find()\n    .find_with_related(Filling) // 多对多关系会执行两次 join\n    .all(db) // 行会自动按左侧实体合并\n    .await?;\n```\n### 嵌套查询\n\nPartial model 通过只查询所需字段来避免过度获取；\n它还使编写深层嵌套的关系查询变得简单。\n```rust\nuse sea_orm::DerivePartialModel;\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"cake::Entity\")]\nstruct CakeWithFruit {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    fruit: Option<fruit::Model>, // 可以是普通模型或另一个 partial model\n}\n\nlet cakes: Vec<CakeWithFruit> = Cake::find()\n    .left_join(fruit::Entity) // 无需指定 join 条件\n    .into_partial_model() // 只会查询 partial model 中的列\n    .all(db)\n    .await?;\n```\n\n### 插入\nSeaORM 的 ActiveModel 让你直接使用 Rust 数据结构，\n通过简单的 API 进行持久化。\n批量插入大量不同数据源的行也很方便。\n```rust\nlet apple = fruit::ActiveModel {\n    name: Set(\"Apple\".to_owned()),\n    ..Default::default() // 无需设置主键\n};\n\nlet pear = fruit::ActiveModel {\n    name: Set(\"Pear\".to_owned()),\n    ..Default::default()\n};\n\n// 插入单个：Active Record 风格\nlet apple = apple.insert(db).await?;\napple.id == 1;\n\n// 插入单个：Repository 风格\nlet result = Fruit::insert(apple).exec(db).await?;\nresult.last_insert_id == 1;\n\n// 插入多个，返回最后插入的 id\nlet result = Fruit::insert_many([apple, pear]).exec(db).await?;\nresult.last_insert_id == Some(2);\n```\n\n### 高级插入\n你可以利用数据库特有的功能执行 upsert 和幂等插入。\n```rust\n// 插入多条并返回（需要数据库支持）\nlet models: Vec<fruit::Model> = Fruit::insert_many([apple, pear])\n    .exec_with_returning(db)\n    .await?;\nmodels[0]\n    == fruit::Model {\n        id: 1, // 数据库分配的值\n        name: \"Apple\".to_owned(),\n        cake_id: None,\n    };\n\n// 使用 ON CONFLICT 在主键冲突时忽略，并提供 MySQL 特定的 polyfill\nlet result = Fruit::insert_many([apple, pear])\n    .on_conflict_do_nothing()\n    .exec(db)\n    .await?;\n\nmatches!(result, TryInsertResult::Conflicted);\n```\n\n### 更新\nActiveModel 通过只更新你修改过的字段来避免竞态条件，\n绝不会覆盖未改动的列。\n你还可以使用流畅的查询构建 API 构造复杂的批量更新查询。\n```rust\nuse sea_orm::sea_query::{Expr, Value};\n\nlet pear: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;\nlet mut pear: fruit::ActiveModel = pear.unwrap().into();\n\npear.name = Set(\"Sweet pear\".to_owned()); // 更新单个字段的值\n\n// 更新单个：只更新修改过的列\nlet pear: fruit::Model = pear.update(db).await?;\n\n// 更新多个：UPDATE \"fruit\" SET \"cake_id\" = \"cake_id\" + 2\n//            WHERE \"fruit\".\"name\" LIKE '%Apple%'\nFruit::update_many()\n    .col_expr(fruit::COLUMN.cake_id, fruit::COLUMN.cake_id.add(2))\n    .filter(fruit::COLUMN.name.contains(\"Apple\"))\n    .exec(db)\n    .await?;\n```\n### 保存\n你可以使用 ActiveModel 执行\"插入或更新\"操作，轻松组合事务操作。\n```rust\nlet banana = fruit::ActiveModel {\n    id: NotSet,\n    name: Set(\"Banana\".to_owned()),\n    ..Default::default()\n};\n\n// 创建，因为主键 `id` 是 `NotSet`\nlet mut banana = banana.save(db).await?;\n\nbanana.id == Unchanged(2);\nbanana.name = Set(\"Banana Mongo\".to_owned());\n\n// 更新，因为主键 `id` 已存在\nlet banana = banana.save(db).await?;\n```\n### 删除\n与插入和更新一致的 ActiveModel API。\n```rust\n// 删除单个：Active Record 风格\nlet orange: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;\nlet orange: fruit::Model = orange.unwrap();\norange.delete(db).await?;\n\n// 删除单个：Repository 风格\nlet orange = fruit::ActiveModel {\n    id: Set(2),\n    ..Default::default()\n};\nfruit::Entity::delete(orange).exec(db).await?;\n\n// 删除多个：DELETE FROM \"fruit\" WHERE \"fruit\".\"name\" LIKE '%Orange%'\nfruit::Entity::delete_many()\n    .filter(fruit::COLUMN.name.contains(\"Orange\"))\n    .exec(db)\n    .await?;\n\n```\n### 原生 SQL 查询\n`raw_sql!` 宏类似 `format!` 宏，但没有 SQL 注入风险。\n它支持嵌套参数插值、数组和元组展开，甚至重复组，\n为构造复杂查询提供了极大的灵活性。\n\n```rust\n#[derive(FromQueryResult)]\nstruct CakeWithBakery {\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<Bakery>,\n}\n\n#[derive(FromQueryResult)]\nstruct Bakery {\n    #[sea_orm(alias = \"bakery_name\")]\n    name: String,\n}\n\nlet cake_ids = [2, 3, 4]; // 通过 `..` 运算符展开\n\n// 可以将原生 SQL 与多种 API 配合使用，包括嵌套查询\nlet cake: Option<CakeWithBakery> = CakeWithBakery::find_by_statement(raw_sql!(\n    Sqlite,\n    r#\"SELECT \"cake\".\"name\", \"bakery\".\"name\" AS \"bakery_name\"\n       FROM \"cake\"\n       LEFT JOIN \"bakery\" ON \"cake\".\"bakery_id\" = \"bakery\".\"id\"\n       WHERE \"cake\".\"id\" IN ({..cake_ids})\"#\n))\n.one(db)\n.await?;\n```\n\n## 🧭 Seaography：即时 GraphQL API\n\n[Seaography](https://github.com/SeaQL/seaography) 是一个构建在 SeaORM 之上的 GraphQL 框架。\nSeaography 允许你快速构建 GraphQL 解析器。\n只需几个命令，你就可以从 SeaORM 实体启动一个功能完备的 GraphQL 服务器，\n包含过滤、分页、关系查询和变更操作！\n\n查看 [Seaography 示例](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) 了解更多。\n\n<img src=\"https://raw.githubusercontent.com/SeaQL/sea-orm/master/examples/seaography_example/Seaography%20example.png\"/>\n\n## 🖥️ SeaORM Pro：专业管理面板\n\n[SeaORM Pro](https://github.com/SeaQL/sea-orm-pro/) 是一个管理面板解决方案，让你可以快速轻松地为应用程序启动管理面板——不需要前端开发技能，但有当然更好！\n\nSeaORM Pro 已更新以支持 SeaORM 2.0 的最新功能。\n\n特性：\n\n+ 完整的 CRUD 操作\n+ 基于 React + GraphQL 构建\n+ 内置 GraphQL 解析器\n+ 使用 TOML 配置自定义 UI\n+ 基于角色的访问控制 *(2.0 新增)*\n\n阅读[快速入门](https://www.sea-ql.org/sea-orm-pro/docs/install-and-config/getting-started/)指南了解更多。\n\n![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-dark.png#gh-dark-mode-only)\n![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-light.png#gh-light-mode-only)\n\n## SQL Server 支持\n\n[SQL Server for SeaORM](https://www.sea-ql.org/SeaORM-X/) 为 MSSQL 提供相同的 SeaORM API。我们移植了所有测试用例和示例，并配有 MSSQL 专属文档。如果你正在构建企业软件，可以[申请商业访问权限](https://forms.office.com/r/1MuRPJmYBR)。目前基于 SeaORM 1.0，但我们会在 SeaORM 2.0 最终发布时为现有用户提供免费升级。\n\n## 版本发布\n\nSeaORM 2.0 已进入候选发布阶段。我们期待你的试用，并通过[分享反馈](https://github.com/SeaQL/sea-orm/discussions/)来帮助塑造最终版本。\n\n+ [变更日志](https://github.com/SeaQL/sea-orm/tree/master/CHANGELOG.md)\n\nSeaORM 2.0 将是我们迄今最重要的版本——包含一些破坏性变更、大量增强功能，以及对开发者体验的明确聚焦。\n\n+ [SeaORM 2.0 先睹为快](https://www.sea-ql.org/blog/2025-09-16-sea-orm-2.0/)\n+ [深入了解 SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-24-sea-orm-2.0/)\n+ [SeaORM 2.0 中的基于角色的访问控制](https://www.sea-ql.org/blog/2025-09-30-sea-orm-rbac/)\n+ [Seaography 2.0：强大且可扩展的 GraphQL 框架](https://www.sea-ql.org/blog/2025-10-08-seaography/)\n+ [SeaORM 2.0：新实体格式](https://www.sea-ql.org/blog/2025-10-20-sea-orm-2.0/)\n+ [SeaORM 2.0：实体优先工作流](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/)\n+ [SeaORM 2.0：强类型列](https://www.sea-ql.org/blog/2025-11-11-sea-orm-2.0/)\n+ [SeaORM Pro 2.0 新特性](https://www.sea-ql.org/blog/2025-11-21-whats-new-in-seaormpro-2.0/)\n+ [SeaORM 2.0：嵌套 ActiveModel](https://www.sea-ql.org/blog/2025-11-25-sea-orm-2.0/)\n+ [SeaORM 2.0 全面介绍](https://www.sea-ql.org/blog/2025-12-05-sea-orm-2.0/)\n+ [我们如何让 SeaORM 支持同步](https://www.sea-ql.org/blog/2025-12-12-sea-orm-2.0/)\n+ [SeaORM 2.0 迁移指南](https://www.sea-ql.org/blog/2026-01-12-sea-orm-2.0/)\n+ [SeaORM 现已支持 Arrow 和 Parquet](https://www.sea-ql.org/blog/2026-02-22-sea-orm-arrow/)\n+ [SeaORM 2.0 支持 SQL Server](https://www.sea-ql.org/blog/2026-02-25-sea-orm-x/)\n\n如果你大量使用 SeaQuery，建议查看我们关于 SeaQuery 1.0 发布的博客文章：\n\n+ [SeaQuery 1.0 之路](https://www.sea-ql.org/blog/2025-08-30-sea-query-1.0/)\n\n## 许可证\n\n根据以下任一许可证授权：\n\n-   Apache 许可证 2.0\n    ([LICENSE-APACHE](LICENSE-APACHE) 或 <http://www.apache.org/licenses/LICENSE-2.0>)\n-   MIT 许可证\n    ([LICENSE-MIT](LICENSE-MIT) 或 <http://opensource.org/licenses/MIT>)\n\n由你选择。\n\n## 贡献\n\n除非你明确声明，否则你有意提交的任何贡献，根据 Apache-2.0 许可证的定义，都将按照上述许可证双重授权，且不附带任何附加条款或条件。\n\n我们诚挚邀请你参与、贡献，并携手共建 Rust 的未来。\n\n向我们的贡献者们致以最真诚的感谢！\n\n[![Contributors](https://opencollective.com/sea-orm/contributors.svg?width=1000&button=false)](https://github.com/SeaQL/sea-orm/graphs/contributors)\n\n## 谁在使用 SeaORM？\n\n以下是一些使用 SeaORM 构建的优秀开源软件的简短列表。欢迎[提交你的项目](https://github.com/SeaQL/sea-orm/blob/master/COMMUNITY.md#built-with-seaorm)！\n\n| 项目 | GitHub | 标语 |\n|---------|--------|---------|\n| [Zed](https://github.com/zed-industries/zed) | ![GitHub stars](https://img.shields.io/github/stars/zed-industries/zed.svg?style=social) | 高性能、多人代码编辑器 |\n| [OpenObserve](https://github.com/openobserve/openobserve) | ![GitHub stars](https://img.shields.io/github/stars/openobserve/openobserve.svg?style=social) | 开源可观测性平台 |\n| [RisingWave](https://github.com/risingwavelabs/risingwave) | ![GitHub stars](https://img.shields.io/github/stars/risingwavelabs/risingwave.svg?style=social) | 流处理和管理平台 |\n| [LLDAP](https://github.com/nitnelave/lldap) | ![GitHub stars](https://img.shields.io/github/stars/nitnelave/lldap.svg?style=social) | 轻量级 LDAP 用户管理服务器 |\n| [Warpgate](https://github.com/warp-tech/warpgate) | ![GitHub stars](https://img.shields.io/github/stars/warp-tech/warpgate.svg?style=social) | 智能 SSH 堡垒，适用于任何 SSH 客户端 |\n| [Svix](https://github.com/svix/svix-webhooks) | ![GitHub stars](https://img.shields.io/github/stars/svix/svix-webhooks.svg?style=social) | 企业级 Webhooks 服务 |\n| [Ryot](https://github.com/IgnisDa/ryot) | ![GitHub stars](https://img.shields.io/github/stars/ignisda/ryot.svg?style=social) | 你唯一需要的自托管追踪器 |\n| [Lapdev](https://github.com/lapce/lapdev) | ![GitHub stars](https://img.shields.io/github/stars/lapce/lapdev.svg?style=social) | 自托管远程开发环境 |\n| [System Initiative](https://github.com/systeminit/si) | ![GitHub stars](https://img.shields.io/github/stars/systeminit/si.svg?style=social) | DevOps 自动化平台 |\n| [OctoBase](https://github.com/toeverything/OctoBase) | ![GitHub stars](https://img.shields.io/github/stars/toeverything/OctoBase.svg?style=social) | 轻量级、可扩展、离线协作数据后端 |\n\n## 赞助\n\n[SeaQL.org](https://www.sea-ql.org/) 是一个由热情的开发者运营的独立开源组织。如果你愿意，通过 [GitHub Sponsor](https://github.com/sponsors/SeaQL) 进行小额捐赠将不胜感激，并将大大有助于维持组织的运营。\n\n### 金牌赞助商\n\n<table><tr>\n<td><a href=\"https://qdx.co/\">\n  <img src=\"https://www.sea-ql.org/static/sponsors/QDX.svg\" width=\"138\"/>\n</a></td>\n</tr></table>\n\n[QDX](https://qdx.co/) 开创了量子动力学驱动的药物发现，利用人工智能和超级计算加速分子建模。\n我们非常感谢 QDX 赞助 SeaORM 的开发，这是为其数据密集型应用提供支持的 SQL 工具包。\n\n### 银牌赞助商\n\n我们感谢银牌赞助商：Digital Ocean 赞助我们的服务器，以及 JetBrains 赞助我们的 IDE。\n\n<table><tr>\n<td><a href=\"https://www.digitalocean.com/\">\n  <img src=\"https://www.sea-ql.org/static/sponsors/DigitalOcean.svg\" width=\"125\">\n</a></td>\n\n<td><a href=\"https://www.jetbrains.com/\">\n  <img src=\"https://www.sea-ql.org/static/sponsors/JetBrains.svg\" width=\"125\">\n</a></td>\n</tr></table>\n\n## 吉祥物\n\nFerris 的朋友，寄居蟹 Terres 是 SeaORM 的官方吉祥物。他的爱好是收集贝壳。\n\n<img alt=\"Terres\" src=\"https://www.sea-ql.org/SeaORM/img/Terres.png\" width=\"400\"/>\n\n## 🦀 Rustacean 贴纸包\nRustacean 贴纸包是表达你对 Rust 热情的完美方式。我们的贴纸采用优质防水乙烯基制成，具有独特的哑光效果。\n\n贴纸包内容：\n\n+ SeaQL 项目的标志：SeaQL、SeaORM、SeaQuery、Seaography\n+ 吉祥物：Ferris x 3、寄居蟹 Terres\n+ Rustacean 文字标识\n\n[支持 SeaQL 并获取贴纸包！](https://www.sea-ql.org/sticker-pack/) 所有收益直接用于 SeaQL 项目的持续开发。\n\n<a href=\"https://www.sea-ql.org/sticker-pack/\"><img alt=\"Rustacean Sticker Pack by SeaQL\" src=\"https://www.sea-ql.org/static/sticker-pack-1s.jpg\" width=\"600\"/></a>\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n\n  <img alt=\"SeaORM\" src=\"https://www.sea-ql.org/blog/img/SeaORM 2.0 Banner.png\"/>\n\n  <h1></h1>\n  <h3>SeaORM is a powerful ORM for building web services in Rust</h3>\n\n  [![crate](https://img.shields.io/crates/v/sea-orm.svg)](https://crates.io/crates/sea-orm)\n  [![build status](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml/badge.svg)](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml)\n  [![GitHub stars](https://img.shields.io/github/stars/SeaQL/sea-orm.svg?style=social&label=Star&maxAge=1)](https://github.com/SeaQL/sea-orm/stargazers/)\n  <br>Support us with a ⭐ !\n\n</div>\n\n# 🐚 SeaORM\n\n[中文文档](https://github.com/SeaQL/sea-orm/blob/master/README-zh.md)\n\n### Advanced Relations\n\nModel complex relationships 1-1, 1-N, M-N, and even self-referential in a high-level, conceptual way.\n\n### Familiar Concepts\n\nInspired by popular ORMs in the Ruby, Python, and Node.js ecosystem, SeaORM offers a developer experience that feels instantly recognizable.\n\n### Feature Rich\n\nSeaORM is a batteries-included ORM with filters, pagination, and nested queries to accelerate building REST, GraphQL, and gRPC APIs.\n\n### Production Ready\n\nWith 250k+ weekly downloads, SeaORM is production-ready, trusted by startups and enterprises worldwide.\n\n## Getting Started\n\n[![Discord](https://img.shields.io/discord/873880840487206962?label=Discord)](https://discord.com/invite/uCPdDXzbdv)\nJoin our Discord server to chat with others!\n\n+ [Documentation](https://www.sea-ql.org/SeaORM)\n\nIntegration examples:\n\n+ [Actix Example](https://github.com/SeaQL/sea-orm/tree/master/examples/actix_example)\n+ [Axum Example](https://github.com/SeaQL/sea-orm/tree/master/examples/axum_example)\n+ [GraphQL Example](https://github.com/SeaQL/sea-orm/tree/master/examples/graphql_example)\n+ [jsonrpsee Example](https://github.com/SeaQL/sea-orm/tree/master/examples/jsonrpsee_example)\n+ [Loco Example](https://github.com/SeaQL/sea-orm/tree/master/examples/loco_example) / [Loco REST Starter](https://github.com/SeaQL/sea-orm/tree/master/examples/loco_starter)\n+ [Poem Example](https://github.com/SeaQL/sea-orm/tree/master/examples/poem_example)\n+ [Rocket Example](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_example) / [Rocket OpenAPI Example](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_okapi_example)\n+ [Salvo Example](https://github.com/SeaQL/sea-orm/tree/master/examples/salvo_example)\n+ [Tonic Example](https://github.com/SeaQL/sea-orm/tree/master/examples/tonic_example)\n+ [Seaography Example (Bakery)](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) / [Seaography Example (Sakila)](https://github.com/SeaQL/seaography/tree/main/examples/sqlite)\n\nIf you want a simple, clean example that fits in a single file that demonstrates the best of SeaORM, you can try:\n+ [Quickstart](https://github.com/SeaQL/sea-orm/blob/master/examples/quickstart/src/main.rs)\n\nLet's have a quick walk through of the unique features of SeaORM.\n\n## Expressive Entity format\nYou don't have to write this by hand! Entity files can be generated from an existing database using `sea-orm-cli`,\nfollowing is generated with `--entity-format dense` *(new in 2.0)*.\n```rust\nmod user {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"user\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n        #[sea_orm(unique)]\n        pub email: String,\n        #[sea_orm(has_one)]\n        pub profile: HasOne<super::profile::Entity>,\n        #[sea_orm(has_many)]\n        pub posts: HasMany<super::post::Entity>,\n    }\n}\nmod post {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"post\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub user_id: i32,\n        pub title: String,\n        #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n        pub author: HasOne<super::user::Entity>,\n        #[sea_orm(has_many, via = \"post_tag\")] // M-N relation with junction\n        pub tags: HasMany<super::tag::Entity>,\n    }\n}\n```\n\n## Smart Entity Loader\nThe Entity Loader intelligently uses join for 1-1 and data loader for 1-N relations,\neliminating the N+1 problem even when performing nested queries.\n```rust\n// join paths:\n// user -> profile\n// user -> post\n//         post -> post_tag -> tag\nlet smart_user = user::Entity::load()\n    .filter_by_id(42) // shorthand for .filter(user::COLUMN.id.eq(42))\n    .with(profile::Entity) // 1-1 uses join\n    .with((post::Entity, tag::Entity)) // 1-N uses data loader\n    .one(db)\n    .await?\n    .unwrap();\n\n// 3 queries are executed under the hood:\n// 1. SELECT FROM user JOIN profile WHERE id = $\n// 2. SELECT FROM post WHERE user_id IN (..)\n// 3. SELECT FROM tag JOIN post_tag WHERE post_id IN (..)\n\nsmart_user\n    == user::ModelEx {\n        id: 42,\n        name: \"Bob\".into(),\n        email: \"bob@sea-ql.org\".into(),\n        profile: HasOne::Loaded(\n            profile::ModelEx {\n                picture: \"image.jpg\".into(),\n            }\n            .into(),\n        ),\n        posts: HasMany::Loaded(vec![post::ModelEx {\n            title: \"Nice weather\".into(),\n            tags: HasMany::Loaded(vec![tag::ModelEx {\n                tag: \"sunny\".into(),\n            }]),\n        }]),\n    };\n```\n\n## ActiveModel: nested persistence made simple\nPersist an entire object graph: user, profile (1-1), posts (1-N), and tags (M-N)\nin a single operation using a fluent builder API. SeaORM automatically determines\nthe dependencies and inserts or deletes objects in the correct order.\n\n```rust\n// this creates the nested object as shown above:\nlet user = user::ActiveModel::builder()\n    .set_name(\"Bob\")\n    .set_email(\"bob@sea-ql.org\")\n    .set_profile(profile::ActiveModel::builder().set_picture(\"image.jpg\"))\n    .add_post(\n        post::ActiveModel::builder()\n            .set_title(\"Nice weather\")\n            .add_tag(tag::ActiveModel::builder().set_tag(\"sunny\")),\n    )\n    .save(db)\n    .await?;\n```\n\n## Schema first or Entity first? Your choice\n\nSeaORM provides a powerful migration system that lets you create tables, modify schemas, and seed data with ease.\n\nWith SeaORM 2.0, you also get a first-class [Entity First Workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/):\nsimply define new entities or add columns to existing ones,\nand SeaORM will automatically detect the changes and create the new tables, columns, unique keys, and foreign keys.\n\n```rust\n// SeaORM resolves foreign key dependencies and creates the tables in topological order.\n// Requires the `entity-registry` and `schema-sync` feature flags.\ndb.get_schema_registry(\"my_crate::entity::*\").sync(db).await;\n```\n\n## Ergonomic Raw SQL\n\nLet SeaORM handle 95% of your transactional queries.\nFor the remaining cases that are too complex to express,\nSeaORM still offers convenient support for writing raw SQL.\n```rust\nlet user = Item { name: \"Bob\" }; // nested parameter access\nlet ids = [2, 3, 4]; // expanded by the `..` operator\n\nlet user: Option<user::Model> = user::Entity::find()\n    .from_raw_sql(raw_sql!(\n        Sqlite,\n        r#\"SELECT \"id\", \"name\" FROM \"user\"\n           WHERE \"name\" LIKE {user.name}\n           AND \"id\" in ({..ids})\n        \"#\n    ))\n    .one(db)\n    .await?;\n```\n\n## Synchronous Support\n\n[`sea-orm-sync`](https://crates.io/crates/sea-orm-sync) provides the full SeaORM API without requiring an async runtime, making it ideal for lightweight CLI programs with SQLite.\n\nSee the [quickstart example](https://github.com/SeaQL/sea-orm/blob/master/sea-orm-sync/examples/quickstart/src/main.rs) for usage.\n\n## Basics\n\n### Select\nSeaORM models 1-N and M-N relationships at the Entity level,\nletting you traverse many-to-many links through a junction table in a single call.\n```rust\n// find all models\nlet cakes: Vec<cake::Model> = Cake::find().all(db).await?;\n\n// find and filter\nlet chocolate: Vec<cake::Model> = Cake::find()\n    .filter(Cake::COLUMN.name.contains(\"chocolate\"))\n    .all(db)\n    .await?;\n\n// find one model\nlet cheese: Option<cake::Model> = Cake::find_by_id(1).one(db).await?;\nlet cheese: cake::Model = cheese.unwrap();\n\n// find related models (lazy)\nlet fruit: Option<fruit::Model> = cheese.find_related(Fruit).one(db).await?;\n\n// find related models (eager): for 1-1 relations\nlet cake_with_fruit: Vec<(cake::Model, Option<fruit::Model>)> =\n    Cake::find().find_also_related(Fruit).all(db).await?;\n\n// find related models (eager): works for both 1-N and M-N relations\nlet cake_with_fillings: Vec<(cake::Model, Vec<filling::Model>)> = Cake::find()\n    .find_with_related(Filling) // for M-N relations, two joins are performed\n    .all(db) // rows are automatically consolidated by left entity\n    .await?;\n```\n### Nested Select\n\nPartial models prevent overfetching by letting you querying only the fields\nyou need; it also makes writing deeply nested relational queries simple.\n```rust\nuse sea_orm::DerivePartialModel;\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"cake::Entity\")]\nstruct CakeWithFruit {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    fruit: Option<fruit::Model>, // this can be a regular or another partial model\n}\n\nlet cakes: Vec<CakeWithFruit> = Cake::find()\n    .left_join(fruit::Entity) // no need to specify join condition\n    .into_partial_model() // only the columns in the partial model will be selected\n    .all(db)\n    .await?;\n```\n\n### Insert\nSeaORM's ActiveModel lets you work directly with Rust data structures and\npersist them through a simple API.\nIt's easy to insert large batches of rows from different data sources.\n```rust\nlet apple = fruit::ActiveModel {\n    name: Set(\"Apple\".to_owned()),\n    ..Default::default() // no need to set primary key\n};\n\nlet pear = fruit::ActiveModel {\n    name: Set(\"Pear\".to_owned()),\n    ..Default::default()\n};\n\n// insert one: Active Record style\nlet apple = apple.insert(db).await?;\napple.id == 1;\n\n// insert one: repository style\nlet result = Fruit::insert(apple).exec(db).await?;\nresult.last_insert_id == 1;\n\n// insert many returning last insert id\nlet result = Fruit::insert_many([apple, pear]).exec(db).await?;\nresult.last_insert_id == Some(2);\n```\n\n### Insert (advanced)\nYou can take advantage of database specific features to perform upsert and idempotent insert.\n```rust\n// insert many with returning (if supported by database)\nlet models: Vec<fruit::Model> = Fruit::insert_many([apple, pear])\n    .exec_with_returning(db)\n    .await?;\nmodels[0]\n    == fruit::Model {\n        id: 1, // database assigned value\n        name: \"Apple\".to_owned(),\n        cake_id: None,\n    };\n\n// insert with ON CONFLICT on primary key do nothing, with MySQL specific polyfill\nlet result = Fruit::insert_many([apple, pear])\n    .on_conflict_do_nothing()\n    .exec(db)\n    .await?;\n\nmatches!(result, TryInsertResult::Conflicted);\n```\n\n### Update\nActiveModel avoids race conditions by updating only the fields you've changed,\nnever overwriting untouched columns.\nYou can also craft complex bulk update queries with a fluent query building API.\n```rust\nuse sea_orm::sea_query::{Expr, Value};\n\nlet pear: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;\nlet mut pear: fruit::ActiveModel = pear.unwrap().into();\n\npear.name = Set(\"Sweet pear\".to_owned()); // update value of a single field\n\n// update one: only changed columns will be updated\nlet pear: fruit::Model = pear.update(db).await?;\n\n// update many: UPDATE \"fruit\" SET \"cake_id\" = \"cake_id\" + 2\n//               WHERE \"fruit\".\"name\" LIKE '%Apple%'\nFruit::update_many()\n    .col_expr(fruit::COLUMN.cake_id, fruit::COLUMN.cake_id.add(2))\n    .filter(fruit::COLUMN.name.contains(\"Apple\"))\n    .exec(db)\n    .await?;\n```\n### Save\nYou can perform \"insert or update\" operation with ActiveModel, making it easy to compose transactional operations.\n```rust\nlet banana = fruit::ActiveModel {\n    id: NotSet,\n    name: Set(\"Banana\".to_owned()),\n    ..Default::default()\n};\n\n// create, because primary key `id` is `NotSet`\nlet mut banana = banana.save(db).await?;\n\nbanana.id == Unchanged(2);\nbanana.name = Set(\"Banana Mongo\".to_owned());\n\n// update, because primary key `id` is present\nlet banana = banana.save(db).await?;\n```\n### Delete\nThe same ActiveModel API consistent with insert and update.\n```rust\n// delete one: Active Record style\nlet orange: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;\nlet orange: fruit::Model = orange.unwrap();\norange.delete(db).await?;\n\n// delete one: repository style\nlet orange = fruit::ActiveModel {\n    id: Set(2),\n    ..Default::default()\n};\nfruit::Entity::delete(orange).exec(db).await?;\n\n// delete many: DELETE FROM \"fruit\" WHERE \"fruit\".\"name\" LIKE '%Orange%'\nfruit::Entity::delete_many()\n    .filter(fruit::COLUMN.name.contains(\"Orange\"))\n    .exec(db)\n    .await?;\n\n```\n### Raw SQL Query\nThe `raw_sql!` macro is like the `format!` macro but without the risk of SQL injection.\nIt supports nested parameter interpolation, array and tuple expansion, and even repeating group,\noffering great flexibility in crafting complex queries.\n\n```rust\n#[derive(FromQueryResult)]\nstruct CakeWithBakery {\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<Bakery>,\n}\n\n#[derive(FromQueryResult)]\nstruct Bakery {\n    #[sea_orm(alias = \"bakery_name\")]\n    name: String,\n}\n\nlet cake_ids = [2, 3, 4]; // expanded by the `..` operator\n\n// can use many APIs with raw SQL, including nested select\nlet cake: Option<CakeWithBakery> = CakeWithBakery::find_by_statement(raw_sql!(\n    Sqlite,\n    r#\"SELECT \"cake\".\"name\", \"bakery\".\"name\" AS \"bakery_name\"\n       FROM \"cake\"\n       LEFT JOIN \"bakery\" ON \"cake\".\"bakery_id\" = \"bakery\".\"id\"\n       WHERE \"cake\".\"id\" IN ({..cake_ids})\"#\n))\n.one(db)\n.await?;\n```\n\n## 🧭 Seaography: instant GraphQL API\n\n[Seaography](https://github.com/SeaQL/seaography) is a GraphQL framework built for SeaORM.\nSeaography allows you to build GraphQL resolvers quickly.\nWith just a few commands, you can launch a fullly-featured GraphQL server from SeaORM entities,\ncomplete with filter, pagination, relational queries and mutations!\n\nLook at the [Seaography Example](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) to learn more.\n\n<img src=\"https://raw.githubusercontent.com/SeaQL/sea-orm/master/examples/seaography_example/Seaography%20example.png\"/>\n\n## 🖥️ SeaORM Pro: Professional Admin Panel\n\n[SeaORM Pro](https://github.com/SeaQL/sea-orm-pro/) is an admin panel solution allowing you to quickly and easily launch an admin panel for your application - frontend development skills not required, but certainly nice to have!\n\nSeaORM Pro has been updated to support the latest features in SeaORM 2.0.\n\nFeatures:\n\n+ Full CRUD\n+ Built on React + GraphQL\n+ Built-in GraphQL resolver\n+ Customize the UI with TOML config\n+ Role Based Access Control *(new in 2.0)*\n\nRead the [Getting Started](https://www.sea-ql.org/sea-orm-pro/docs/install-and-config/getting-started/) guide to learn more.\n\n![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-dark.png#gh-dark-mode-only)\n![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-light.png#gh-light-mode-only)\n\n## SQL Server Support\n\n[SQL Server for SeaORM](https://www.sea-ql.org/SeaORM-X/) offers the same SeaORM API for MSSQL. We ported all test cases and examples, complemented by MSSQL specific documentation. If you are building enterprise software, you can [request commercial access](https://forms.office.com/r/1MuRPJmYBR). It is currently based on SeaORM 1.0, but we will offer free upgrade to existing users when SeaORM 2.0 is finalized.\n\n## Releases\n\nSeaORM 2.0 has reached its release candidate phase. We'd love for you to try it out and help shape the final release by [sharing your feedback](https://github.com/SeaQL/sea-orm/discussions/).\n\n+ [Change Log](https://github.com/SeaQL/sea-orm/tree/master/CHANGELOG.md)\n\nSeaORM 2.0 is shaping up to be our most significant release yet - with a few breaking changes, plenty of enhancements, and a clear focus on developer experience.\n\n+ [A Sneak Peek at SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-16-sea-orm-2.0/)\n+ [SeaORM 2.0: A closer look](https://www.sea-ql.org/blog/2025-09-24-sea-orm-2.0/)\n+ [Role Based Access Control in SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-30-sea-orm-rbac/)\n+ [Seaography 2.0: A Powerful and Extensible GraphQL Framework](https://www.sea-ql.org/blog/2025-10-08-seaography/)\n+ [SeaORM 2.0: New Entity Format](https://www.sea-ql.org/blog/2025-10-20-sea-orm-2.0/)\n+ [SeaORM 2.0: Entity First Workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/)\n+ [SeaORM 2.0: Strongly-Typed Column](https://www.sea-ql.org/blog/2025-11-11-sea-orm-2.0/)\n+ [What's new in SeaORM Pro 2.0](https://www.sea-ql.org/blog/2025-11-21-whats-new-in-seaormpro-2.0/)\n+ [SeaORM 2.0: Nested ActiveModel](https://www.sea-ql.org/blog/2025-11-25-sea-orm-2.0/)\n+ [A walk-through of SeaORM 2.0](https://www.sea-ql.org/blog/2025-12-05-sea-orm-2.0/)\n+ [How we made SeaORM synchronous](https://www.sea-ql.org/blog/2025-12-12-sea-orm-2.0/)\n+ [SeaORM 2.0 Migration Guide](https://www.sea-ql.org/blog/2026-01-12-sea-orm-2.0/)\n+ [SeaORM now supports Arrow & Parquet](https://www.sea-ql.org/blog/2026-02-22-sea-orm-arrow/)\n+ [SeaORM 2.0 with SQL Server Support](https://www.sea-ql.org/blog/2026-02-25-sea-orm-x/)\n\nIf you make extensive use of SeaQuery, we recommend checking out our blog post on SeaQuery 1.0 release:\n\n+ [The road to SeaQuery 1.0](https://www.sea-ql.org/blog/2025-08-30-sea-query-1.0/)\n\n## License\n\nLicensed under either of\n\n-   Apache License, Version 2.0\n    ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)\n-   MIT license\n    ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)\n\nat your option.\n\n## Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n\nWe invite you to participate, contribute and together help build Rust's future.\n\nA big shout out to our contributors!\n\n[![Contributors](https://opencollective.com/sea-orm/contributors.svg?width=1000&button=false)](https://github.com/SeaQL/sea-orm/graphs/contributors)\n\n## Who's using SeaORM?\n\nHere is a short list of awesome open source software built with SeaORM. Feel free to [submit yours](https://github.com/SeaQL/sea-orm/blob/master/COMMUNITY.md#built-with-seaorm)!\n\n| Project | GitHub | Tagline |\n|---------|--------|---------|\n| [Zed](https://github.com/zed-industries/zed) | ![GitHub stars](https://img.shields.io/github/stars/zed-industries/zed.svg?style=social) | A high-performance, multiplayer code editor |\n| [OpenObserve](https://github.com/openobserve/openobserve) | ![GitHub stars](https://img.shields.io/github/stars/openobserve/openobserve.svg?style=social) | Open-source observability platform |\n| [RisingWave](https://github.com/risingwavelabs/risingwave) | ![GitHub stars](https://img.shields.io/github/stars/risingwavelabs/risingwave.svg?style=social) | Stream processing and management platform |\n| [LLDAP](https://github.com/nitnelave/lldap) | ![GitHub stars](https://img.shields.io/github/stars/nitnelave/lldap.svg?style=social) | A light LDAP server for user management |\n| [Warpgate](https://github.com/warp-tech/warpgate) | ![GitHub stars](https://img.shields.io/github/stars/warp-tech/warpgate.svg?style=social) | Smart SSH bastion that works with any SSH client |\n| [Svix](https://github.com/svix/svix-webhooks) | ![GitHub stars](https://img.shields.io/github/stars/svix/svix-webhooks.svg?style=social) | The enterprise ready webhooks service |\n| [Ryot](https://github.com/IgnisDa/ryot) | ![GitHub stars](https://img.shields.io/github/stars/ignisda/ryot.svg?style=social) | The only self hosted tracker you will ever need |\n| [Lapdev](https://github.com/lapce/lapdev) | ![GitHub stars](https://img.shields.io/github/stars/lapce/lapdev.svg?style=social) | Self-hosted remote development enviroment |\n| [System Initiative](https://github.com/systeminit/si) | ![GitHub stars](https://img.shields.io/github/stars/systeminit/si.svg?style=social) | DevOps Automation Platform |\n| [OctoBase](https://github.com/toeverything/OctoBase) | ![GitHub stars](https://img.shields.io/github/stars/toeverything/OctoBase.svg?style=social) | A light-weight, scalable, offline collaborative data backend |\n\n## Sponsorship\n\n[SeaQL.org](https://www.sea-ql.org/) is an independent open-source organization run by passionate developers.\nIf you feel generous, a small donation via [GitHub Sponsor](https://github.com/sponsors/SeaQL) will be greatly appreciated, and goes a long way towards sustaining the organization.\n\n### Gold Sponsors\n\n<table><tr>\n<td><a href=\"https://qdx.co/\">\n  <img src=\"https://www.sea-ql.org/static/sponsors/QDX.svg\" width=\"138\"/>\n</a></td>\n</tr></table>\n\n[QDX](https://qdx.co/) pioneers quantum dynamics-powered drug discovery, leveraging AI and supercomputing to accelerate molecular modeling.\nWe're immensely grateful to QDX for sponsoring the development of SeaORM, the SQL toolkit that powers their data intensive applications.\n\n### Silver Sponsors\n\nWe're grateful to our silver sponsors: Digital Ocean, for sponsoring our servers. And JetBrains, for sponsoring our IDE.\n\n<table><tr>\n<td><a href=\"https://www.digitalocean.com/\">\n  <img src=\"https://www.sea-ql.org/static/sponsors/DigitalOcean.svg\" width=\"125\">\n</a></td>\n\n<td><a href=\"https://www.jetbrains.com/\">\n  <img src=\"https://www.sea-ql.org/static/sponsors/JetBrains.svg\" width=\"125\">\n</a></td>\n</tr></table>\n\n## Mascot\n\nA friend of Ferris, Terres the hermit crab is the official mascot of SeaORM. His hobby is collecting shells.\n\n<img alt=\"Terres\" src=\"https://www.sea-ql.org/SeaORM/img/Terres.png\" width=\"400\"/>\n\n## 🦀 Rustacean Sticker Pack\nThe Rustacean Sticker Pack is the perfect way to express your passion for Rust. Our stickers are made with a premium water-resistant vinyl with a unique matte finish.\n\nSticker Pack Contents:\n\n+ Logo of SeaQL projects: SeaQL, SeaORM, SeaQuery, Seaography\n+ Mascots: Ferris the Crab x 3, Terres the Hermit Crab\n+ The Rustacean wordmark\n\n[Support SeaQL and get a Sticker Pack!](https://www.sea-ql.org/sticker-pack/) All proceeds contributes directly to the ongoing development of SeaQL projects.\n\n<a href=\"https://www.sea-ql.org/sticker-pack/\"><img alt=\"Rustacean Sticker Pack by SeaQL\" src=\"https://www.sea-ql.org/static/sticker-pack-1s.jpg\" width=\"600\"/></a>\n"
  },
  {
    "path": "VERSIONS.md",
    "content": "# Known good version combo\n\nsea-orm      sea-query    sea-query-derive  sea-query-sqlx    sea-schema\n2.0.0-rc.1   1.0.0-rc.6   1.0.0-rc.5        sea-query-binder  0.17.0-rc.3\n2.0.0-rc.4   1.0.0-rc.12  1.0.0-rc.9        0.8.0-rc.8        0.17.0-rc.6\n2.0.0-rc.9   1.0.0-rc.14  1.0.0-rc.9        0.8.0-rc.9        0.17.0-rc.8\n2.0.0-rc.24  1.0.0-rc.27  1.0.0-rc.11       0.8.0-rc.10       0.17.0-rc.17\n2.0.0-rc.27  1.0.0-rc.29  1.0.0-rc.11       0.8.0-rc.11       0.17.0-rc.17"
  },
  {
    "path": "build-tools/back-async.rs",
    "content": "cp sea-orm-sync/src/driver/rusqlite.rs ./src/driver/"
  },
  {
    "path": "build-tools/bump.sh",
    "content": "#!/bin/bash\nset -e\n\n# Bump `sea-orm-codegen` version\ncd sea-orm-codegen\nsed -i 's/^version.*$/version       = \"'$1'\"/' Cargo.toml\ncd ..\n\n# Bump `sea-orm-cli` version\ncd sea-orm-cli\nsed -i 's/^version.*$/version = \"'$1'\"/' Cargo.toml\nsed -i 's/^sea-orm-codegen [^,]*,/sea-orm-codegen = { version = \"\\='$1'\",/' Cargo.toml\ncd ..\n\n# Bump `sea-orm-macros` version\ncd sea-orm-macros\nsed -i 's/^version.*$/version       = \"'$1'\"/' Cargo.toml\ncd ..\n\n# Bump `sea-orm` version\nsed -i 's/^version.*$/version       = \"'$1'\"/' Cargo.toml\nsed -i 's/^sea-orm-macros [^,]*,/sea-orm-macros = { version = \"'~$1'\",/' Cargo.toml\n\n# Bump `sea-orm-migration` version\ncd sea-orm-migration\nsed -i 's/^version.*$/version       = \"'$1'\"/' Cargo.toml\nsed -i 's/^sea-orm-cli [^,]*,/sea-orm-cli = { version = \"'~$1'\",/' Cargo.toml\nsed -i 's/^sea-orm [^,]*,/sea-orm = { version = \"'~$1'\",/' Cargo.toml\ncd ..\n\n# Bump `sea-orm-sync` version\ncd sea-orm-sync\nsed -i 's/^version.*$/version       = \"'$1'\"/' Cargo.toml\ncd ..\n\ngit commit -am \"$1\"\n\n# Bump examples' dependency version\ncd examples\nfind . -depth -type f -name '*.toml' -exec sed -i 's/^version = \".*\" # sea-orm version$/version = \"'~$1'\" # sea-orm version/' {} \\;\nfind . -depth -type f -name '*.toml' -exec sed -i 's/^version = \".*\" # sea-orm-migration version$/version = \"'~$1'\" # sea-orm-migration version/' {} \\;\ngit add .\ngit commit -m \"update examples\""
  },
  {
    "path": "build-tools/clean.sh",
    "content": "#!/bin/bash\nset -x\n\nfor dir in */; do\n    cd \"$dir\";\n    cargo clean;\n    cd ..;\ndone"
  },
  {
    "path": "build-tools/del-rel-dep.sh",
    "content": "#!/bin/bash\nset -e\n\nfind examples/ -depth -type f -name '*.toml' -exec sed -i '/^path = \"..\\/..\\/..\\/sea-orm-migration\"/d' {} \\;\nfind examples/ -depth -type f -name '*.toml' -exec sed -i '/^path = \"..\\/..\\/..\\/\"/d' {} \\;"
  },
  {
    "path": "build-tools/docker-compose.yml",
    "content": "version: \"3\"\n\nservices:\n    # \n    # MariaDB\n    # \n\n    mariadb_10_6:\n        image: mariadb:10.6\n        ports:\n            - 3306\n        environment:\n            MYSQL_DB: mysql\n            MYSQL_USER: sea\n            MYSQL_PASSWORD: sea\n            MYSQL_ALLOW_EMPTY_PASSWORD: yes\n            MYSQL_ROOT_PASSWORD: root\n\n    mariadb_10_5:\n        image: mariadb:10.5\n        ports:\n            - 3306\n        environment:\n            MYSQL_DB: mysql\n            MYSQL_USER: sea\n            MYSQL_PASSWORD: sea\n            MYSQL_ALLOW_EMPTY_PASSWORD: yes\n            MYSQL_ROOT_PASSWORD: root\n\n    mariadb_10_4:\n        image: mariadb:10.4\n        ports:\n            - 3306\n        environment:\n            MYSQL_DB: mysql\n            MYSQL_USER: sea\n            MYSQL_PASSWORD: sea\n            MYSQL_ALLOW_EMPTY_PASSWORD: yes\n            MYSQL_ROOT_PASSWORD: root\n\n    # \n    # MySQL\n    # \n\n    mysql_8_0:\n        image: mysql:8.0\n        ports:\n            - 3306\n        environment:\n            MYSQL_DB: mysql\n            MYSQL_USER: sea\n            MYSQL_PASSWORD: sea\n            MYSQL_ALLOW_EMPTY_PASSWORD: yes\n            MYSQL_ROOT_PASSWORD: root\n\n    mysql_5_7:\n        image: mysql:5.7\n        ports:\n            - 3306\n        environment:\n            MYSQL_DB: mysql\n            MYSQL_USER: sea\n            MYSQL_PASSWORD: sea\n            MYSQL_ALLOW_EMPTY_PASSWORD: yes\n            MYSQL_ROOT_PASSWORD: root\n\n    # \n    # PostgreSQL\n    # \n\n    postgres_13:\n        image: postgres:13\n        ports:\n            - 5432\n        environment:\n            POSTGRES_USER: root\n            POSTGRES_PASSWORD: root\n\n    postgres_12:\n        image: postgres:12\n        ports:\n            - 5432\n        environment:\n            POSTGRES_USER: root\n            POSTGRES_PASSWORD: root\n\n    postgres_11:\n        image: postgres:11\n        ports:\n            - 5432\n        environment:\n            POSTGRES_USER: root\n            POSTGRES_PASSWORD: root\n"
  },
  {
    "path": "build-tools/docker-create.sh",
    "content": "# Some Common Docker Commands You Might Need (use with caution)\n# \n# Delete all containers\n# $ docker rm -f $(docker ps -a -q)\n# \n# Delete all volumes\n# $ docker volume rm $(docker volume ls -q)\n# \n# Delete all images\n# $ docker image rm $(docker image ls -q)\n\n# Setup MariaDB\n\ndocker run \\\n    --name \"mariadb-10.6\" \\\n    --env MYSQL_DB=\"mysql\" \\\n    --env MYSQL_USER=\"sea\" \\\n    --env MYSQL_PASSWORD=\"sea\" \\\n    --env MYSQL_ALLOW_EMPTY_PASSWORD=\"yes\" \\\n    --env MYSQL_ROOT_PASSWORD=\"root\" \\\n    -d -p 3306:3306 mariadb:10.6\ndocker stop \"mariadb-10.6\"\n\ndocker run \\\n    --name \"mariadb-10.5\" \\\n    --env MYSQL_DB=\"mysql\" \\\n    --env MYSQL_USER=\"sea\" \\\n    --env MYSQL_PASSWORD=\"sea\" \\\n    --env MYSQL_ALLOW_EMPTY_PASSWORD=\"yes\" \\\n    --env MYSQL_ROOT_PASSWORD=\"root\" \\\n    -d -p 3306:3306 mariadb:10.5\ndocker stop \"mariadb-10.5\"\n\ndocker run \\\n    --name \"mariadb-10.4\" \\\n    --env MYSQL_DB=\"mysql\" \\\n    --env MYSQL_USER=\"sea\" \\\n    --env MYSQL_PASSWORD=\"sea\" \\\n    --env MYSQL_ALLOW_EMPTY_PASSWORD=\"yes\" \\\n    --env MYSQL_ROOT_PASSWORD=\"root\" \\\n    -d -p 3306:3306 mariadb:10.4\ndocker stop \"mariadb-10.4\"\n\n# Setup MySQL\n\ndocker run \\\n    --name \"mysql-8.0\" \\\n    --env MYSQL_DB=\"mysql\" \\\n    --env MYSQL_USER=\"sea\" \\\n    --env MYSQL_PASSWORD=\"sea\" \\\n    --env MYSQL_ALLOW_EMPTY_PASSWORD=\"yes\" \\\n    --env MYSQL_ROOT_PASSWORD=\"root\" \\\n    -d -p 3306:3306 mysql:8.0\ndocker stop \"mysql-8.0\"\n\ndocker run \\\n    --name \"mysql-5.7\" \\\n    --env MYSQL_DB=\"mysql\" \\\n    --env MYSQL_USER=\"sea\" \\\n    --env MYSQL_PASSWORD=\"sea\" \\\n    --env MYSQL_ALLOW_EMPTY_PASSWORD=\"yes\" \\\n    --env MYSQL_ROOT_PASSWORD=\"root\" \\\n    -d -p 3306:3306 mysql:5.7\ndocker stop \"mysql-5.7\"\n\n# Setup PostgreSQL\n\ndocker run \\\n    --name \"postgres-vector-14\" \\\n    --env POSTGRES_USER=\"sea\" \\\n    --env POSTGRES_PASSWORD=\"sea\" \\\n    -d -p 5432:5432 pgvector/pgvector:pg14\ndocker stop \"postgres-vector-14\"\n\ndocker run \\\n    --name \"postgres-14\" \\\n    --env POSTGRES_USER=\"sea\" \\\n    --env POSTGRES_PASSWORD=\"sea\" \\\n    -d -p 5432:5432 postgres:14\ndocker stop \"postgres-14\"\n\ndocker run \\\n    --name \"postgres-13\" \\\n    --env POSTGRES_USER=\"sea\" \\\n    --env POSTGRES_PASSWORD=\"sea\" \\\n    -d -p 5432:5432 postgres:13\ndocker stop \"postgres-13\"\n\ndocker run \\\n    --name \"postgres-12\" \\\n    --env POSTGRES_USER=\"sea\" \\\n    --env POSTGRES_PASSWORD=\"sea\" \\\n    -d -p 5432:5432 postgres:12\ndocker stop \"postgres-12\"\n\ndocker run \\\n    --name \"postgres-11\" \\\n    --env POSTGRES_USER=\"sea\" \\\n    --env POSTGRES_PASSWORD=\"sea\" \\\n    -d -p 5432:5432 postgres:11\ndocker stop \"postgres-11\"\n"
  },
  {
    "path": "build-tools/make-sync.sh",
    "content": "rm -rf sea-orm-sync/src\nrm -rf sea-orm-sync/tests\ncp -r src sea-orm-sync\ncp -r tests sea-orm-sync\ncp -r examples/quickstart/src/main.rs sea-orm-sync/examples/quickstart/src/main.rs\nrm -rf sea-orm-sync/src/bin\ncd sea-orm-sync\nfind src -type f -name '*.rs' -exec sed -i '' \"s/Pin<Box<dyn Future<Output = Result<Self::Stream<'a>, DbErr>> + 'a + Send>>/Result<Self::Stream<'a>, DbErr>/\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"s/Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'b>>/Result<T, E>/\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"s/Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>/Result<T, E>/\" {} +\nfind src   -type f -name '*.rs' -exec sed -i '' 's/Box::pin(async move {/({/' {} +\nfind tests -type f -name '*.rs' -exec sed -i '' 's/Box::pin(async move {/({/' {} +\nfind src   -type f -name '*.rs' -exec sed -i '' 's/async //' {} +\nfind tests -type f -name '*.rs' -exec sed -i '' 's/async //' {} +\nfind examples -type f -name '*.rs' -exec sed -i '' 's/async //' {} +\nfind src   -type f -name '*.rs' -exec sed -i '' 's/\\.await//' {} +\nfind tests -type f -name '*.rs' -exec sed -i '' 's/\\.await//' {} +\nfind examples -type f -name '*.rs' -exec sed -i '' 's/\\.await//' {} +\nfind src   -type f -name '*.rs' -exec sed -i '' '/#\\[async_trait::async_trait\\]/d' {} +\nfind tests -type f -name '*.rs' -exec sed -i '' '/#\\[async_trait::async_trait\\]/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/#\\[smol_potat::test\\]/#\\[test\\]/' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/#\\[smol_potat::main\\]/d' {} +\nfind examples -type f -name '*.rs' -exec sed -i '' '/#\\[tokio::main\\]/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/#\\[tokio::test\\]/#\\[test\\]/' {} +\nfind tests -type f -name '*.rs' -exec sed -i '' 's/#\\[cfg(feature = \"sqlx-sqlite\")\\]/#\\[cfg(feature = \"rusqlite\")\\]/' {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"/[a-zA-Z]+<Self>: Send + Sync,/d\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"/[a-zA-Z]+<Self>: Send,/d\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"s/: Send + Sync {/ {/\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"s/type Stream<'a>: Stream/type Stream<'a>: Iterator/\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"s/: Send {/ {/\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"s/>: Send$/>/\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"s/: Sync {/ {/\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"s/Send + Sync + //\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"s/ + Sync//\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"s/ + Send//\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"s/Send + //\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/Arc<dyn std::error::Error>/Arc<dyn std::error::Error + Send + Sync>/' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/T: Send,/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/R::Model: Send,/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/S::Item: Send,/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' \"s/Box::pin/Box::new/\" {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/impl Stream</impl Iterator</' {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/S: Stream</S: Iterator</' {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/use futures_util::lock::Mutex;/use std::sync::Mutex;/' {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/use futures_util::lock::MutexGuard;/use std::sync::MutexGuard;/' {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/, pin::Pin//' {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/{pin::Pin, /{/' {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/{task::Poll, /{/' {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/{future::Future, /{/' {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/, task::Poll//' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/use std::{pin::Pin};/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/use std::{task::Poll};/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/use std::{future::Future};/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/, future::Future//' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/use futures_util::Stream/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/use futures_util::{Stream/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/use futures_util::{TryStreamExt,/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/\\/\\/\\/ use futures_util/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/use futures_util::future::BoxFuture;/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' '/use async_stream::/d' {} +\nfind tests -type f -name '*.rs' -exec sed -i '' '/use futures_util::StreamExt/d' {} +\nfind src -type f -name '*.rs' -exec sed -i '' 's/self.conn.try_lock()/self.conn.try_lock().ok()/' {} +\nsed -i '' 's/self.conn.try_lock().ok()/self.conn.try_lock()/' ./src/driver/rusqlite.rs\ncargo fmt"
  },
  {
    "path": "build-tools/publish.sh",
    "content": "#!/bin/bash\nset -e\n\n# publish `sea-orm-codegen`\ncd sea-orm-codegen\ncargo publish\ncd ..\n\n# publish `sea-orm-cli`\ncd sea-orm-cli\ncargo publish\ncd ..\n\n# publish `sea-orm-macros`\ncd sea-orm-macros\ncargo publish\ncd ..\n\n# publish `sea-orm`\ncargo publish\n\n# publish `sea-orm-migration`\ncd sea-orm-migration\ncargo publish\ncd ..\n\n# publish `sea-orm-sync`\ncd sea-orm-sync\ncargo publish"
  },
  {
    "path": "build-tools/readme.sh",
    "content": "# Run `sh develop/cargo-readme.sh` on project root to generate `README.md` from `src/lib.rs`\n# cargo install cargo-readme\ncargo readme --no-badges --no-indent-headings --no-license --no-template --no-title > README.md\ncd sea-orm-sync && cargo readme --no-badges --no-indent-headings --no-license --no-template --no-title > README.md"
  },
  {
    "path": "build-tools/rustclippy.sh",
    "content": "#!/bin/bash\nset -e\nif [ -d ./build-tools ]; then\n    targets=(\n        \"Cargo.toml\"\n        \"sea-orm-cli/Cargo.toml\"\n        \"sea-orm-codegen/Cargo.toml\"\n        \"sea-orm-macros/Cargo.toml\"\n        \"sea-orm-migration/Cargo.toml\"\n        \"sea-orm-rocket/Cargo.toml\"\n    )\n\n    for target in \"${targets[@]}\"; do\n        echo \"cargo clippy --manifest-path ${target} --fix --allow-dirty --allow-staged\"\n        cargo clippy --manifest-path \"${target}\" --fix --allow-dirty --allow-staged\n    done\n\n    examples=(`find examples -type f -name 'Cargo.toml'`)\n    for example in \"${examples[@]}\"; do\n        echo \"cargo clippy --manifest-path ${example} --fix --allow-dirty --allow-staged\"\n        cargo clippy --manifest-path \"${example}\" --fix --allow-dirty --allow-staged\n    done\nelse\n    echo \"Please execute this script from the repository root.\"\nfi\n"
  },
  {
    "path": "build-tools/rustfmt.sh",
    "content": "#!/bin/bash\nset -e\ntaplo fmt\nif [ -d ./build-tools ]; then\n    targets=(\n        \"Cargo.toml\"\n        \"sea-orm-cli/Cargo.toml\"\n        \"sea-orm-codegen/Cargo.toml\"\n        \"sea-orm-macros/Cargo.toml\"\n        \"sea-orm-migration/Cargo.toml\"\n        \"sea-orm-rocket/Cargo.toml\"\n    )\n\n    for target in \"${targets[@]}\"; do\n        echo \"cargo +nightly fmt --manifest-path ${target} --all\"\n        cargo +nightly fmt --manifest-path \"${target}\" --all\n    done\n\n    examples=(`find examples -type f -name 'Cargo.toml'`)\n    for example in \"${examples[@]}\"; do\n        echo \"cargo +nightly fmt --manifest-path ${example} --all\"\n        cargo +nightly fmt --manifest-path \"${example}\" --all\n    done\n\n    slmd COMMUNITY.md -oi\nelse\n    echo \"Please execute this script from the repository root.\"\nfi\n"
  },
  {
    "path": "build-tools/update-strum-macros.sh",
    "content": "rm -rf sea-orm-macros/src/strum/helpers\nrm -rf sea-orm-macros/src/strum/enum_iter.rs\n\ncp -r ../strum/strum_macros/src/helpers sea-orm-macros/src/strum/helpers\ncp -r ../strum/strum_macros/src/macros/enum_iter.rs sea-orm-macros/src/strum/enum_iter.rs\n\nsed -i 's/crate::helpers::{*/super::helpers::{/' sea-orm-macros/src/strum/enum_iter.rs\nsed -i 's/parse_quote!(::strum)*/parse_quote!(sea_orm::strum)/' sea-orm-macros/src/strum/helpers/type_props.rs"
  },
  {
    "path": "changelog/2.0.0-rc.20.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.20\n\n*(since 2.0.0-rc.19)*\n\n### New Features\n\n**Allow more stringy newtypes in `DeriveValueType`** (#2831)\n\n- Produce syntax-aware attribute errors in `DeriveValueType` macro\n- Allow `value_type` attr for named field structs in `DeriveValueType`\n- Assume no derive attributes means `DeriveValueTypeStruct`\n\n**Many-to-many self-referencing relation** (#2823)\n\n- Add primary_key check to `DeriveEntityModel`\n- Support `RelatedSelfVia` and `self_ref` in dense entity format\n- Support `self_ref` on compact_model and in reverse\n- Loader support for self via in reverse\n\n**ActiveModelEx: support `self_ref`**\n\nActiveModelEx now supports self-referencing relations.\n\n**Add nullable column types**\n\nSupport for nullable column types added.\n\n### Bug Fixes\n\n**Fix missing casts when returning one** (#2825)\n\nFixed missing type casts when using `returning_one` / `returning_all`.\n\n**Temp fix MySQL JSON equals**\n\nWorkaround for MySQL JSON equality comparison issues.\n\n**Automatically convert `eq(None)` to `IS NULL`** (#2826)\n\n`eq(None)` is now correctly translated to `IS NULL` in SQL.\n\n**Fix compile error when postgres-vector is enabled** (#2821)\n\nResolved compilation failure with the `postgres-vector` feature.\n\n### Improvements\n\n- Entity Loader: move `EntityLoaderWithParam` trait to be owned by user for better blanket impl support\n- Built with SeaORM: Add FirstLook.gg (#2828)\n"
  },
  {
    "path": "changelog/2.0.0-rc.21.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.21\n\n*(since 2.0.0-rc.20)*\n\n### New Features\n\n**Rusqlite / sea-orm-sync** (#2847)\n\n- New `sea-orm-sync` crate for synchronous SQLite via rusqlite\n- Stream and transaction support\n- Integration with `sea-schema-sync`\n\n**Add `--banner-version` to CLI** (#2836)\n\nCLI now supports a `--banner-version` flag.\n\n**Add `exists` method to `PaginatorTrait`** (#2623)\n\n`PaginatorTrait` now includes an `exists` method for efficient existence checks.\n\n### Bug Fixes\n\n**Respect `#[serde(rename)]` in `ActiveModel::from_json`** (#2842)\n\n`ActiveModel::from_json` now correctly respects `#[serde(rename)]` and `#[serde(rename_all)]` attributes when deserializing JSON.\n\n### Improvements\n\n- Reduce Vec allocations (#2835)\n- Add taplo for TOML formatting (#2844)\n- SeaORM sync example and preparation for `sea-orm-sync` crate\n"
  },
  {
    "path": "changelog/2.0.0-rc.22.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.22\n\n*(since 2.0.0-rc.21)*\n\n### New Features\n\n**`DatabaseExecutor` unified executor type** (#2839)\n\nAdded a unified `DatabaseExecutor` type that wraps either a `&DatabaseConnection` or `&DatabaseTransaction`. This moves the `SchemaManagerConnection` pattern from `sea-orm-migration` into sea-orm core, providing:\n\n- `DatabaseExecutor` enum for unified handling of connections and transactions\n- `IntoDatabaseExecutor` trait for ergonomic conversions\n- `SchemaManagerConnection` type alias for backward compatibility\n- `SchemaManagerConnectionExt` trait for migration-specific methods\n\n### Bug Fixes\n\n*None in this release.*\n\n### Improvements\n\n**Refactor Value array** (#2849)\n\nRefactored the internal `Value` array handling for improved consistency and maintainability.\n\n**Refactor CI** (#2859)\n\n- Parallelized test compilation for faster CI runs\n- Updated `actions/cache` to v5\n- Fixed cache keys\n\n**sea-orm-sync example**\n\nAdded and improved the `sea-orm-sync` example.\n\n**Update examples**\n\nUpdated example code across the repository.\n"
  },
  {
    "path": "changelog/2.0.0-rc.23.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.23\n\n*(since 2.0.0-rc.22)*\n\n### New Features\n\n**`DeriveValueType` implements `IntoActiveValue`** (#2868)\n\n`DeriveValueType` now automatically implements `IntoActiveValue`, so custom value types can be used directly when building ActiveModels without additional boilerplate.\n\n**`IntoActiveValue` for more types**\n\n`IntoActiveValue` is now implemented for additional standard types, improving ergonomics when setting ActiveModel fields.\n\n### Bug Fixes\n\n**Fix sea-orm-sync**\n\nFixed issues in the `sea-orm-sync` crate.\n\n**Fix sync**\n\nFixed sync-related bugs.\n\n**Fix tests**\n\nResolved failing tests.\n\n**Insert many on conflict do nothing returning** (#2389)\n\nAdded test coverage and fixes for `insert_many` with `on_conflict_do_nothing` and `returning` clauses.\n\n### Improvements\n\n**Remove `NotU8` trait** (#2868)\n\nThe `NotU8` trait has been removed. `DeriveValueType` now handles type constraints internally, simplifying the derive macro.\n\n**Remove `bigdecimal` from default features**\n\nThe `bigdecimal` dependency is no longer included in default features, reducing the default dependency footprint. Enable it explicitly if needed.\n\n**CI improvements**\n\nVarious CI fixes and improvements.\n"
  },
  {
    "path": "changelog/2.0.0-rc.24.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.24\n\n*(since 2.0.0-rc.23)*\n\n### Improvements\n\n- Bumped `sea-query` to 1.0.0-rc.27\n- Updated example projects to use the new release\n"
  },
  {
    "path": "changelog/2.0.0-rc.25.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.25\n\n*(since 2.0.0-rc.24)*\n\n### Bug Fixes\n\n**Restore value system**\n\nRestored the value system across the core crate, drivers (MySQL, PostgreSQL, SQLite), and entity/column types. Refactored executor and query handling for consistency.\n\n**Fix sea-orm-sync**\n\nAligned `sea-orm-sync` with the restored value system changes in the main crate. Updated drivers, entity types, and executor/query logic to match.\n\n### Improvements\n\n- Bumped `sea-query` to 1.0.0-rc.28\n- Updated example projects to use the new release\n"
  },
  {
    "path": "changelog/2.0.0-rc.26.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.26\n\n*(since 2.0.0-rc.25)*\n\n### New Features\n\n**PostgreSQL legacy serial primary key option**\n\nAdded the `postgres-use-serial-pk` feature flag to use legacy `serial` / `bigserial` types for auto-increment primary keys instead of `GENERATED BY DEFAULT AS IDENTITY`. Enable with `postgres-use-serial-pk` in your `Cargo.toml` if you need compatibility with older PostgreSQL setups or tooling.\n"
  },
  {
    "path": "changelog/2.0.0-rc.27.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.27\n\n*(since 2.0.0-rc.26)*\n\n### Improvements\n\n**DeriveValueType implements NotU8**\n\n`DeriveValueType` now also implements `sea_query::postgres_array::NotU8`, enabling custom value types to work with PostgreSQL array columns. This is auto-generated when the `postgres-array` feature is enabled. Remove any manual `NotU8` implementations on your custom types to avoid conflicts.\n"
  },
  {
    "path": "changelog/2.0.0-rc.28.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.28\n\n*(since 2.0.0-rc.27)*\n\n### New Features\n\n**`sqlx-all` feature in sea-orm-migration** (#2887)\n\nAdded `sqlx-all` feature flag to `sea-orm-migration` for compatibility with sqlx's all-database feature.\n\n**`set_if_not_equals_and` on ActiveValue** (#2888)\n\nAdded `set_if_not_equals_and` method to `ActiveValue` for conditional updates based on value comparison.\n\n**Set auto_increment to false for String/Uuid primary keys by default** (#2881)\n\nMacros now set `auto_increment = false` by default when the primary key is `String` or `Uuid`, avoiding incorrect schema generation.\n\n### Bug Fixes\n\n**Postgres: combine SET TRANSACTION statements** (#2893)\n\nCombined `SET TRANSACTION ISOLATION LEVEL` and `ACCESS MODE` into a single statement for PostgreSQL, fixing transaction setup.\n\n### Improvements\n\n**Debug log for entity registry** (#2900)\n\nAdded debug logging for entity registry operations to aid troubleshooting.\n\n**Deprecate do_nothing and on_empty_do_nothing** (#2883)\n\nDeprecated `do_nothing` and `on_empty_do_nothing` on insert operations. Added documentation and tests for the deprecation path.\n\n**Add Rustify to COMMUNITY.md** (#2898)\n\nAdded Rustify bot to the community bots section, covering multi-source lyrics, AI analysis, real-time profanity detection, and auto-skip features.\n"
  },
  {
    "path": "changelog/2.0.0-rc.29.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.29\n\n*(since 2.0.0-rc.28)*\n\n### New Features\n\n**Tracing spans for database operations** (#2885)\n\nAdded `ObservabilityHook` and `with_db_span!` macro for distributed tracing support. Database operations and transactions emit tracing spans when the `tracing-spans` feature is enabled.\n\n**Wrapper type for storing UUIDs as TEXT** (#2914)\n\nAdded a wrapper type for storing `Uuid` values as TEXT columns.\n\n**`Insert::try_insert` method**\n\nAdded `try_insert` to the `Insert` trait for fallible insert operations.\n\n**Filter relations outside generation set** (#2913)\n\nCodegen now filters relations that fall outside the generation set.\n\n### Bug Fixes\n\n**Allow LEFT JOIN to produce None for nested models** (#2845)\n\nFixed handling of nested `Option<Model>` in `FromQueryResult` when using LEFT JOINs, so optional nested models correctly produce `None` when no related row exists.\n\n**Fix DeriveIntoActiveModel** (#2926)\n\nFixed `DeriveIntoActiveModel` derive macro; added test coverage.\n\n**Fix tracing spans visibility** (#2925)\n\nCorrected tracing span visibility for database operations.\n\n**Fix derive enums without per-case rename** (#2922)\n\nFixed codegen for enums that do not use per-variant `rename` attributes. Addresses [#2921](https://github.com/SeaQL/sea-orm/issues/2921).\n\n**Fix renaming enum variants starting with digits** (#2905)\n\nEnum variants that start with digits are now correctly renamed during codegen.\n\n**Revert multi-argument extra attribute support** (#2915)\n\nReverted the multi-argument extra attribute codegen change (#2560) due to incorrect test input parsing that caused `syn` to panic. The attribute format should split arguments by `,`.\n\n**Add missing lifetime hint to `EntityName::table_name`** (#2907)\n\nAdded the missing lifetime hint to fix compilation in certain contexts.\n\n### Improvements\n\n**Optimize exists** (#2909)\n\nImproved performance of the `exists` query.\n"
  },
  {
    "path": "changelog/2.0.0-rc.30.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.30\n\n*(since 2.0.0-rc.29)*\n\n### Improvements\n\n**Dependency updates**\n\nBumped `sea-query` dependency.\n\n**Examples**\n\nUpdated examples.\n"
  },
  {
    "path": "changelog/2.0.0-rc.31.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.31\n\n*(since 2.0.0-rc.30)*\n\n### New Features\n\n**`ne_all` for `Condition`**\n\nAdded `ne_all` to complement `eq_any`, allowing negation of multiple values in conditions.\n\n**Typed column for `TextUuid`** (#2717)\n\nAdded typed column support for `TextUuid` type.\n\n**Custom derives for `Model` and `ModelEx`** (#2933)\n\nMacros now support `model_attrs` and `model_ex_attrs` to pass custom derives and attributes to the generated `Model` and `ModelEx` structs. Enables customization such as TypeScript interface names when using `ts-rs`:\n\n```rust\n#[sea_orm::model]\n#[derive(TS, ...)]\n#[sea_orm(model_attrs(ts(rename = \"Fruit\")))]\n#[sea_orm(model_ex_attrs(ts(rename = \"FruitEx\")))]\nstruct Model { ... }\n```\n\n### Bug Fixes\n\n**`COUNT(*)` overflow on MySQL and SQLite** (#2944)\n\n`COUNT(*)` now returns `i64` on all backends. MySQL's `COUNT(*)` returns `BIGINT` (64-bit); previously it was read as `i32`, which could overflow for large datasets.\n\n**Proxy error handling** (#2935)\n\nFixed proxy error handling.\n\n### Improvements\n\n**Relaxed trait bounds for `eq_any` / `ne_all`**\n\nRelaxed trait bounds on `eq_any` and `ne_all` for broader compatibility. Depends on latest `sea-query`.\n\n**Raw string hashes** (#2381)\n\nRefactored to remove raw string hashes for improved readability.\n"
  },
  {
    "path": "changelog/2.0.0-rc.32.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.32\n\n*(since 2.0.0-rc.31)*\n\n### New Features\n\n**`MigratorTrait` with `self`** (#2806)\n\n`MigratorTrait` now uses `MigratorTraitSelf` with a shim, enabling migrator implementations that take `self` by reference.\n\n**PostgreSQL `application_name`**\n\nAdded support for setting `application_name` when connecting to PostgreSQL.\n\n### Improvements\n\n- Updated examples\n"
  },
  {
    "path": "changelog/2.0.0-rc.34.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.34\n\n*(since 2.0.0-rc.32)*\n\n### New Features\n\n**Arrow / Parquet support** (#2957)\n\n- Extracted `sea-orm-arrow` into a dedicated crate\n- Added `ArrowSchema`, `DeriveArrowSchema` for entity-to-Arrow conversion\n- Support decimal with different formats and timestamp with different timezone/resolution\n- Added `ActiveModel::from_arrow` for creating ActiveModels from Arrow arrays\n- Parquet example added\n- Arrow support in `sea-orm-sync`\n\n**`DeriveValueType`: `try_from_u64`** (#2958)\n\n`DeriveValueType` now derives `TryFromU64` for custom value types.\n\n**Derive `Clone` for topologies** (#2954)\n\nTopology types can now derive `Clone`.\n\n**`preserve-user-modifications` experimental flag** (#2964)\n\nAdded experimental `preserve-user-modifications` option for schema sync; default is `false`.\n\n**Optional `sea-schema`**\n\n`sea-schema` can be optional in some configurations.\n\n### Bug Fixes\n\n**Don't create redundant unique indexes** (#2950)\n\nFixed creation of redundant unique indexes on PostgreSQL and SQLite when a column is already unique. Fixes #2873.\n\n**Typo: \"exsiting\" → \"existing\"** (#2956)\n\n### Improvements\n\n- Refactored `sea-orm-arrow`; upgraded to Arrow 57; removed direct Arrow dependency\n- Improved docs for `DeriveValueType` (#2958)\n- Split up test suite by creating only needed tables per test\n- Support SeaORM X in `sea-orm-sync`\n"
  },
  {
    "path": "changelog/2.0.0-rc.35.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.35\n\n*(since 2.0.0-rc.34)*\n\n### New Features\n\n**SQLite Transaction Modes** (#2932)\n\nAdded `begin_with_options` to `TransactionTrait`, allowing you to specify SQLite transaction modes (`DEFERRED`, `IMMEDIATE`, `EXCLUSIVE`), along with isolation level and access mode for other backends. Works for both sqlx-sqlite and rusqlite.\n\n```rust\nuse sea_orm::{TransactionTrait, TransactionOptions, SqliteTransactionMode};\n\nlet txn = db.begin_with_options(TransactionOptions {\n    sqlite_transaction_mode: Some(SqliteTransactionMode::Immediate),\n    ..Default::default()\n}).await?;\n```\n\nNested transactions correctly fall back to `SAVEPOINT` regardless of the mode.\n\n**Extend `DeriveIntoActiveModel`** (#2961)\n\n`DeriveIntoActiveModel` now supports `set`, `default`, `ignore`, `exhaustive`, and custom `active_model` path attributes for fine-grained control when converting \"form\" or \"input\" structs into ActiveModels.\n\n**`set`** — always set fields not present on the struct:\n\n```rust\n#[derive(DeriveIntoActiveModel)]\n#[sea_orm(active_model = \"fruit::ActiveModel\", set(cake_id = \"None\"))]\nstruct NewFruit {\n    name: String,\n    // cake_id is not on the struct, but will always be Set(None)\n}\n\nNewFruit { name: \"Apple\".into() }.into_active_model()\n// => ActiveModel { id: NotSet, name: Set(\"Apple\"), cake_id: Set(None) }\n```\n\nMultiple `set` entries can be combined or split across attributes:\n\n```rust\n#[derive(DeriveIntoActiveModel)]\n#[sea_orm(\n    active_model = \"fruit::ActiveModel\",\n    set(name = \"String::from(\\\"cherry\\\")\", cake_id = \"None\")\n)]\nstruct IdOnlyFruit {\n    id: i32,\n}\n\nIdOnlyFruit { id: 1 }.into_active_model()\n// => ActiveModel { id: Set(1), name: Set(\"cherry\"), cake_id: Set(None) }\n```\n\n**`default`** — fallback value when an `Option<T>` field is `None`:\n\n```rust\n#[derive(DeriveIntoActiveModel)]\n#[sea_orm(active_model = \"fruit::ActiveModel\")]\nstruct NewFruit {\n    #[sea_orm(default = \"String::from(\\\"Unnamed\\\")\")]\n    name: Option<String>,\n}\n\nNewFruit { name: Some(\"Apple\".into()) }.into_active_model()\n// => ActiveModel { id: NotSet, name: Set(\"Apple\"), cake_id: NotSet }\n\nNewFruit { name: None }.into_active_model()\n// => ActiveModel { id: NotSet, name: Set(\"Unnamed\"), cake_id: NotSet }\n```\n\nBare `#[sea_orm(default)]` (without a value) uses `Default::default()` as the fallback. This also works with custom enum types that implement `Into<Option<T>>`.\n\n**`ignore`** — exclude struct fields from the ActiveModel:\n\n```rust\n#[derive(DeriveIntoActiveModel)]\n#[sea_orm(active_model = \"fruit::ActiveModel\")]\nstruct NewFruit {\n    name: String,\n    cake_id: i32,\n    #[sea_orm(ignore)]\n    _extra: String,  // not mapped to ActiveModel\n}\n```\n\n**`exhaustive`** — require all ActiveModel fields to be either on the struct or in `set(...)`:\n\n```rust\n#[derive(DeriveIntoActiveModel)]\n#[sea_orm(active_model = \"fruit::ActiveModel\", exhaustive, set(cake_id = \"None\"))]\nstruct FullFruit {\n    id: i32,\n    name: String,\n    // cake_id is covered by set(...), so all fields are accounted for\n}\n```\n\n**Combining everything** — `set` + `default` + `ignore` + `exhaustive`:\n\n```rust\n#[derive(DeriveIntoActiveModel)]\n#[sea_orm(active_model = \"fruit::ActiveModel\", exhaustive, set(cake_id = \"None\"))]\nstruct NewFruit {\n    id: i32,\n    #[sea_orm(default = \"String::from(\\\"Unnamed\\\")\")]\n    name: Option<String>,\n}\n\nNewFruit { id: 1, name: Some(\"Apple\".into()) }.into_active_model()\n// => ActiveModel { id: Set(1), name: Set(\"Apple\"), cake_id: Set(None) }\n\nNewFruit { id: 2, name: None }.into_active_model()\n// => ActiveModel { id: Set(2), name: Set(\"Unnamed\"), cake_id: Set(None) }\n```\n\n**`IntoSimpleExpr` for `FunctionCall`** (#2822)\n\n`FunctionCall` now implements `IntoSimpleExpr`, so function calls can be used directly in select expressions and filters without wrapping in `SimpleExpr`.\n\n**Arrow: Support `Decimal64` and Fixed-Size Binary** (#2957)\n\n- Decimal columns with precision <= 18 now map to Arrow `Decimal64` (was always `Decimal128`)\n- Precision 19-38 maps to `Decimal128`, above 38 to `Decimal256`\n- Added `FixedSizeBinary(N)` support via `#[sea_orm(arrow_byte_width = N)]`\n- Added `BinaryArray` / `LargeBinaryArray` / `FixedSizeBinaryArray` to `Value::Bytes` conversion\n\n**Optional `time` crate for Migrations** (#2865)\n\nMigrations can now use the `time` crate instead of `std::time::SystemTime` for timestamps, enabling compilation to WASM targets. Activate with the `with-time` feature on `sea-orm-migration`.\n\n**OpenTelemetry `SpanKind::Client`** (#2937)\n\nThe `db_span!` macro now emits `otel.kind = \"client\"`, ensuring database spans are properly recognized as client spans by APM tools (Datadog, Jaeger, etc.).\n\n### Bug Fixes\n\n**Fix unique column in schema sync** (#2971)\n\nColumns marked with `#[sea_orm(unique)]` are now correctly handled by the schema sync/diff builder, generating proper unique constraints instead of being silently ignored.\n\n**Fix `DeriveArrowSchema` with split attributes** (#2973)\n\nFixed a compilation error when `#[sea_orm(...)]` attributes were split across multiple lines on the same field (e.g. `#[sea_orm(primary_key)]` and `#[sea_orm(auto_increment = false)]` separately). The macro now properly consumes attributes it doesn't recognize.\n\n**Map internal error types properly**\n\nInternal errors from the schema builder are now mapped to the correct `DbErr` variants instead of being lost or mistyped.\n\n### Improvements\n\n**Pi Spigot Example**\n\nThe `sea-orm-sync` pi spigot example has been refactored into a tutorial-style example with:\n- OOP `PiSpigot` struct with state machine pattern (`new` / `step` / `finalize` / `to_state` / `from_state`)\n- `clap` CLI with `--digits`, `--checkpoint`, and `--db` flags\n- Comprehensive tests against 1000 known digits of pi, including three-phase checkpoint/resume\n- Tutorial README demonstrating how to add SQLite persistence to any program\n"
  },
  {
    "path": "changelog/2.0.0-rc.36.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.36\n\n*(since 2.0.0-rc.35)*\n\n### New Features\n\n**Per-Migration Transaction Control** (#2980)\n\nPreviously, all Postgres migrations ran inside a single batch transaction, while MySQL and SQLite ran without one. This was an all-or-nothing approach with no way to opt out for individual migrations (e.g. `CREATE INDEX CONCURRENTLY` on Postgres requires running outside a transaction).\n\n`MigrationTrait` now has a `use_transaction()` method to control this per migration:\n\n```rust\nimpl MigrationTrait for Migration {\n    fn use_transaction(&self) -> Option<bool> {\n        Some(false) // opt out of automatic transaction\n    }\n}\n```\n\n- `None` (default): follow backend convention — Postgres uses a transaction, MySQL/SQLite do not\n- `Some(true)`: force a transaction on any backend\n- `Some(false)`: disable automatic transaction wrapping\n\nFor migrations that opt out, `SchemaManager::begin()` and `SchemaManager::commit()` allow manual transaction control within the migration body:\n\n```rust\nasync fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n    // DDL in a transaction\n    let m = manager.begin().await?;\n    m.create_table(\n        Table::create()\n            .table(\"my_table\")\n            .col(pk_auto(\"id\"))\n            .col(string(\"name\"))\n            .to_owned(),\n    ).await?;\n    m.commit().await?;\n\n    // Non-transactional DDL\n    manager.get_connection()\n        .execute_unprepared(\"CREATE INDEX CONCURRENTLY idx_name ON my_table (name)\")\n        .await?;\n    Ok(())\n}\n```\n\nCore changes:\n- Added `OwnedTransaction` variant to `DatabaseExecutor`, enabling `SchemaManager` to own a transaction\n- Added `DatabaseExecutor::is_transaction()` for runtime introspection\n- Each migration is now wrapped individually rather than in a batch\n"
  },
  {
    "path": "changelog/2.0.0-rc.37.md",
    "content": "## Release Notes: SeaORM 2.0.0-rc.37\n\n*(since 2.0.0-rc.36)*\n\n### New Features\n\n**ER Diagram Generation** (`sea-orm-cli generate entity --er-diagram`)\n\n`sea-orm-cli` can now generate a [Mermaid](https://mermaid.js.org/) ER diagram alongside the entity files. Pass `--er-diagram` to write `entities.mermaid` into the output directory:\n\n```sh\nsea-orm-cli generate entity -u postgres://... -o src/entity --er-diagram\n```\n\nThe diagram annotates columns with `PK`, `FK`, and `UK` markers and renders all relations — including many-to-many via junction tables — as Mermaid `erDiagram` syntax. Example output:\n\n```\nerDiagram\n    user {\n        int id PK\n        varchar name\n        varchar email UK\n        int parent_id FK\n    }\n    post {\n        int id PK\n        text title\n        int user_id FK\n    }\n    user }o--|| user : \"parent_id\"\n    post }o--|| user : \"user_id\"\n    post }o--o{ tag : \"[post_tag]\"\n```\n\n**PostgreSQL Statement Timeout** (`ConnectOptions::statement_timeout`)\n\n`ConnectOptions` now accepts a `statement_timeout` for PostgreSQL connections. The timeout is set via the connection options at connect time (no extra round-trip) and causes the server to abort any statement that exceeds the duration:\n\n```rust\nConnectOptions::new(DATABASE_URL)\n    .statement_timeout(Duration::from_secs(30))\n    .to_owned()\n```\n\nHas no effect on MySQL or SQLite connections.\n\n**SQLite `?mode=` URL Parameter Support** (#2987)\n\nThe rusqlite driver now parses the `?mode=` query parameter from SQLite connection URLs, matching the behaviour of the sqlx SQLite driver:\n\n| Mode | Behaviour |\n|---|---|\n| `rwc` (default) | Read-write, create if not exists |\n| `rw` | Read-write, must exist |\n| `ro` | Read-only |\n| `memory` | In-memory database |\n\n```rust\n// Open an existing database read-only\nlet db = Database::connect(\"sqlite:./data.db?mode=ro\").await?;\n```\n\nUnsupported parameters or unknown mode values return a `DbErr::Conn` error.\n\n### Bug Fixes\n\n**`no-default-features` compile errors with `mac_address` and `proxy`** (#2992)\n\n- `with-mac_address` feature: added missing `TryGetable` impls, `try_from_u64` impl, postgres array support, and `with-json` serde flag\n- `proxy` feature: removed an accidental hard dependency on `serde_json` (now only activated via `with-json`)\n- Fixed `cfg` guards on JSON/JSONB proxy row handling to require `with-json`\n"
  },
  {
    "path": "examples/actix_example/Cargo.toml",
    "content": "[package]\nauthors      = [\"Sam Samai <sam@studio2pi.com.au>\"]\nedition      = \"2024\"\nname         = \"sea-orm-actix-4-beta-example\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[workspace]\nmembers = [\".\", \"api\", \"entity\", \"migration\"]\n\n[dependencies]\nactix-example-api = { path = \"api\" }\n"
  },
  {
    "path": "examples/actix_example/README.md",
    "content": "![screenshot](Screenshot.png)\n\n# Actix 4 with SeaORM example app\n\n1. Modify the `DATABASE_URL` var in `.env` to point to your chosen database\n\n1. Turn on the appropriate database feature for your chosen db in `api/Cargo.toml` (the `\"sqlx-mysql\",` line)\n\n1. Execute `cargo run` to start the server\n\n1. Visit [localhost:8000](http://localhost:8000) in browser\n\nRun server with auto-reloading:\n\n```bash\ncargo install systemfd cargo-watch\nsystemfd --no-pid -s http::8000 -- cargo watch -x run\n```\n\nRun tests:\n\n```bash\ncd api\ncargo test\n```\n\nRun migration:\n\n```bash\ncargo run -p migration -- up\n```\n\nRegenerate entity:\n\n```bash\nsea-orm-cli generate entity --output-dir ./entity/src --lib --entity-format dense --with-serde both\n```"
  },
  {
    "path": "examples/actix_example/api/Cargo.toml",
    "content": "[package]\nauthors      = [\"Sam Samai <sam@studio2pi.com.au>\"]\nedition      = \"2024\"\nname         = \"actix-example-api\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nactix-files        = \"0.6\"\nactix-http         = \"3\"\nactix-rt           = \"2.8\"\nactix-service      = \"2\"\nactix-web          = \"4\"\ndotenvy            = \"0.15\"\nentity             = { path = \"../entity\" }\nlistenfd           = \"1\"\nmigration          = { path = \"../migration\" }\nserde              = \"1\"\ntera               = \"1.19.0\"\ntracing-subscriber = { version = \"0.3.17\", features = [\"env-filter\"] }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"debug-print\",\n    \"runtime-tokio-native-tls\",\n    \"sqlx-mysql\",\n    # \"sqlx-postgres\",\n    # \"sqlx-sqlite\",\n]\npath = \"../../../\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n\n[dev-dependencies]\nactix-example-api = { path = \".\", features = [\"sqlite\"] }\ntokio             = { version = \"1.20.0\", features = [\"macros\", \"rt\"] }\n\n[features]\nsqlite = [\"sea-orm/sqlx-sqlite\"]\n"
  },
  {
    "path": "examples/actix_example/api/src/lib.rs",
    "content": "pub mod service;\n\nuse actix_files::Files as Fs;\nuse actix_web::{\n    App, Error, HttpRequest, HttpResponse, HttpServer, Result, error, get, middleware, post, web,\n};\n\nuse entity::post;\nuse listenfd::ListenFd;\nuse migration::{Migrator, MigratorTrait};\nuse sea_orm::{Database, DatabaseConnection};\nuse serde::{Deserialize, Serialize};\nuse service::{Mutation, Query};\nuse std::env;\nuse tera::Tera;\n\nconst DEFAULT_POSTS_PER_PAGE: u64 = 5;\n\n#[derive(Debug, Clone)]\nstruct AppState {\n    templates: tera::Tera,\n    conn: DatabaseConnection,\n}\n\n#[derive(Debug, Deserialize)]\npub struct Params {\n    page: Option<u64>,\n    posts_per_page: Option<u64>,\n}\n\n#[derive(Deserialize, Serialize, Debug, Clone)]\nstruct FlashData {\n    kind: String,\n    message: String,\n}\n\n#[get(\"/\")]\nasync fn list(req: HttpRequest, data: web::Data<AppState>) -> Result<HttpResponse, Error> {\n    let template = &data.templates;\n    let conn = &data.conn;\n\n    // get params\n    let params = web::Query::<Params>::from_query(req.query_string()).unwrap();\n\n    let page = params.page.unwrap_or(1);\n    let posts_per_page = params.posts_per_page.unwrap_or(DEFAULT_POSTS_PER_PAGE);\n\n    let (posts, num_pages) = Query::find_posts_in_page(conn, page, posts_per_page)\n        .await\n        .expect(\"Cannot find posts in page\");\n\n    let mut ctx = tera::Context::new();\n    ctx.insert(\"posts\", &posts);\n    ctx.insert(\"page\", &page);\n    ctx.insert(\"posts_per_page\", &posts_per_page);\n    ctx.insert(\"num_pages\", &num_pages);\n\n    let body = template\n        .render(\"index.html.tera\", &ctx)\n        .map_err(|_| error::ErrorInternalServerError(\"Template error\"))?;\n    Ok(HttpResponse::Ok().content_type(\"text/html\").body(body))\n}\n\n#[get(\"/new\")]\nasync fn new(data: web::Data<AppState>) -> Result<HttpResponse, Error> {\n    let template = &data.templates;\n    let ctx = tera::Context::new();\n    let body = template\n        .render(\"new.html.tera\", &ctx)\n        .map_err(|_| error::ErrorInternalServerError(\"Template error\"))?;\n    Ok(HttpResponse::Ok().content_type(\"text/html\").body(body))\n}\n\n#[post(\"/\")]\nasync fn create(\n    data: web::Data<AppState>,\n    post_form: web::Form<post::Model>,\n) -> Result<HttpResponse, Error> {\n    let conn = &data.conn;\n\n    let form = post_form.into_inner();\n\n    Mutation::create_post(conn, form)\n        .await\n        .expect(\"could not insert post\");\n\n    Ok(HttpResponse::Found()\n        .append_header((\"location\", \"/\"))\n        .finish())\n}\n\n#[get(r#\"/{id:\\d+}\"#)]\nasync fn edit(data: web::Data<AppState>, id: web::Path<i32>) -> Result<HttpResponse, Error> {\n    let conn = &data.conn;\n    let template = &data.templates;\n    let id = id.into_inner();\n\n    let post: Option<post::Model> = Query::find_post_by_id(conn, id)\n        .await\n        .expect(\"could not find post\");\n\n    let mut ctx = tera::Context::new();\n    let body = match post {\n        Some(post) => {\n            ctx.insert(\"post\", &post);\n\n            template\n                .render(\"edit.html.tera\", &ctx)\n                .map_err(|_| error::ErrorInternalServerError(\"Template error\"))\n        }\n        None => {\n            ctx.insert(\"uri\", &format!(\"/{}\", id));\n\n            template\n                .render(\"error/404.html.tera\", &ctx)\n                .map_err(|_| error::ErrorInternalServerError(\"Template error\"))\n        }\n    };\n    Ok(HttpResponse::Ok().content_type(\"text/html\").body(body?))\n}\n\n#[post(\"/{id}\")]\nasync fn update(\n    data: web::Data<AppState>,\n    id: web::Path<i32>,\n    post_form: web::Form<post::Model>,\n) -> Result<HttpResponse, Error> {\n    let conn = &data.conn;\n    let form = post_form.into_inner();\n    let id = id.into_inner();\n\n    Mutation::update_post_by_id(conn, id, form)\n        .await\n        .expect(\"could not edit post\");\n\n    Ok(HttpResponse::Found()\n        .append_header((\"location\", \"/\"))\n        .finish())\n}\n\n#[post(\"/delete/{id}\")]\nasync fn delete(data: web::Data<AppState>, id: web::Path<i32>) -> Result<HttpResponse, Error> {\n    let conn = &data.conn;\n    let id = id.into_inner();\n\n    Mutation::delete_post(conn, id)\n        .await\n        .expect(\"could not delete post\");\n\n    Ok(HttpResponse::Found()\n        .append_header((\"location\", \"/\"))\n        .finish())\n}\n\nasync fn not_found(data: web::Data<AppState>, request: HttpRequest) -> Result<HttpResponse, Error> {\n    let mut ctx = tera::Context::new();\n    ctx.insert(\"uri\", request.uri().path());\n\n    let template = &data.templates;\n    let body = template\n        .render(\"error/404.html.tera\", &ctx)\n        .map_err(|_| error::ErrorInternalServerError(\"Template error\"))?;\n\n    Ok(HttpResponse::Ok().content_type(\"text/html\").body(body))\n}\n\n#[actix_web::main]\nasync fn start() -> std::io::Result<()> {\n    unsafe {\n        std::env::set_var(\"RUST_LOG\", \"debug\");\n    }\n    tracing_subscriber::fmt::init();\n\n    // get env vars\n    dotenvy::dotenv().ok();\n    let db_url = env::var(\"DATABASE_URL\").expect(\"DATABASE_URL is not set in .env file\");\n    let host = env::var(\"HOST\").expect(\"HOST is not set in .env file\");\n    let port = env::var(\"PORT\").expect(\"PORT is not set in .env file\");\n    let server_url = format!(\"{host}:{port}\");\n\n    // establish connection to database and apply migrations\n    // -> create post table if not exists\n    let conn = Database::connect(&db_url).await.unwrap();\n    Migrator::up(&conn, None).await.unwrap();\n\n    // load tera templates and build app state\n    let templates = Tera::new(concat!(env!(\"CARGO_MANIFEST_DIR\"), \"/templates/**/*\")).unwrap();\n    let state = AppState { templates, conn };\n\n    // create server and try to serve over socket if possible\n    let mut listenfd = ListenFd::from_env();\n    let mut server = HttpServer::new(move || {\n        App::new()\n            .service(Fs::new(\"/static\", \"./api/static\"))\n            .app_data(web::Data::new(state.clone()))\n            .wrap(middleware::Logger::default()) // enable logger\n            .default_service(web::route().to(not_found))\n            .configure(init)\n    });\n\n    server = match listenfd.take_tcp_listener(0)? {\n        Some(listener) => server.listen(listener)?,\n        None => server.bind(&server_url)?,\n    };\n\n    println!(\"Starting server at {server_url}\");\n    server.run().await?;\n\n    Ok(())\n}\n\nfn init(cfg: &mut web::ServiceConfig) {\n    cfg.service(list);\n    cfg.service(new);\n    cfg.service(create);\n    cfg.service(edit);\n    cfg.service(update);\n    cfg.service(delete);\n}\n\npub fn main() {\n    let result = start();\n\n    if let Some(err) = result.err() {\n        println!(\"Error: {err}\");\n    }\n}\n"
  },
  {
    "path": "examples/actix_example/api/src/service/mod.rs",
    "content": "mod mutation;\nmod query;\n\npub use mutation::*;\npub use query::*;\n"
  },
  {
    "path": "examples/actix_example/api/src/service/mutation.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Mutation;\n\nimpl Mutation {\n    pub async fn create_post(\n        db: &DbConn,\n        form_data: post::Model,\n    ) -> Result<post::ActiveModel, DbErr> {\n        post::ActiveModel {\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n            ..Default::default()\n        }\n        .save(db)\n        .await\n    }\n\n    pub async fn update_post_by_id(\n        db: &DbConn,\n        id: i32,\n        form_data: post::Model,\n    ) -> Result<post::Model, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post::ActiveModel {\n            id: post.id,\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n        }\n        .update(db)\n        .await\n    }\n\n    pub async fn delete_post(db: &DbConn, id: i32) -> Result<DeleteResult, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post.delete(db).await\n    }\n\n    pub async fn delete_all_posts(db: &DbConn) -> Result<DeleteResult, DbErr> {\n        Post::delete_many().exec(db).await\n    }\n}\n"
  },
  {
    "path": "examples/actix_example/api/src/service/query.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Query;\n\nimpl Query {\n    pub async fn find_post_by_id(db: &DbConn, id: i32) -> Result<Option<post::Model>, DbErr> {\n        Post::find_by_id(id).one(db).await\n    }\n\n    /// If ok, returns (post models, num pages).\n    pub async fn find_posts_in_page(\n        db: &DbConn,\n        page: u64,\n        posts_per_page: u64,\n    ) -> Result<(Vec<post::Model>, u64), DbErr> {\n        // Setup paginator\n        let paginator = Post::find()\n            .order_by_asc(post::Column::Id)\n            .paginate(db, posts_per_page);\n        let num_pages = paginator.num_pages().await?;\n\n        // Fetch paginated posts\n        paginator.fetch_page(page - 1).await.map(|p| (p, num_pages))\n    }\n}\n"
  },
  {
    "path": "examples/actix_example/api/static/css/normalize.css",
    "content": "/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\n\n/**\n * 1. Set default font family to sans-serif.\n * 2. Prevent iOS text size adjust after orientation change, without disabling\n *    user zoom.\n */\n\nhtml {\n  font-family: sans-serif; /* 1 */\n  -ms-text-size-adjust: 100%; /* 2 */\n  -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/**\n * Remove default margin.\n */\n\nbody {\n  margin: 0;\n}\n\n/* HTML5 display definitions\n   ========================================================================== */\n\n/**\n * Correct `block` display not defined for any HTML5 element in IE 8/9.\n * Correct `block` display not defined for `details` or `summary` in IE 10/11\n * and Firefox.\n * Correct `block` display not defined for `main` in IE 11.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n/**\n * 1. Correct `inline-block` display not defined in IE 8/9.\n * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n */\n\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block; /* 1 */\n  vertical-align: baseline; /* 2 */\n}\n\n/**\n * Prevent modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n/**\n * Address `[hidden]` styling not present in IE 8/9/10.\n * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.\n */\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n/* Links\n   ========================================================================== */\n\n/**\n * Remove the gray background color from active links in IE 10.\n */\n\na {\n  background-color: transparent;\n}\n\n/**\n * Improve readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n  outline: 0;\n}\n\n/* Text-level semantics\n   ========================================================================== */\n\n/**\n * Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n */\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n/**\n * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n */\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n/**\n * Address styling not present in Safari and Chrome.\n */\n\ndfn {\n  font-style: italic;\n}\n\n/**\n * Address variable `h1` font-size and margin within `section` and `article`\n * contexts in Firefox 4+, Safari, and Chrome.\n */\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n/**\n * Address styling not present in IE 8/9.\n */\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n/**\n * Address inconsistent and variable font size in all browsers.\n */\n\nsmall {\n  font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n/* Embedded content\n   ========================================================================== */\n\n/**\n * Remove border when inside `a` element in IE 8/9/10.\n */\n\nimg {\n  border: 0;\n}\n\n/**\n * Correct overflow not hidden in IE 9/10/11.\n */\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n/* Grouping content\n   ========================================================================== */\n\n/**\n * Address margin not present in IE 8/9 and Safari.\n */\n\nfigure {\n  margin: 1em 40px;\n}\n\n/**\n * Address differences between Firefox and other browsers.\n */\n\nhr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\n\n/**\n * Contain overflow in all browsers.\n */\n\npre {\n  overflow: auto;\n}\n\n/**\n * Address odd `em`-unit font size rendering in all browsers.\n */\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n/* Forms\n   ========================================================================== */\n\n/**\n * Known limitation: by default, Chrome and Safari on OS X allow very limited\n * styling of `select`, unless a `border` property is set.\n */\n\n/**\n * 1. Correct color not being inherited.\n *    Known issue: affects color of disabled elements.\n * 2. Correct font properties not being inherited.\n * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit; /* 1 */\n  font: inherit; /* 2 */\n  margin: 0; /* 3 */\n}\n\n/**\n * Address `overflow` set to `hidden` in IE 8/9/10/11.\n */\n\nbutton {\n  overflow: visible;\n}\n\n/**\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\n * All other form control elements do not inherit `text-transform` values.\n * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n * Correct `select` style inheritance in Firefox.\n */\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n/**\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *    and `video` controls.\n * 2. Correct inability to style clickable `input` types in iOS.\n * 3. Improve usability and consistency of cursor style between image-type\n *    `input` and others.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; /* 2 */\n  cursor: pointer; /* 3 */\n}\n\n/**\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n/**\n * Remove inner padding and border in Firefox 4+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n/**\n * Address Firefox 4+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\ninput {\n  line-height: normal;\n}\n\n/**\n * It's recommended that you don't attempt to style these elements.\n * Firefox's implementation doesn't respect box-sizing, padding, or width.\n *\n * 1. Address box sizing set to `content-box` in IE 8/9/10.\n * 2. Remove excess padding in IE 8/9/10.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Fix the cursor style for Chrome's increment/decrement buttons. For certain\n * `font-size` values of the `input`, it causes the cursor style of the\n * decrement button to change from `default` to `text`.\n */\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n/**\n * 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n * 2. Address `box-sizing` set to `border-box` in Safari and Chrome\n *    (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; /* 1 */\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box; /* 2 */\n  box-sizing: content-box;\n}\n\n/**\n * Remove inner padding and search cancel button in Safari and Chrome on OS X.\n * Safari (but not Chrome) clips the cancel button when the search input has\n * padding (and `textfield` appearance).\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n/**\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n/**\n * 1. Correct `color` not being inherited in IE 8/9/10/11.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\n\nlegend {\n  border: 0; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Remove default vertical scrollbar in IE 8/9/10/11.\n */\n\ntextarea {\n  overflow: auto;\n}\n\n/**\n * Don't inherit the `font-weight` (applied by a rule above).\n * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n */\n\noptgroup {\n  font-weight: bold;\n}\n\n/* Tables\n   ========================================================================== */\n\n/**\n * Remove most spacing between table cells.\n */\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n"
  },
  {
    "path": "examples/actix_example/api/static/css/skeleton.css",
    "content": "/*\n* Skeleton V2.0.4\n* Copyright 2014, Dave Gamache\n* www.getskeleton.com\n* Free to use under the MIT license.\n* https://opensource.org/licenses/mit-license.php\n* 12/29/2014\n*/\n\n\n/* Table of contents\n––––––––––––––––––––––––––––––––––––––––––––––––––\n- Grid\n- Base Styles\n- Typography\n- Links\n- Buttons\n- Forms\n- Lists\n- Code\n- Tables\n- Spacing\n- Utilities\n- Clearing\n- Media Queries\n*/\n\n\n/* Grid\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.container {\n  position: relative;\n  width: 100%;\n  max-width: 960px;\n  margin: 0 auto;\n  padding: 0 20px;\n  box-sizing: border-box; }\n.column,\n.columns {\n  width: 100%;\n  float: left;\n  box-sizing: border-box; }\n\n/* For devices larger than 400px */\n@media (min-width: 400px) {\n  .container {\n    width: 85%;\n    padding: 0; }\n}\n\n/* For devices larger than 550px */\n@media (min-width: 550px) {\n  .container {\n    width: 80%; }\n  .column,\n  .columns {\n    margin-left: 4%; }\n  .column:first-child,\n  .columns:first-child {\n    margin-left: 0; }\n\n  .one.column,\n  .one.columns                    { width: 4.66666666667%; }\n  .two.columns                    { width: 13.3333333333%; }\n  .three.columns                  { width: 22%;            }\n  .four.columns                   { width: 30.6666666667%; }\n  .five.columns                   { width: 39.3333333333%; }\n  .six.columns                    { width: 48%;            }\n  .seven.columns                  { width: 56.6666666667%; }\n  .eight.columns                  { width: 65.3333333333%; }\n  .nine.columns                   { width: 74.0%;          }\n  .ten.columns                    { width: 82.6666666667%; }\n  .eleven.columns                 { width: 91.3333333333%; }\n  .twelve.columns                 { width: 100%; margin-left: 0; }\n\n  .one-third.column               { width: 30.6666666667%; }\n  .two-thirds.column              { width: 65.3333333333%; }\n\n  .one-half.column                { width: 48%; }\n\n  /* Offsets */\n  .offset-by-one.column,\n  .offset-by-one.columns          { margin-left: 8.66666666667%; }\n  .offset-by-two.column,\n  .offset-by-two.columns          { margin-left: 17.3333333333%; }\n  .offset-by-three.column,\n  .offset-by-three.columns        { margin-left: 26%;            }\n  .offset-by-four.column,\n  .offset-by-four.columns         { margin-left: 34.6666666667%; }\n  .offset-by-five.column,\n  .offset-by-five.columns         { margin-left: 43.3333333333%; }\n  .offset-by-six.column,\n  .offset-by-six.columns          { margin-left: 52%;            }\n  .offset-by-seven.column,\n  .offset-by-seven.columns        { margin-left: 60.6666666667%; }\n  .offset-by-eight.column,\n  .offset-by-eight.columns        { margin-left: 69.3333333333%; }\n  .offset-by-nine.column,\n  .offset-by-nine.columns         { margin-left: 78.0%;          }\n  .offset-by-ten.column,\n  .offset-by-ten.columns          { margin-left: 86.6666666667%; }\n  .offset-by-eleven.column,\n  .offset-by-eleven.columns       { margin-left: 95.3333333333%; }\n\n  .offset-by-one-third.column,\n  .offset-by-one-third.columns    { margin-left: 34.6666666667%; }\n  .offset-by-two-thirds.column,\n  .offset-by-two-thirds.columns   { margin-left: 69.3333333333%; }\n\n  .offset-by-one-half.column,\n  .offset-by-one-half.columns     { margin-left: 52%; }\n\n}\n\n\n/* Base Styles\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n/* NOTE\nhtml is set to 62.5% so that all the REM measurements throughout Skeleton\nare based on 10px sizing. So basically 1.5rem = 15px :) */\nhtml {\n  font-size: 62.5%; }\nbody {\n  font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */\n  line-height: 1.6;\n  font-weight: 400;\n  font-family: \"Raleway\", \"HelveticaNeue\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  color: #222; }\n\n\n/* Typography\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nh1, h2, h3, h4, h5, h6 {\n  margin-top: 0;\n  margin-bottom: 2rem;\n  font-weight: 300; }\nh1 { font-size: 4.0rem; line-height: 1.2;  letter-spacing: -.1rem;}\nh2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; }\nh3 { font-size: 3.0rem; line-height: 1.3;  letter-spacing: -.1rem; }\nh4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; }\nh5 { font-size: 1.8rem; line-height: 1.5;  letter-spacing: -.05rem; }\nh6 { font-size: 1.5rem; line-height: 1.6;  letter-spacing: 0; }\n\n/* Larger than phablet */\n@media (min-width: 550px) {\n  h1 { font-size: 5.0rem; }\n  h2 { font-size: 4.2rem; }\n  h3 { font-size: 3.6rem; }\n  h4 { font-size: 3.0rem; }\n  h5 { font-size: 2.4rem; }\n  h6 { font-size: 1.5rem; }\n}\n\np {\n  margin-top: 0; }\n\n\n/* Links\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\na {\n  color: #1EAEDB; }\na:hover {\n  color: #0FA0CE; }\n\n\n/* Buttons\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.button,\nbutton,\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n  display: inline-block;\n  height: 38px;\n  padding: 0 30px;\n  color: #555;\n  text-align: center;\n  font-size: 11px;\n  font-weight: 600;\n  line-height: 38px;\n  letter-spacing: .1rem;\n  text-transform: uppercase;\n  text-decoration: none;\n  white-space: nowrap;\n  background-color: transparent;\n  border-radius: 4px;\n  border: 1px solid #bbb;\n  cursor: pointer;\n  box-sizing: border-box; }\n.button:hover,\nbutton:hover,\ninput[type=\"submit\"]:hover,\ninput[type=\"reset\"]:hover,\ninput[type=\"button\"]:hover,\n.button:focus,\nbutton:focus,\ninput[type=\"submit\"]:focus,\ninput[type=\"reset\"]:focus,\ninput[type=\"button\"]:focus {\n  color: #333;\n  border-color: #888;\n  outline: 0; }\n.button.button-primary,\nbutton.button-primary,\nbutton.primary,\ninput[type=\"submit\"].button-primary,\ninput[type=\"reset\"].button-primary,\ninput[type=\"button\"].button-primary {\n  color: #FFF;\n  background-color: #33C3F0;\n  border-color: #33C3F0; }\n.button.button-primary:hover,\nbutton.button-primary:hover,\nbutton.primary:hover,\ninput[type=\"submit\"].button-primary:hover,\ninput[type=\"reset\"].button-primary:hover,\ninput[type=\"button\"].button-primary:hover,\n.button.button-primary:focus,\nbutton.button-primary:focus,\nbutton.primary:focus,\ninput[type=\"submit\"].button-primary:focus,\ninput[type=\"reset\"].button-primary:focus,\ninput[type=\"button\"].button-primary:focus {\n  color: #FFF;\n  background-color: #1EAEDB;\n  border-color: #1EAEDB; }\n\n\n/* Forms\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ninput[type=\"text\"],\ninput[type=\"tel\"],\ninput[type=\"url\"],\ninput[type=\"password\"],\ntextarea,\nselect {\n  height: 38px;\n  padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */\n  background-color: #fff;\n  border: 1px solid #D1D1D1;\n  border-radius: 4px;\n  box-shadow: none;\n  box-sizing: border-box; }\n/* Removes awkward default styles on some inputs for iOS */\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ninput[type=\"text\"],\ninput[type=\"tel\"],\ninput[type=\"url\"],\ninput[type=\"password\"],\ntextarea {\n  -webkit-appearance: none;\n     -moz-appearance: none;\n          appearance: none; }\ntextarea {\n  min-height: 65px;\n  padding-top: 6px;\n  padding-bottom: 6px; }\ninput[type=\"email\"]:focus,\ninput[type=\"number\"]:focus,\ninput[type=\"search\"]:focus,\ninput[type=\"text\"]:focus,\ninput[type=\"tel\"]:focus,\ninput[type=\"url\"]:focus,\ninput[type=\"password\"]:focus,\ntextarea:focus,\nselect:focus {\n  border: 1px solid #33C3F0;\n  outline: 0; }\nlabel,\nlegend {\n  display: block;\n  margin-bottom: .5rem;\n  font-weight: 600; }\nfieldset {\n  padding: 0;\n  border-width: 0; }\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  display: inline; }\nlabel > .label-body {\n  display: inline-block;\n  margin-left: .5rem;\n  font-weight: normal; }\n\n\n/* Lists\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nul {\n  list-style: circle inside; }\nol {\n  list-style: decimal inside; }\nol, ul {\n  padding-left: 0;\n  margin-top: 0; }\nul ul,\nul ol,\nol ol,\nol ul {\n  margin: 1.5rem 0 1.5rem 3rem;\n  font-size: 90%; }\nli {\n  margin-bottom: 1rem; }\n\n\n/* Code\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\ncode {\n  padding: .2rem .5rem;\n  margin: 0 .2rem;\n  font-size: 90%;\n  white-space: nowrap;\n  background: #F1F1F1;\n  border: 1px solid #E1E1E1;\n  border-radius: 4px; }\npre > code {\n  display: block;\n  padding: 1rem 1.5rem;\n  white-space: pre; }\n\n\n/* Tables\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nth,\ntd {\n  padding: 12px 15px;\n  text-align: left;\n  border-bottom: 1px solid #E1E1E1; }\nth:first-child,\ntd:first-child {\n  padding-left: 0; }\nth:last-child,\ntd:last-child {\n  padding-right: 0; }\n\n\n/* Spacing\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nbutton,\n.button {\n  margin-bottom: 1rem; }\ninput,\ntextarea,\nselect,\nfieldset {\n  margin-bottom: 1.5rem; }\npre,\nblockquote,\ndl,\nfigure,\ntable,\np,\nul,\nol,\nform {\n  margin-bottom: 2.5rem; }\n\n\n/* Utilities\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.u-full-width {\n  width: 100%;\n  box-sizing: border-box; }\n.u-max-full-width {\n  max-width: 100%;\n  box-sizing: border-box; }\n.u-pull-right {\n  float: right; }\n.u-pull-left {\n  float: left; }\n\n\n/* Misc\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nhr {\n  margin-top: 3rem;\n  margin-bottom: 3.5rem;\n  border-width: 0;\n  border-top: 1px solid #E1E1E1; }\n\n\n/* Clearing\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n\n/* Self Clearing Goodness */\n.container:after,\n.row:after,\n.u-cf {\n  content: \"\";\n  display: table;\n  clear: both; }\n\n\n/* Media Queries\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n/*\nNote: The best way to structure the use of media queries is to create the queries\nnear the relevant code. For example, if you wanted to change the styles for buttons\non small devices, paste the mobile query code up in the buttons section and style it\nthere.\n*/\n\n\n/* Larger than mobile */\n@media (min-width: 400px) {}\n\n/* Larger than phablet (also point when grid becomes active) */\n@media (min-width: 550px) {}\n\n/* Larger than tablet */\n@media (min-width: 750px) {}\n\n/* Larger than desktop */\n@media (min-width: 1000px) {}\n\n/* Larger than Desktop HD */\n@media (min-width: 1200px) {}\n"
  },
  {
    "path": "examples/actix_example/api/static/css/style.css",
    "content": ".field-error {\n  border: 1px solid #ff0000 !important;\n}\n\n.field-error-flash {\n  color: #ff0000;\n  display: block;\n  margin: -10px 0 10px 0;\n}\n\n.field-success {\n  border: 1px solid #5ab953 !important;\n}\n\n.field-success-flash {\n  color: #5ab953;\n  display: block;\n  margin: -10px 0 10px 0;\n}\n\nspan.completed {\n  text-decoration: line-through;\n}\n\nform.inline {\n  display: inline;\n}\n\nform.link,\nbutton.link {\n  display: inline;\n  color: #1eaedb;\n  border: none;\n  outline: none;\n  background: none;\n  cursor: pointer;\n  padding: 0;\n  margin: 0 0 0 0;\n  height: inherit;\n  text-decoration: underline;\n  font-size: inherit;\n  text-transform: none;\n  font-weight: normal;\n  line-height: inherit;\n  letter-spacing: inherit;\n}\n\nform.link:hover,\nbutton.link:hover {\n  color: #0fa0ce;\n}\n\nbutton.small {\n  height: 20px;\n  padding: 0 10px;\n  font-size: 10px;\n  line-height: 20px;\n  margin: 0 2.5px;\n}\n\n.post:hover {\n  background-color: #bce2ee;\n}\n\n.post td {\n  padding: 5px;\n  width: 150px;\n}\n\n#delete-button {\n  color: red;\n  border-color: red;\n}\n"
  },
  {
    "path": "examples/actix_example/api/templates/edit.html.tera",
    "content": "{% extends \"layout.html.tera\" %} {% block content %}\n<div class=\"row\">\n  <h4>Edit Post</h4>\n  <div class=\"twelve columns\">\n    <div class=\"ten columns\">\n      <form action=\"/{{ post.id }}\" method=\"post\">\n        <div class=\"twelve columns\">\n          <input\n            type=\"text\"\n            placeholder=\"title\"\n            name=\"title\"\n            id=\"title\"\n            value=\"{{ post.title }}\"\n            autofocus\n            class=\"u-full-width\"\n          />\n          <input\n            type=\"text\"\n            placeholder=\"content\"\n            name=\"text\"\n            id=\"text\"\n            value=\"{{ post.text }}\"\n            autofocus\n            class=\"u-full-width\"\n          />\n        </div>\n        <div class=\"twelve columns\">\n          <div class=\"two columns\">\n            <a href=\"/\">\n              <input type=\"button\" value=\"cancel\" />\n            </a>\n          </div>\n          <div class=\"eight columns\"></div>\n          <div class=\"two columns\">\n            <input type=\"submit\" value=\"save post\" />\n          </div>\n        </div>\n      </form>\n    </div>\n    <div class=\"two columns\">\n      <form action=\"/delete/{{ post.id }}\" method=\"post\">\n        <div class=\"two columns\">\n          <input id=\"delete-button\" type=\"submit\" value=\"delete post\" />\n        </div>\n      </form>\n    </div>\n  </div>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/actix_example/api/templates/error/404.html.tera",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>404 - tera</title>\n  </head>\n  <body>\n    <h1>404: Hey! There's nothing here.</h1>\n    The page at {{ uri }} does not exist!\n  </body>\n</html>\n"
  },
  {
    "path": "examples/actix_example/api/templates/index.html.tera",
    "content": "{% extends \"layout.html.tera\" %} {% block content %}\n<div class=\"container\">\n  <p><!--Nothing to see here --></p>\n  <h1>Posts</h1>\n  {% if flash %}\n  <small class=\"field-{{ flash.kind }}-flash\">\n    {{ flash.message }}\n  </small>\n  {% endif %}\n  <table>\n    <tbody>\n      <thead>\n        <tr>\n          <th>ID</th>\n          <th>Title</th>\n          <th>Text</th>\n        </tr>\n      </thead>\n      {% for post in posts %}\n      <tr class=\"post\" onclick=\"window.location='/{{ post.id }}';\">\n        <td>{{ post.id }}</td>\n        <td>{{ post.title }}</td>\n        <td>{{ post.text }}</td>\n      </tr>\n      {% endfor %}\n    </tbody>\n    <tfoot>\n      <tr>\n        <td></td>\n        <td>\n          {% if page == 1 %} Previous {% else %}\n          <a href=\"/?page={{ page - 1 }}&posts_per_page={{ posts_per_page }}\"\n            >Previous</a\n          >\n          {% endif %} | {% if page == num_pages %} Next {% else %}\n          <a href=\"/?page={{ page + 1 }}&posts_per_page={{ posts_per_page }}\"\n            >Next</a\n          >\n          {% endif %}\n        </td>\n        <td></td>\n      </tr>\n    </tfoot>\n  </table>\n\n  <div class=\"twelve columns\">\n    <a href=\"/new\">\n      <input type=\"button\" value=\"add post\" />\n    </a>\n  </div>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/actix_example/api/templates/layout.html.tera",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>Actix Example</title>\n    <meta name=\"description\" content=\"Actix - SeaOrm integration example\" />\n    <meta name=\"author\" content=\"Sam Samai\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\n    <link\n      href=\"//fonts.googleapis.com/css?family=Raleway:400,300,600\"\n      rel=\"stylesheet\"\n      type=\"text/css\"\n    />\n    <link rel=\"stylesheet\" href=\"/static/css/normalize.css\" />\n    <link rel=\"stylesheet\" href=\"/static/css/skeleton.css\" />\n    <link rel=\"stylesheet\" href=\"/static/css/style.css\" />\n    <link rel=\"icon\" type=\"image/png\" href=\"/static/images/favicon.png\" />\n  </head>\n  <body>\n    <div class=\"container\">\n      <p><!--Nothing to see here --></p>\n      {% block content %}{% endblock content %}\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/actix_example/api/templates/new.html.tera",
    "content": "{% extends \"layout.html.tera\" %} {% block content %}\n<div class=\"row\">\n  <h4>New Post</h4>\n  <form action=\"/\" method=\"post\">\n    <div class=\"twelve columns\">\n      <input\n        type=\"text\"\n        placeholder=\"enter title\"\n        name=\"title\"\n        id=\"title\"\n        value=\"\"\n        autofocus\n        class=\"u-full-width\"\n      />\n      <input\n        type=\"text\"\n        placeholder=\"enter content\"\n        name=\"text\"\n        id=\"text\"\n        value=\"\"\n        autofocus\n        class=\"u-full-width\"\n      />\n    </div>\n    <div class=\"twelve columns\">\n      <div class=\"two columns\">\n        <a href=\"/\">\n          <input type=\"button\" value=\"cancel\" />\n        </a>\n      </div>\n      <div class=\"eight columns\"></div>\n      <div class=\"two columns\">\n        <input type=\"submit\" value=\"save post\" />\n      </div>\n    </div>\n  </form>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/actix_example/api/tests/crud_tests.rs",
    "content": "use actix_example_api::service::{Mutation, Query};\nuse entity::post;\nuse sea_orm::Database;\n\n#[tokio::test]\nasync fn crud_tests() {\n    let db = &Database::connect(\"sqlite::memory:\").await.unwrap();\n\n    db.get_schema_builder()\n        .register(post::Entity)\n        .apply(db)\n        .await\n        .unwrap();\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title A\".to_owned(),\n                text: \"Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(1),\n                title: sea_orm::ActiveValue::Unchanged(\"Title A\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text A\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title B\".to_owned(),\n                text: \"Text B\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(2),\n                title: sea_orm::ActiveValue::Unchanged(\"Title B\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text B\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 1).await.unwrap().unwrap();\n\n        assert_eq!(post.id, 1);\n        assert_eq!(post.title, \"Title A\");\n    }\n\n    {\n        let post = Mutation::update_post_by_id(\n            db,\n            1,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            }\n        );\n    }\n\n    {\n        let result = Mutation::delete_post(db, 2).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 2).await.unwrap();\n        assert!(post.is_none());\n    }\n\n    {\n        let result = Mutation::delete_all_posts(db).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n}\n"
  },
  {
    "path": "examples/actix_example/entity/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"entity\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"entity\"\npath = \"src/lib.rs\"\n\n[dependencies]\nserde = { version = \"1\", features = [\"derive\"] }\n\n[dependencies.sea-orm]\npath    = \"../../../\"    # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n"
  },
  {
    "path": "examples/actix_example/entity/src/lib.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub mod prelude;\n\npub mod post;\n"
  },
  {
    "path": "examples/actix_example/entity/src/post.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"post\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    pub title: String,\n    #[sea_orm(column_type = \"Text\")]\n    pub text: String,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/actix_example/entity/src/prelude.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub use super::post::Entity as Post;\n"
  },
  {
    "path": "examples/actix_example/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nentity = { path = \"../entity\" }\ntokio  = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable following runtime and db backend features if you want to run migration via CLI\n    \"runtime-tokio-native-tls\",\n    \"sqlx-mysql\",\n]\npath = \"../../../sea-orm-migration\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/actix_example/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/actix_example/migration/src/lib.rs",
    "content": "pub use sea_orm_migration::prelude::*;\n\nmod m20220120_000001_create_post_table;\nmod m20220120_000002_seed_posts;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220120_000001_create_post_table::Migration),\n            Box::new(m20220120_000002_seed_posts::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "examples/actix_example/migration/src/m20220120_000001_create_post_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"post\")\n                    .if_not_exists()\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"title\"))\n                    .col(string(\"text\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"post\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/actix_example/migration/src/m20220120_000002_seed_posts.rs",
    "content": "use entity::post;\nuse sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};\nuse sea_orm_migration::prelude::*;\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let seed_data = vec![\n            (\"First Post\", \"This is the first post.\"),\n            (\"Second Post\", \"This is another post.\"),\n        ];\n\n        for (title, text) in seed_data {\n            let model = post::ActiveModel {\n                title: Set(title.to_string()),\n                text: Set(text.to_string()),\n                ..Default::default()\n            };\n            model.insert(db).await?;\n        }\n\n        println!(\"Posts table seeded successfully.\");\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let titles_to_delete = vec![\"First Post\", \"Second Post\"];\n        post::Entity::delete_many()\n            .filter(post::Column::Title.is_in(titles_to_delete))\n            .exec(db)\n            .await?;\n\n        println!(\"Posts seeded data removed.\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/actix_example/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/actix_example/src/main.rs",
    "content": "fn main() {\n    actix_example_api::main();\n}\n"
  },
  {
    "path": "examples/axum_example/Cargo.toml",
    "content": "[package]\nauthors      = [\"Yoshiera Huang <huangjasper@126.com>\"]\nedition      = \"2024\"\nname         = \"sea-orm-axum-example\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[workspace]\nmembers = [\".\", \"api\", \"entity\", \"migration\"]\n\n[dependencies]\naxum-example-api = { path = \"api\" }\n"
  },
  {
    "path": "examples/axum_example/README.md",
    "content": "![screenshot](Screenshot.png)\n\n# Axum with SeaORM example app\n\n1. Modify the `DATABASE_URL` var in `.env` to point to your chosen database\n\n1. Turn on the appropriate database feature for your chosen db in `api/Cargo.toml` (the `\"sqlx-postgres\",` line)\n\n1. Execute `cargo run` to start the server\n\n1. Visit [localhost:8000](http://localhost:8000) in browser\n\nRun tests:\n\n```bash\ncd api\ncargo test\n```\n\nRun migration:\n\n```bash\ncargo run -p migration -- up\n```\n\nRegenerate entity:\n\n```bash\nsea-orm-cli generate entity --output-dir ./entity/src --lib --entity-format dense --with-serde both\n```"
  },
  {
    "path": "examples/axum_example/api/Cargo.toml",
    "content": "[package]\nauthors      = [\"Yoshiera Huang <huangjasper@126.com>\"]\nedition      = \"2024\"\nname         = \"axum-example-api\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nanyhow             = \"1.0.75\"\naxum               = \"0.8\"\ndotenvy            = \"0.15.7\"\nentity             = { path = \"../entity\" }\nmigration          = { path = \"../migration\" }\nserde              = \"1.0.193\"\nserde_json         = \"1.0.108\"\ntera               = \"1.19.1\"\ntokio              = { version = \"1.34.0\", features = [\"full\"] }\ntower              = \"0.5\"\ntower-cookies      = \"0.11\"\ntower-http         = { version = \"0.6\", features = [\"fs\"] }\ntracing-subscriber = { version = \"0.3.18\", features = [\"env-filter\"] }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"debug-print\",\n    \"runtime-tokio-native-tls\",\n    \"sqlx-postgres\",\n    # \"sqlx-mysql\",\n    # \"sqlx-sqlite\",\n]\npath = \"../../../\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n\n[dev-dependencies]\naxum-example-api = { path = \".\", features = [\"sqlite\"] }\n\n[features]\nsqlite = [\"sea-orm/sqlx-sqlite\"]\n"
  },
  {
    "path": "examples/axum_example/api/src/flash.rs",
    "content": "use axum::http::{HeaderMap, HeaderValue, StatusCode, header};\nuse serde::{Deserialize, Serialize, de::DeserializeOwned};\nuse tower_cookies::{Cookie, Cookies};\n\n#[derive(Deserialize)]\nstruct ValuedMessage<T> {\n    #[serde(rename = \"_\")]\n    value: T,\n}\n\n#[derive(Serialize)]\nstruct ValuedMessageRef<'a, T> {\n    #[serde(rename = \"_\")]\n    value: &'a T,\n}\n\nconst FLASH_COOKIE_NAME: &str = \"_flash\";\n\npub fn get_flash_cookie<T>(cookies: &Cookies) -> Option<T>\nwhere\n    T: DeserializeOwned,\n{\n    cookies.get(FLASH_COOKIE_NAME).and_then(|flash_cookie| {\n        if let Ok(ValuedMessage::<T> { value }) = serde_json::from_str(flash_cookie.value()) {\n            Some(value)\n        } else {\n            None\n        }\n    })\n}\n\npub type PostResponse = (StatusCode, HeaderMap);\n\npub fn post_response<T>(cookies: &mut Cookies, data: T) -> PostResponse\nwhere\n    T: Serialize,\n{\n    let valued_message_ref = ValuedMessageRef { value: &data };\n\n    let mut cookie = Cookie::new(\n        FLASH_COOKIE_NAME,\n        serde_json::to_string(&valued_message_ref).unwrap(),\n    );\n    cookie.set_path(\"/\");\n    cookies.add(cookie);\n\n    let mut header = HeaderMap::new();\n    header.insert(header::LOCATION, HeaderValue::from_static(\"/\"));\n\n    (StatusCode::SEE_OTHER, header)\n}\n"
  },
  {
    "path": "examples/axum_example/api/src/lib.rs",
    "content": "mod flash;\npub mod service;\n\nuse axum::{\n    Router,\n    extract::{Form, Path, Query, State},\n    http::StatusCode,\n    response::Html,\n    routing::{get, get_service, post},\n};\nuse entity::post;\nuse flash::{PostResponse, get_flash_cookie, post_response};\nuse migration::{Migrator, MigratorTrait};\nuse sea_orm::{Database, DatabaseConnection};\nuse serde::{Deserialize, Serialize};\nuse service::{Mutation, Query as QueryService};\nuse std::env;\nuse tera::Tera;\nuse tower_cookies::{CookieManagerLayer, Cookies};\nuse tower_http::services::ServeDir;\n\n#[tokio::main]\nasync fn start() -> anyhow::Result<()> {\n    unsafe {\n        env::set_var(\"RUST_LOG\", \"debug\");\n    }\n    tracing_subscriber::fmt::init();\n\n    dotenvy::dotenv().ok();\n    let db_url = env::var(\"DATABASE_URL\").expect(\"DATABASE_URL is not set in .env file\");\n    let host = env::var(\"HOST\").expect(\"HOST is not set in .env file\");\n    let port = env::var(\"PORT\").expect(\"PORT is not set in .env file\");\n    let server_url = format!(\"{host}:{port}\");\n\n    let conn = Database::connect(db_url)\n        .await\n        .expect(\"Database connection failed\");\n    Migrator::up(&conn, None).await.unwrap();\n\n    let templates = Tera::new(concat!(env!(\"CARGO_MANIFEST_DIR\"), \"/templates/**/*\"))\n        .expect(\"Tera initialization failed\");\n\n    let state = AppState { templates, conn };\n\n    let app = Router::new()\n        .route(\"/\", get(list_posts).post(create_post))\n        .route(\"/{id}\", get(edit_post).post(update_post))\n        .route(\"/new\", get(new_post))\n        .route(\"/delete/{id}\", post(delete_post))\n        .nest_service(\n            \"/static\",\n            get_service(ServeDir::new(concat!(\n                env!(\"CARGO_MANIFEST_DIR\"),\n                \"/static\"\n            )))\n            .handle_error(|error| async move {\n                (\n                    StatusCode::INTERNAL_SERVER_ERROR,\n                    format!(\"Unhandled internal error: {error}\"),\n                )\n            }),\n        )\n        .layer(CookieManagerLayer::new())\n        .with_state(state);\n\n    let listener = tokio::net::TcpListener::bind(&server_url).await.unwrap();\n    axum::serve(listener, app).await?;\n\n    Ok(())\n}\n\n#[derive(Clone)]\nstruct AppState {\n    templates: Tera,\n    conn: DatabaseConnection,\n}\n\n#[derive(Deserialize)]\nstruct Params {\n    page: Option<u64>,\n    posts_per_page: Option<u64>,\n}\n\n#[derive(Deserialize, Serialize, Debug, Clone)]\nstruct FlashData {\n    kind: String,\n    message: String,\n}\n\nasync fn list_posts(\n    state: State<AppState>,\n    Query(params): Query<Params>,\n    cookies: Cookies,\n) -> Result<Html<String>, (StatusCode, &'static str)> {\n    let page = params.page.unwrap_or(1);\n    let posts_per_page = params.posts_per_page.unwrap_or(5);\n\n    let (posts, num_pages) = QueryService::find_posts_in_page(&state.conn, page, posts_per_page)\n        .await\n        .expect(\"Cannot find posts in page\");\n\n    let mut ctx = tera::Context::new();\n    ctx.insert(\"posts\", &posts);\n    ctx.insert(\"page\", &page);\n    ctx.insert(\"posts_per_page\", &posts_per_page);\n    ctx.insert(\"num_pages\", &num_pages);\n\n    if let Some(value) = get_flash_cookie::<FlashData>(&cookies) {\n        ctx.insert(\"flash\", &value);\n    }\n\n    let body = state\n        .templates\n        .render(\"index.html.tera\", &ctx)\n        .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, \"Template error\"))?;\n\n    Ok(Html(body))\n}\n\nasync fn new_post(state: State<AppState>) -> Result<Html<String>, (StatusCode, &'static str)> {\n    let ctx = tera::Context::new();\n    let body = state\n        .templates\n        .render(\"new.html.tera\", &ctx)\n        .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, \"Template error\"))?;\n\n    Ok(Html(body))\n}\n\nasync fn create_post(\n    state: State<AppState>,\n    mut cookies: Cookies,\n    form: Form<post::Model>,\n) -> Result<PostResponse, (StatusCode, &'static str)> {\n    let form = form.0;\n\n    Mutation::create_post(&state.conn, form)\n        .await\n        .expect(\"could not insert post\");\n\n    let data = FlashData {\n        kind: \"success\".to_owned(),\n        message: \"Post successfully added\".to_owned(),\n    };\n\n    Ok(post_response(&mut cookies, data))\n}\n\nasync fn edit_post(\n    state: State<AppState>,\n    Path(id): Path<i32>,\n) -> Result<Html<String>, (StatusCode, &'static str)> {\n    let post: post::Model = QueryService::find_post_by_id(&state.conn, id)\n        .await\n        .expect(\"could not find post\")\n        .unwrap_or_else(|| panic!(\"could not find post with id {id}\"));\n\n    let mut ctx = tera::Context::new();\n    ctx.insert(\"post\", &post);\n\n    let body = state\n        .templates\n        .render(\"edit.html.tera\", &ctx)\n        .map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, \"Template error\"))?;\n\n    Ok(Html(body))\n}\n\nasync fn update_post(\n    state: State<AppState>,\n    Path(id): Path<i32>,\n    mut cookies: Cookies,\n    form: Form<post::Model>,\n) -> Result<PostResponse, (StatusCode, String)> {\n    let form = form.0;\n\n    Mutation::update_post_by_id(&state.conn, id, form)\n        .await\n        .expect(\"could not edit post\");\n\n    let data = FlashData {\n        kind: \"success\".to_owned(),\n        message: \"Post successfully updated\".to_owned(),\n    };\n\n    Ok(post_response(&mut cookies, data))\n}\n\nasync fn delete_post(\n    state: State<AppState>,\n    Path(id): Path<i32>,\n    mut cookies: Cookies,\n) -> Result<PostResponse, (StatusCode, &'static str)> {\n    Mutation::delete_post(&state.conn, id)\n        .await\n        .expect(\"could not delete post\");\n\n    let data = FlashData {\n        kind: \"success\".to_owned(),\n        message: \"Post successfully deleted\".to_owned(),\n    };\n\n    Ok(post_response(&mut cookies, data))\n}\n\npub fn main() {\n    let result = start();\n\n    if let Some(err) = result.err() {\n        println!(\"Error: {err}\");\n    }\n}\n"
  },
  {
    "path": "examples/axum_example/api/src/service/mod.rs",
    "content": "mod mutation;\nmod query;\n\npub use mutation::*;\npub use query::*;\n"
  },
  {
    "path": "examples/axum_example/api/src/service/mutation.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Mutation;\n\nimpl Mutation {\n    pub async fn create_post(\n        db: &DbConn,\n        form_data: post::Model,\n    ) -> Result<post::ActiveModel, DbErr> {\n        post::ActiveModel {\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n            ..Default::default()\n        }\n        .save(db)\n        .await\n    }\n\n    pub async fn update_post_by_id(\n        db: &DbConn,\n        id: i32,\n        form_data: post::Model,\n    ) -> Result<post::Model, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post::ActiveModel {\n            id: post.id,\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n        }\n        .update(db)\n        .await\n    }\n\n    pub async fn delete_post(db: &DbConn, id: i32) -> Result<DeleteResult, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post.delete(db).await\n    }\n\n    pub async fn delete_all_posts(db: &DbConn) -> Result<DeleteResult, DbErr> {\n        Post::delete_many().exec(db).await\n    }\n}\n"
  },
  {
    "path": "examples/axum_example/api/src/service/query.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Query;\n\nimpl Query {\n    pub async fn find_post_by_id(db: &DbConn, id: i32) -> Result<Option<post::Model>, DbErr> {\n        Post::find_by_id(id).one(db).await\n    }\n\n    /// If ok, returns (post models, num pages).\n    pub async fn find_posts_in_page(\n        db: &DbConn,\n        page: u64,\n        posts_per_page: u64,\n    ) -> Result<(Vec<post::Model>, u64), DbErr> {\n        // Setup paginator\n        let paginator = Post::find()\n            .order_by_asc(post::Column::Id)\n            .paginate(db, posts_per_page);\n        let num_pages = paginator.num_pages().await?;\n\n        // Fetch paginated posts\n        paginator.fetch_page(page - 1).await.map(|p| (p, num_pages))\n    }\n}\n"
  },
  {
    "path": "examples/axum_example/api/static/css/normalize.css",
    "content": "/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\n\n/**\n * 1. Set default font family to sans-serif.\n * 2. Prevent iOS text size adjust after orientation change, without disabling\n *    user zoom.\n */\n\nhtml {\n  font-family: sans-serif; /* 1 */\n  -ms-text-size-adjust: 100%; /* 2 */\n  -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/**\n * Remove default margin.\n */\n\nbody {\n  margin: 0;\n}\n\n/* HTML5 display definitions\n   ========================================================================== */\n\n/**\n * Correct `block` display not defined for any HTML5 element in IE 8/9.\n * Correct `block` display not defined for `details` or `summary` in IE 10/11\n * and Firefox.\n * Correct `block` display not defined for `main` in IE 11.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n/**\n * 1. Correct `inline-block` display not defined in IE 8/9.\n * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n */\n\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block; /* 1 */\n  vertical-align: baseline; /* 2 */\n}\n\n/**\n * Prevent modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n/**\n * Address `[hidden]` styling not present in IE 8/9/10.\n * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.\n */\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n/* Links\n   ========================================================================== */\n\n/**\n * Remove the gray background color from active links in IE 10.\n */\n\na {\n  background-color: transparent;\n}\n\n/**\n * Improve readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n  outline: 0;\n}\n\n/* Text-level semantics\n   ========================================================================== */\n\n/**\n * Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n */\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n/**\n * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n */\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n/**\n * Address styling not present in Safari and Chrome.\n */\n\ndfn {\n  font-style: italic;\n}\n\n/**\n * Address variable `h1` font-size and margin within `section` and `article`\n * contexts in Firefox 4+, Safari, and Chrome.\n */\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n/**\n * Address styling not present in IE 8/9.\n */\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n/**\n * Address inconsistent and variable font size in all browsers.\n */\n\nsmall {\n  font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n/* Embedded content\n   ========================================================================== */\n\n/**\n * Remove border when inside `a` element in IE 8/9/10.\n */\n\nimg {\n  border: 0;\n}\n\n/**\n * Correct overflow not hidden in IE 9/10/11.\n */\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n/* Grouping content\n   ========================================================================== */\n\n/**\n * Address margin not present in IE 8/9 and Safari.\n */\n\nfigure {\n  margin: 1em 40px;\n}\n\n/**\n * Address differences between Firefox and other browsers.\n */\n\nhr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\n\n/**\n * Contain overflow in all browsers.\n */\n\npre {\n  overflow: auto;\n}\n\n/**\n * Address odd `em`-unit font size rendering in all browsers.\n */\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n/* Forms\n   ========================================================================== */\n\n/**\n * Known limitation: by default, Chrome and Safari on OS X allow very limited\n * styling of `select`, unless a `border` property is set.\n */\n\n/**\n * 1. Correct color not being inherited.\n *    Known issue: affects color of disabled elements.\n * 2. Correct font properties not being inherited.\n * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit; /* 1 */\n  font: inherit; /* 2 */\n  margin: 0; /* 3 */\n}\n\n/**\n * Address `overflow` set to `hidden` in IE 8/9/10/11.\n */\n\nbutton {\n  overflow: visible;\n}\n\n/**\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\n * All other form control elements do not inherit `text-transform` values.\n * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n * Correct `select` style inheritance in Firefox.\n */\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n/**\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *    and `video` controls.\n * 2. Correct inability to style clickable `input` types in iOS.\n * 3. Improve usability and consistency of cursor style between image-type\n *    `input` and others.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; /* 2 */\n  cursor: pointer; /* 3 */\n}\n\n/**\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n/**\n * Remove inner padding and border in Firefox 4+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n/**\n * Address Firefox 4+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\ninput {\n  line-height: normal;\n}\n\n/**\n * It's recommended that you don't attempt to style these elements.\n * Firefox's implementation doesn't respect box-sizing, padding, or width.\n *\n * 1. Address box sizing set to `content-box` in IE 8/9/10.\n * 2. Remove excess padding in IE 8/9/10.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Fix the cursor style for Chrome's increment/decrement buttons. For certain\n * `font-size` values of the `input`, it causes the cursor style of the\n * decrement button to change from `default` to `text`.\n */\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n/**\n * 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n * 2. Address `box-sizing` set to `border-box` in Safari and Chrome\n *    (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; /* 1 */\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box; /* 2 */\n  box-sizing: content-box;\n}\n\n/**\n * Remove inner padding and search cancel button in Safari and Chrome on OS X.\n * Safari (but not Chrome) clips the cancel button when the search input has\n * padding (and `textfield` appearance).\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n/**\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n/**\n * 1. Correct `color` not being inherited in IE 8/9/10/11.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\n\nlegend {\n  border: 0; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Remove default vertical scrollbar in IE 8/9/10/11.\n */\n\ntextarea {\n  overflow: auto;\n}\n\n/**\n * Don't inherit the `font-weight` (applied by a rule above).\n * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n */\n\noptgroup {\n  font-weight: bold;\n}\n\n/* Tables\n   ========================================================================== */\n\n/**\n * Remove most spacing between table cells.\n */\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n"
  },
  {
    "path": "examples/axum_example/api/static/css/skeleton.css",
    "content": "/*\n* Skeleton V2.0.4\n* Copyright 2014, Dave Gamache\n* www.getskeleton.com\n* Free to use under the MIT license.\n* https://opensource.org/licenses/mit-license.php\n* 12/29/2014\n*/\n\n\n/* Table of contents\n––––––––––––––––––––––––––––––––––––––––––––––––––\n- Grid\n- Base Styles\n- Typography\n- Links\n- Buttons\n- Forms\n- Lists\n- Code\n- Tables\n- Spacing\n- Utilities\n- Clearing\n- Media Queries\n*/\n\n\n/* Grid\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.container {\n  position: relative;\n  width: 100%;\n  max-width: 960px;\n  margin: 0 auto;\n  padding: 0 20px;\n  box-sizing: border-box; }\n.column,\n.columns {\n  width: 100%;\n  float: left;\n  box-sizing: border-box; }\n\n/* For devices larger than 400px */\n@media (min-width: 400px) {\n  .container {\n    width: 85%;\n    padding: 0; }\n}\n\n/* For devices larger than 550px */\n@media (min-width: 550px) {\n  .container {\n    width: 80%; }\n  .column,\n  .columns {\n    margin-left: 4%; }\n  .column:first-child,\n  .columns:first-child {\n    margin-left: 0; }\n\n  .one.column,\n  .one.columns                    { width: 4.66666666667%; }\n  .two.columns                    { width: 13.3333333333%; }\n  .three.columns                  { width: 22%;            }\n  .four.columns                   { width: 30.6666666667%; }\n  .five.columns                   { width: 39.3333333333%; }\n  .six.columns                    { width: 48%;            }\n  .seven.columns                  { width: 56.6666666667%; }\n  .eight.columns                  { width: 65.3333333333%; }\n  .nine.columns                   { width: 74.0%;          }\n  .ten.columns                    { width: 82.6666666667%; }\n  .eleven.columns                 { width: 91.3333333333%; }\n  .twelve.columns                 { width: 100%; margin-left: 0; }\n\n  .one-third.column               { width: 30.6666666667%; }\n  .two-thirds.column              { width: 65.3333333333%; }\n\n  .one-half.column                { width: 48%; }\n\n  /* Offsets */\n  .offset-by-one.column,\n  .offset-by-one.columns          { margin-left: 8.66666666667%; }\n  .offset-by-two.column,\n  .offset-by-two.columns          { margin-left: 17.3333333333%; }\n  .offset-by-three.column,\n  .offset-by-three.columns        { margin-left: 26%;            }\n  .offset-by-four.column,\n  .offset-by-four.columns         { margin-left: 34.6666666667%; }\n  .offset-by-five.column,\n  .offset-by-five.columns         { margin-left: 43.3333333333%; }\n  .offset-by-six.column,\n  .offset-by-six.columns          { margin-left: 52%;            }\n  .offset-by-seven.column,\n  .offset-by-seven.columns        { margin-left: 60.6666666667%; }\n  .offset-by-eight.column,\n  .offset-by-eight.columns        { margin-left: 69.3333333333%; }\n  .offset-by-nine.column,\n  .offset-by-nine.columns         { margin-left: 78.0%;          }\n  .offset-by-ten.column,\n  .offset-by-ten.columns          { margin-left: 86.6666666667%; }\n  .offset-by-eleven.column,\n  .offset-by-eleven.columns       { margin-left: 95.3333333333%; }\n\n  .offset-by-one-third.column,\n  .offset-by-one-third.columns    { margin-left: 34.6666666667%; }\n  .offset-by-two-thirds.column,\n  .offset-by-two-thirds.columns   { margin-left: 69.3333333333%; }\n\n  .offset-by-one-half.column,\n  .offset-by-one-half.columns     { margin-left: 52%; }\n\n}\n\n\n/* Base Styles\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n/* NOTE\nhtml is set to 62.5% so that all the REM measurements throughout Skeleton\nare based on 10px sizing. So basically 1.5rem = 15px :) */\nhtml {\n  font-size: 62.5%; }\nbody {\n  font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */\n  line-height: 1.6;\n  font-weight: 400;\n  font-family: \"Raleway\", \"HelveticaNeue\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  color: #222; }\n\n\n/* Typography\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nh1, h2, h3, h4, h5, h6 {\n  margin-top: 0;\n  margin-bottom: 2rem;\n  font-weight: 300; }\nh1 { font-size: 4.0rem; line-height: 1.2;  letter-spacing: -.1rem;}\nh2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; }\nh3 { font-size: 3.0rem; line-height: 1.3;  letter-spacing: -.1rem; }\nh4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; }\nh5 { font-size: 1.8rem; line-height: 1.5;  letter-spacing: -.05rem; }\nh6 { font-size: 1.5rem; line-height: 1.6;  letter-spacing: 0; }\n\n/* Larger than phablet */\n@media (min-width: 550px) {\n  h1 { font-size: 5.0rem; }\n  h2 { font-size: 4.2rem; }\n  h3 { font-size: 3.6rem; }\n  h4 { font-size: 3.0rem; }\n  h5 { font-size: 2.4rem; }\n  h6 { font-size: 1.5rem; }\n}\n\np {\n  margin-top: 0; }\n\n\n/* Links\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\na {\n  color: #1EAEDB; }\na:hover {\n  color: #0FA0CE; }\n\n\n/* Buttons\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.button,\nbutton,\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n  display: inline-block;\n  height: 38px;\n  padding: 0 30px;\n  color: #555;\n  text-align: center;\n  font-size: 11px;\n  font-weight: 600;\n  line-height: 38px;\n  letter-spacing: .1rem;\n  text-transform: uppercase;\n  text-decoration: none;\n  white-space: nowrap;\n  background-color: transparent;\n  border-radius: 4px;\n  border: 1px solid #bbb;\n  cursor: pointer;\n  box-sizing: border-box; }\n.button:hover,\nbutton:hover,\ninput[type=\"submit\"]:hover,\ninput[type=\"reset\"]:hover,\ninput[type=\"button\"]:hover,\n.button:focus,\nbutton:focus,\ninput[type=\"submit\"]:focus,\ninput[type=\"reset\"]:focus,\ninput[type=\"button\"]:focus {\n  color: #333;\n  border-color: #888;\n  outline: 0; }\n.button.button-primary,\nbutton.button-primary,\nbutton.primary,\ninput[type=\"submit\"].button-primary,\ninput[type=\"reset\"].button-primary,\ninput[type=\"button\"].button-primary {\n  color: #FFF;\n  background-color: #33C3F0;\n  border-color: #33C3F0; }\n.button.button-primary:hover,\nbutton.button-primary:hover,\nbutton.primary:hover,\ninput[type=\"submit\"].button-primary:hover,\ninput[type=\"reset\"].button-primary:hover,\ninput[type=\"button\"].button-primary:hover,\n.button.button-primary:focus,\nbutton.button-primary:focus,\nbutton.primary:focus,\ninput[type=\"submit\"].button-primary:focus,\ninput[type=\"reset\"].button-primary:focus,\ninput[type=\"button\"].button-primary:focus {\n  color: #FFF;\n  background-color: #1EAEDB;\n  border-color: #1EAEDB; }\n\n\n/* Forms\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ninput[type=\"text\"],\ninput[type=\"tel\"],\ninput[type=\"url\"],\ninput[type=\"password\"],\ntextarea,\nselect {\n  height: 38px;\n  padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */\n  background-color: #fff;\n  border: 1px solid #D1D1D1;\n  border-radius: 4px;\n  box-shadow: none;\n  box-sizing: border-box; }\n/* Removes awkward default styles on some inputs for iOS */\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ninput[type=\"text\"],\ninput[type=\"tel\"],\ninput[type=\"url\"],\ninput[type=\"password\"],\ntextarea {\n  -webkit-appearance: none;\n     -moz-appearance: none;\n          appearance: none; }\ntextarea {\n  min-height: 65px;\n  padding-top: 6px;\n  padding-bottom: 6px; }\ninput[type=\"email\"]:focus,\ninput[type=\"number\"]:focus,\ninput[type=\"search\"]:focus,\ninput[type=\"text\"]:focus,\ninput[type=\"tel\"]:focus,\ninput[type=\"url\"]:focus,\ninput[type=\"password\"]:focus,\ntextarea:focus,\nselect:focus {\n  border: 1px solid #33C3F0;\n  outline: 0; }\nlabel,\nlegend {\n  display: block;\n  margin-bottom: .5rem;\n  font-weight: 600; }\nfieldset {\n  padding: 0;\n  border-width: 0; }\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  display: inline; }\nlabel > .label-body {\n  display: inline-block;\n  margin-left: .5rem;\n  font-weight: normal; }\n\n\n/* Lists\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nul {\n  list-style: circle inside; }\nol {\n  list-style: decimal inside; }\nol, ul {\n  padding-left: 0;\n  margin-top: 0; }\nul ul,\nul ol,\nol ol,\nol ul {\n  margin: 1.5rem 0 1.5rem 3rem;\n  font-size: 90%; }\nli {\n  margin-bottom: 1rem; }\n\n\n/* Code\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\ncode {\n  padding: .2rem .5rem;\n  margin: 0 .2rem;\n  font-size: 90%;\n  white-space: nowrap;\n  background: #F1F1F1;\n  border: 1px solid #E1E1E1;\n  border-radius: 4px; }\npre > code {\n  display: block;\n  padding: 1rem 1.5rem;\n  white-space: pre; }\n\n\n/* Tables\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nth,\ntd {\n  padding: 12px 15px;\n  text-align: left;\n  border-bottom: 1px solid #E1E1E1; }\nth:first-child,\ntd:first-child {\n  padding-left: 0; }\nth:last-child,\ntd:last-child {\n  padding-right: 0; }\n\n\n/* Spacing\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nbutton,\n.button {\n  margin-bottom: 1rem; }\ninput,\ntextarea,\nselect,\nfieldset {\n  margin-bottom: 1.5rem; }\npre,\nblockquote,\ndl,\nfigure,\ntable,\np,\nul,\nol,\nform {\n  margin-bottom: 2.5rem; }\n\n\n/* Utilities\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.u-full-width {\n  width: 100%;\n  box-sizing: border-box; }\n.u-max-full-width {\n  max-width: 100%;\n  box-sizing: border-box; }\n.u-pull-right {\n  float: right; }\n.u-pull-left {\n  float: left; }\n\n\n/* Misc\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nhr {\n  margin-top: 3rem;\n  margin-bottom: 3.5rem;\n  border-width: 0;\n  border-top: 1px solid #E1E1E1; }\n\n\n/* Clearing\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n\n/* Self Clearing Goodness */\n.container:after,\n.row:after,\n.u-cf {\n  content: \"\";\n  display: table;\n  clear: both; }\n\n\n/* Media Queries\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n/*\nNote: The best way to structure the use of media queries is to create the queries\nnear the relevant code. For example, if you wanted to change the styles for buttons\non small devices, paste the mobile query code up in the buttons section and style it\nthere.\n*/\n\n\n/* Larger than mobile */\n@media (min-width: 400px) {}\n\n/* Larger than phablet (also point when grid becomes active) */\n@media (min-width: 550px) {}\n\n/* Larger than tablet */\n@media (min-width: 750px) {}\n\n/* Larger than desktop */\n@media (min-width: 1000px) {}\n\n/* Larger than Desktop HD */\n@media (min-width: 1200px) {}\n"
  },
  {
    "path": "examples/axum_example/api/static/css/style.css",
    "content": ".field-error {\n  border: 1px solid #ff0000 !important;\n}\n\n.field-error-flash {\n  color: #ff0000;\n  display: block;\n  margin: -10px 0 10px 0;\n}\n\n.field-success {\n  border: 1px solid #5ab953 !important;\n}\n\n.field-success-flash {\n  color: #5ab953;\n  display: block;\n  margin: -10px 0 10px 0;\n}\n\nspan.completed {\n  text-decoration: line-through;\n}\n\nform.inline {\n  display: inline;\n}\n\nform.link,\nbutton.link {\n  display: inline;\n  color: #1eaedb;\n  border: none;\n  outline: none;\n  background: none;\n  cursor: pointer;\n  padding: 0;\n  margin: 0 0 0 0;\n  height: inherit;\n  text-decoration: underline;\n  font-size: inherit;\n  text-transform: none;\n  font-weight: normal;\n  line-height: inherit;\n  letter-spacing: inherit;\n}\n\nform.link:hover,\nbutton.link:hover {\n  color: #0fa0ce;\n}\n\nbutton.small {\n  height: 20px;\n  padding: 0 10px;\n  font-size: 10px;\n  line-height: 20px;\n  margin: 0 2.5px;\n}\n\n.post:hover {\n  background-color: #bce2ee;\n}\n\n.post td {\n  padding: 5px;\n  width: 150px;\n}\n\n#delete-button {\n  color: red;\n  border-color: red;\n}\n"
  },
  {
    "path": "examples/axum_example/api/templates/edit.html.tera",
    "content": "{% extends \"layout.html.tera\" %} {% block content %}\n<div class=\"row\">\n  <h4>Edit Post</h4>\n  <div class=\"twelve columns\">\n    <div class=\"ten columns\">\n      <form action=\"/{{ post.id }}\" method=\"post\">\n        <div class=\"twelve columns\">\n          <input\n            type=\"text\"\n            placeholder=\"title\"\n            name=\"title\"\n            id=\"title\"\n            value=\"{{ post.title }}\"\n            autofocus\n            class=\"u-full-width\"\n          />\n          <input\n            type=\"text\"\n            placeholder=\"content\"\n            name=\"text\"\n            id=\"text\"\n            value=\"{{ post.text }}\"\n            autofocus\n            class=\"u-full-width\"\n          />\n        </div>\n        <div class=\"twelve columns\">\n          <div class=\"two columns\">\n            <a href=\"/\">\n              <input type=\"button\" value=\"cancel\" />\n            </a>\n          </div>\n          <div class=\"eight columns\"></div>\n          <div class=\"two columns\">\n            <input type=\"submit\" value=\"save post\" />\n          </div>\n        </div>\n      </form>\n    </div>\n    <div class=\"two columns\">\n      <form action=\"/delete/{{ post.id }}\" method=\"post\">\n        <div class=\"two columns\">\n          <input id=\"delete-button\" type=\"submit\" value=\"delete post\" />\n        </div>\n      </form>\n    </div>\n  </div>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/axum_example/api/templates/error/404.html.tera",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>404 - tera</title>\n  </head>\n  <body>\n    <h1>404: Hey! There's nothing here.</h1>\n    The page at {{ uri }} does not exist!\n  </body>\n</html>\n"
  },
  {
    "path": "examples/axum_example/api/templates/index.html.tera",
    "content": "{% extends \"layout.html.tera\" %} {% block content %}\n<div class=\"container\">\n  <p><!--Nothing to see here --></p>\n  <h1>Posts</h1>\n  {% if flash %}\n  <small class=\"field-{{ flash.kind }}-flash\">\n    {{ flash.message }}\n  </small>\n  {% endif %}\n  <table>\n    <tbody>\n      <thead>\n        <tr>\n          <th>ID</th>\n          <th>Title</th>\n          <th>Text</th>\n        </tr>\n      </thead>\n      {% for post in posts %}\n      <tr class=\"post\" onclick=\"window.location='/{{ post.id }}';\">\n        <td>{{ post.id }}</td>\n        <td>{{ post.title }}</td>\n        <td>{{ post.text }}</td>\n      </tr>\n      {% endfor %}\n    </tbody>\n    <tfoot>\n      <tr>\n        <td></td>\n        <td>\n          {% if page == 1 %} Previous {% else %}\n          <a href=\"/?page={{ page - 1 }}&posts_per_page={{ posts_per_page }}\"\n            >Previous</a\n          >\n          {% endif %} | {% if page == num_pages %} Next {% else %}\n          <a href=\"/?page={{ page + 1 }}&posts_per_page={{ posts_per_page }}\"\n            >Next</a\n          >\n          {% endif %}\n        </td>\n        <td></td>\n      </tr>\n    </tfoot>\n  </table>\n\n  <div class=\"twelve columns\">\n    <a href=\"/new\">\n      <input type=\"button\" value=\"add post\" />\n    </a>\n  </div>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/axum_example/api/templates/layout.html.tera",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>Axum Example</title>\n    <meta name=\"description\" content=\"Axum - SeaOrm integration example\" />\n    <meta name=\"author\" content=\"Yoshiera Huang\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\n    <link\n      href=\"//fonts.googleapis.com/css?family=Raleway:400,300,600\"\n      rel=\"stylesheet\"\n      type=\"text/css\"\n    />\n    <link rel=\"stylesheet\" href=\"/static/css/normalize.css\" />\n    <link rel=\"stylesheet\" href=\"/static/css/skeleton.css\" />\n    <link rel=\"stylesheet\" href=\"/static/css/style.css\" />\n    <link rel=\"icon\" type=\"image/png\" href=\"/static/images/favicon.png\" />\n  </head>\n  <body>\n    <div class=\"container\">\n      <p><!--Nothing to see here --></p>\n      {% block content %}{% endblock content %}\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/axum_example/api/templates/new.html.tera",
    "content": "{% extends \"layout.html.tera\" %} {% block content %}\n<div class=\"row\">\n  <h4>New Post</h4>\n  <form action=\"/\" method=\"post\">\n    <div class=\"twelve columns\">\n      <input\n        type=\"text\"\n        placeholder=\"enter title\"\n        name=\"title\"\n        id=\"title\"\n        value=\"\"\n        autofocus\n        class=\"u-full-width\"\n      />\n      <input\n        type=\"text\"\n        placeholder=\"enter content\"\n        name=\"text\"\n        id=\"text\"\n        value=\"\"\n        autofocus\n        class=\"u-full-width\"\n      />\n    </div>\n    <div class=\"twelve columns\">\n      <div class=\"two columns\">\n        <a href=\"/\">\n          <input type=\"button\" value=\"cancel\" />\n        </a>\n      </div>\n      <div class=\"eight columns\"></div>\n      <div class=\"two columns\">\n        <input type=\"submit\" value=\"save post\" />\n      </div>\n    </div>\n  </form>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/axum_example/api/tests/crud_tests.rs",
    "content": "use axum_example_api::service::{Mutation, Query};\nuse entity::post;\nuse sea_orm::Database;\n\n#[tokio::test]\nasync fn crud_tests() {\n    let db = &Database::connect(\"sqlite::memory:\").await.unwrap();\n\n    db.get_schema_builder()\n        .register(post::Entity)\n        .apply(db)\n        .await\n        .unwrap();\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title A\".to_owned(),\n                text: \"Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(1),\n                title: sea_orm::ActiveValue::Unchanged(\"Title A\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text A\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title B\".to_owned(),\n                text: \"Text B\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(2),\n                title: sea_orm::ActiveValue::Unchanged(\"Title B\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text B\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 1).await.unwrap().unwrap();\n\n        assert_eq!(post.id, 1);\n        assert_eq!(post.title, \"Title A\");\n    }\n\n    {\n        let post = Mutation::update_post_by_id(\n            db,\n            1,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            }\n        );\n    }\n\n    {\n        let result = Mutation::delete_post(db, 2).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 2).await.unwrap();\n        assert!(post.is_none());\n    }\n\n    {\n        let result = Mutation::delete_all_posts(db).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n}\n"
  },
  {
    "path": "examples/axum_example/entity/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"entity\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"entity\"\npath = \"src/lib.rs\"\n\n[dependencies]\nserde = { version = \"1\", features = [\"derive\"] }\n\n[dependencies.sea-orm]\npath    = \"../../../\"    # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n"
  },
  {
    "path": "examples/axum_example/entity/src/lib.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub mod prelude;\n\npub mod post;\n"
  },
  {
    "path": "examples/axum_example/entity/src/post.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"post\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    pub title: String,\n    #[sea_orm(column_type = \"Text\")]\n    pub text: String,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/axum_example/entity/src/prelude.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub use super::post::Entity as Post;\n"
  },
  {
    "path": "examples/axum_example/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nentity = { path = \"../entity\" }\ntokio  = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable following runtime and db backend features if you want to run migration via CLI\n    \"runtime-tokio-native-tls\",\n    \"sqlx-postgres\",\n]\npath = \"../../../sea-orm-migration\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/axum_example/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/axum_example/migration/src/lib.rs",
    "content": "pub use sea_orm_migration::prelude::*;\n\nmod m20220120_000001_create_post_table;\nmod m20220120_000002_seed_posts;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220120_000001_create_post_table::Migration),\n            Box::new(m20220120_000002_seed_posts::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "examples/axum_example/migration/src/m20220120_000001_create_post_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"post\")\n                    .if_not_exists()\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"title\"))\n                    .col(string(\"text\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"post\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/axum_example/migration/src/m20220120_000002_seed_posts.rs",
    "content": "use entity::post;\nuse sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};\nuse sea_orm_migration::prelude::*;\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let seed_data = vec![\n            (\"First Post\", \"This is the first post.\"),\n            (\"Second Post\", \"This is another post.\"),\n        ];\n\n        for (title, text) in seed_data {\n            let model = post::ActiveModel {\n                title: Set(title.to_string()),\n                text: Set(text.to_string()),\n                ..Default::default()\n            };\n            model.insert(db).await?;\n        }\n\n        println!(\"Posts table seeded successfully.\");\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let titles_to_delete = vec![\"First Post\", \"Second Post\"];\n        post::Entity::delete_many()\n            .filter(post::Column::Title.is_in(titles_to_delete))\n            .exec(db)\n            .await?;\n\n        println!(\"Posts seeded data removed.\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/axum_example/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/axum_example/src/main.rs",
    "content": "fn main() {\n    axum_example_api::main();\n}\n"
  },
  {
    "path": "examples/basic/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-example-basic\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nfutures-util = { version = \"0.3\" }\nsea-orm = { path = \"../../\", features = [\n    \"sqlx-mysql\",\n    \"runtime-tokio-native-tls\",\n] }\nserde_json = { version = \"1\" }\ntokio = { version = \"1\", features = [\"full\"] }\n"
  },
  {
    "path": "examples/basic/Readme.md",
    "content": "# SeaORM MySQL example\n\nPrepare:\n\nSetup a test database and configure the connection string in `main.rs`.\nRun `bakery.sql` to setup the test table and data.\n\nRunning: `cargo run`\n\n```sh\nfind all cakes: SELECT `cake`.`id`, `cake`.`name` FROM `cake`\n\nModel { id: 1, name: \"New York Cheese\" }\n\nModel { id: 2, name: \"Chocolate Forest\" }\n\nfind all fruits: SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\n\nModel { id: 1, name: \"Blueberry\", cake_id: Some(1) }\n\nModel { id: 2, name: \"Raspberry\", cake_id: Some(1) }\n\nModel { id: 3, name: \"Strawberry\", cake_id: Some(2) }\n\nModel { id: 4, name: \"Apple\", cake_id: None }\n\nModel { id: 5, name: \"Banana\", cake_id: None }\n\nModel { id: 6, name: \"Cherry\", cake_id: None }\n\nModel { id: 7, name: \"Lemon\", cake_id: None }\n\nModel { id: 8, name: \"Orange\", cake_id: None }\n\nModel { id: 9, name: \"Pineapple\", cake_id: None }\n\n===== =====\n\nfind one by primary key: SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = 1 LIMIT 1\n\nModel { id: 1, name: \"New York Cheese\" }\n\nfind one by name: SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE '%chocolate%' LIMIT 1\n\nSome(Model { id: 2, name: \"Chocolate Forest\" })\n\nfind models belong to: SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` INNER JOIN `cake` ON `cake`.`id` = `fruit`.`cake_id` WHERE `cake`.`id` = 1\n\nModel { id: 1, name: \"Blueberry\", cake_id: Some(1) }\n\nModel { id: 2, name: \"Raspberry\", cake_id: Some(1) }\n\n===== =====\n\nfind fruits and cakes: SELECT `fruit`.`id` AS `A_id`, `fruit`.`name` AS `A_name`, `fruit`.`cake_id` AS `A_cake_id`, `cake`.`id` AS `B_id`, `cake`.`name` AS `B_name` FROM `fruit` LEFT JOIN `cake` ON `fruit`.`cake_id` = `cake`.`id`\nwith loader: \nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\nSELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` IN (1, 1, 2, NULL, NULL, NULL, NULL, NULL, NULL)\n\n(Model { id: 1, name: \"Blueberry\", cake_id: Some(1) }, Some(Model { id: 1, name: \"New York Cheese\" }))\n(Model { id: 2, name: \"Raspberry\", cake_id: Some(1) }, Some(Model { id: 1, name: \"New York Cheese\" }))\n(Model { id: 3, name: \"Strawberry\", cake_id: Some(2) }, Some(Model { id: 2, name: \"Chocolate Forest\" }))\n(Model { id: 4, name: \"Apple\", cake_id: None }, None)\n(Model { id: 5, name: \"Banana\", cake_id: None }, None)\n(Model { id: 6, name: \"Cherry\", cake_id: None }, None)\n(Model { id: 7, name: \"Lemon\", cake_id: None }, None)\n(Model { id: 8, name: \"Orange\", cake_id: None }, None)\n(Model { id: 9, name: \"Pineapple\", cake_id: None }, None)\n===== =====\n\nfind cakes with fruits: SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`, `fruit`.`id` AS `B_id`, `fruit`.`name` AS `B_name`, `fruit`.`cake_id` AS `B_cake_id` FROM `cake` LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` ORDER BY `cake`.`id` ASC\nwith loader: \nSELECT `cake`.`id`, `cake`.`name` FROM `cake`\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`cake_id` IN (1, 2)\n\n(Model { id: 1, name: \"New York Cheese\" }, [Model { id: 1, name: \"Blueberry\", cake_id: Some(1) }, Model { id: 2, name: \"Raspberry\", cake_id: Some(1) }])\n\n(Model { id: 2, name: \"Chocolate Forest\" }, [Model { id: 3, name: \"Strawberry\", cake_id: Some(2) }])\n\n===== =====\n\ncount fruits by cake: SELECT `cake`.`name`, COUNT(`fruit`.`id`) AS `num_of_fruits` FROM `cake` LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` GROUP BY `cake`.`name`\n\nSelectResult { name: \"New York Cheese\", num_of_fruits: 2 }\n\nSelectResult { name: \"Chocolate Forest\", num_of_fruits: 1 }\n\n===== =====\n\nfind cakes and fillings: SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`, `filling`.`id` AS `B_id`, `filling`.`name` AS `B_name` FROM `cake` LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id` LEFT JOIN `filling` ON `cake_filling`.`filling_id` = `filling`.`id` ORDER BY `cake`.`id` ASC\nwith loader: \nSELECT `cake`.`id`, `cake`.`name` FROM `cake`\nSELECT `cake_filling`.`cake_id`, `cake_filling`.`filling_id` FROM `cake_filling` WHERE `cake_filling`.`cake_id` IN (1, 2)\nSELECT `filling`.`id`, `filling`.`name` FROM `filling` WHERE `filling`.`id` IN (1, 2, 2, 3)\n\n(Model { id: 1, name: \"New York Cheese\" }, [Model { id: 1, name: \"Vanilla\" }, Model { id: 2, name: \"Lemon\" }])\n\n(Model { id: 2, name: \"Chocolate Forest\" }, [Model { id: 2, name: \"Lemon\" }, Model { id: 3, name: \"Mango\" }])\n\nfind fillings for cheese cake: SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = 1 LIMIT 1\nSELECT `filling`.`id`, `filling`.`name` FROM `filling` INNER JOIN `cake_filling` ON `cake_filling`.`filling_id` = `filling`.`id` INNER JOIN `cake` ON `cake`.`id` = `cake_filling`.`cake_id` WHERE `cake`.`id` = 1\n\nModel { id: 1, name: \"Vanilla\" }\n\nModel { id: 2, name: \"Lemon\" }\n\nfind cakes for lemon: SELECT `filling`.`id`, `filling`.`name` FROM `filling` WHERE `filling`.`id` = 2 LIMIT 1\nSELECT `cake`.`id`, `cake`.`name` FROM `cake` INNER JOIN `cake_filling` ON `cake_filling`.`cake_id` = `cake`.`id` INNER JOIN `filling` ON `filling`.`id` = `cake_filling`.`filling_id` WHERE `filling`.`id` = 2\n\nModel { id: 1, name: \"New York Cheese\" }\n\nModel { id: 2, name: \"Chocolate Forest\" }\n\n===== =====\n\nfind all cakes paginated: \nSELECT `cake`.`id`, `cake`.`name` FROM `cake` LIMIT 3 OFFSET 0\nModel { id: 1, name: \"New York Cheese\" }\nModel { id: 2, name: \"Chocolate Forest\" }\nSELECT `cake`.`id`, `cake`.`name` FROM `cake` LIMIT 3 OFFSET 3\n\nfind all fruits paginated: \nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 0\nModel { id: 1, name: \"Blueberry\", cake_id: Some(1) }\nModel { id: 2, name: \"Raspberry\", cake_id: Some(1) }\nModel { id: 3, name: \"Strawberry\", cake_id: Some(2) }\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 3\nModel { id: 4, name: \"Apple\", cake_id: None }\nModel { id: 5, name: \"Banana\", cake_id: None }\nModel { id: 6, name: \"Cherry\", cake_id: None }\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 6\nModel { id: 7, name: \"Lemon\", cake_id: None }\nModel { id: 8, name: \"Orange\", cake_id: None }\nModel { id: 9, name: \"Pineapple\", cake_id: None }\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 9\n\nfind all fruits with stream: \nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 0\nModel { id: 1, name: \"Blueberry\", cake_id: Some(1) }\nModel { id: 2, name: \"Raspberry\", cake_id: Some(1) }\nModel { id: 3, name: \"Strawberry\", cake_id: Some(2) }\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 3\nModel { id: 4, name: \"Apple\", cake_id: None }\nModel { id: 5, name: \"Banana\", cake_id: None }\nModel { id: 6, name: \"Cherry\", cake_id: None }\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 6\nModel { id: 7, name: \"Lemon\", cake_id: None }\nModel { id: 8, name: \"Orange\", cake_id: None }\nModel { id: 9, name: \"Pineapple\", cake_id: None }\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 9\n\nfind all fruits in json with stream: \nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 0\nObject {\"cake_id\": Number(1), \"id\": Number(1), \"name\": String(\"Blueberry\")}\nObject {\"cake_id\": Number(1), \"id\": Number(2), \"name\": String(\"Raspberry\")}\nObject {\"cake_id\": Number(2), \"id\": Number(3), \"name\": String(\"Strawberry\")}\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 3\nObject {\"cake_id\": Null, \"id\": Number(4), \"name\": String(\"Apple\")}\nObject {\"cake_id\": Null, \"id\": Number(5), \"name\": String(\"Banana\")}\nObject {\"cake_id\": Null, \"id\": Number(6), \"name\": String(\"Cherry\")}\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 6\nObject {\"cake_id\": Null, \"id\": Number(7), \"name\": String(\"Lemon\")}\nObject {\"cake_id\": Null, \"id\": Number(8), \"name\": String(\"Orange\")}\nObject {\"cake_id\": Null, \"id\": Number(9), \"name\": String(\"Pineapple\")}\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 9\n===== =====\n\nfruits first page: \nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` LIMIT 3 OFFSET 0\nModel { id: 1, name: \"Blueberry\", cake_id: Some(1) }\nModel { id: 2, name: \"Raspberry\", cake_id: Some(1) }\nModel { id: 3, name: \"Strawberry\", cake_id: Some(2) }\n===== =====\n\nfruits number of page: \nSELECT COUNT(*) AS num_items FROM (SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`) AS `sub_query`\n3\n===== =====\n\nINSERT INTO `fruit` (`name`) VALUES ('pear')\nInserted: last_insert_id = 64\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = 64 LIMIT 1\nPear: Some(Model { id: 64, name: \"pear\", cake_id: None })\nUPDATE `fruit` SET `name` = 'Sweet pear' WHERE `fruit`.`id` = 64\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = 64 LIMIT 1\nUpdated: Model { id: 64, name: \"Sweet pear\", cake_id: None }\nDELETE FROM `fruit` WHERE `fruit`.`id` = 64\nDeleted: DeleteResult { rows_affected: 1 }\n===== =====\n\nINSERT INTO `fruit` (`name`) VALUES ('Banana')\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = 65 LIMIT 1\nInserted: ActiveModel { id: Unchanged(65), name: Unchanged(\"Banana\"), cake_id: Unchanged(None) }\nUPDATE `fruit` SET `name` = 'Banana Mongo' WHERE `fruit`.`id` = 65\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = 65 LIMIT 1\nUpdated: ActiveModel { id: Unchanged(65), name: Unchanged(\"Banana Mongo\"), cake_id: Unchanged(None) }\nDELETE FROM `fruit` WHERE `fruit`.`id` = 65\nDeleted: DeleteResult { rows_affected: 1 }\n===== =====\n\nINSERT INTO `fruit` (`name`) VALUES ('Pineapple')\nSELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = 66 LIMIT 1\nSaved: ActiveModel { id: Unchanged(66), name: Unchanged(\"Pineapple\"), cake_id: Unchanged(None) }\nDELETE FROM `fruit` WHERE `fruit`.`id` = 66\nDeleted: DeleteResult { rows_affected: 1 }\n```"
  },
  {
    "path": "examples/basic/bakery.sql",
    "content": "DROP TABLE IF EXISTS `cake`;\n\nCREATE TABLE `cake` (\n  `id` int NOT NULL AUTO_INCREMENT,\n  `name` varchar(255) NOT NULL,\n  PRIMARY KEY (`id`)\n);\n\nINSERT INTO `cake` (`id`, `name`) VALUES\n\t(1, 'New York Cheese'),\n\t(2, 'Chocolate Forest');\n\nDROP TABLE IF EXISTS `fruit`;\n\nCREATE TABLE `fruit` (\n  `id` int NOT NULL AUTO_INCREMENT,\n  `name` varchar(255) NOT NULL,\n  `cake_id` int DEFAULT NULL,\n  PRIMARY KEY (`id`),\n  CONSTRAINT `fk-fruit-cake` FOREIGN KEY (`cake_id`) REFERENCES `cake` (`id`)\n);\n\nINSERT INTO `fruit` (`id`, `name`, `cake_id`) VALUES\n  (1, 'Blueberry', 1),\n  (2, 'Raspberry', 1),\n  (3, 'Strawberry', 2);\n\nINSERT INTO `fruit` (`name`, `cake_id`) VALUES\n  ('Apple', NULL),\n  ('Banana', NULL),\n  ('Cherry', NULL),\n  ('Lemon', NULL),\n  ('Orange', NULL),\n  ('Pineapple', NULL);\n\nDROP TABLE IF EXISTS `filling`;\n\nCREATE TABLE `filling` (\n  `id` int NOT NULL AUTO_INCREMENT,\n  `name` varchar(255) NOT NULL,\n  PRIMARY KEY (`id`)\n);\n\nINSERT INTO `filling` (`id`, `name`) VALUES\n  (1, 'Vanilla'),\n  (2, 'Lemon'),\n  (3, 'Mango');\n\nDROP TABLE IF EXISTS `cake_filling`;\n\nCREATE TABLE `cake_filling` (\n  `cake_id` int NOT NULL,\n  `filling_id` int NOT NULL,\n  PRIMARY KEY (`cake_id`, `filling_id`),\n  CONSTRAINT `fk-cake_filling-cake` FOREIGN KEY (`cake_id`) REFERENCES `cake` (`id`),\n  CONSTRAINT `fk-cake_filling-filling` FOREIGN KEY (`filling_id`) REFERENCES `filling` (`id`)\n);\n\nINSERT INTO `cake_filling` (`cake_id`, `filling_id`) VALUES\n  (1, 1),\n  (1, 2),\n  (2, 2),\n  (2, 3);"
  },
  {
    "path": "examples/basic/src/entity/cake.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String>,\n    #[sea_orm(has_many)]\n    pub fruits: HasMany<super::fruit::Entity>,\n    #[sea_orm(has_many, via = \"cake_filling\")]\n    pub fillings: HasMany<super::filling::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/basic/src/entity/cake_filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake_filling\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub filling_id: i32,\n    #[sea_orm(\n        belongs_to,\n        from = \"cake_id\",\n        to = \"id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    pub cake: HasOne<super::cake::Entity>,\n    #[sea_orm(\n        belongs_to,\n        from = \"filling_id\",\n        to = \"id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    pub filling: HasOne<super::filling::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/basic/src/entity/filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"filling\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(has_many, via = \"cake_filling\")]\n    pub cakes: HasMany<super::cake::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/basic/src/entity/fruit.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"fruit\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub cake_id: Option<i32>,\n    #[sea_orm(belongs_to, from = \"cake_id\", to = \"id\")]\n    pub cake: HasOne<super::cake::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/basic/src/entity/mod.rs",
    "content": "pub mod cake;\npub mod cake_filling;\npub mod filling;\npub mod fruit;\n\npub mod sea_orm_active_enums;\n\npub use cake::Entity as Cake;\npub use cake_filling::Entity as CakeFilling;\npub use filling::Entity as Filling;\npub use fruit::Entity as Fruit;\n"
  },
  {
    "path": "examples/basic/src/entity/sea_orm_active_enums.rs",
    "content": "//! SeaORM's active enums.\n\nuse sea_orm::entity::prelude::*;\n\n/// Tea active enum\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"tea\")]\npub enum Tea {\n    /// EverydayTea variant\n    #[sea_orm(string_value = \"EverydayTea\")]\n    EverydayTea,\n    /// BreakfastTea variant\n    #[sea_orm(string_value = \"BreakfastTea\")]\n    BreakfastTea,\n}\n"
  },
  {
    "path": "examples/basic/src/main.rs",
    "content": "//! Basic sea-orm example.\n\n#![deny(missing_docs)]\n\nuse sea_orm::Database;\n\nmod entity;\nmod mutation;\nmod query;\n\nuse entity::*;\nuse mutation::*;\nuse query::*;\n\n#[tokio::main]\nasync fn main() {\n    let db = Database::connect(\n        std::env::var(\"DATABASE_URL\")\n            .unwrap_or_else(|_| \"mysql://sea:sea@localhost/bakery\".to_owned()),\n    )\n    .await\n    .unwrap();\n\n    println!(\"{db:?}\\n\");\n\n    println!(\"===== =====\\n\");\n\n    all_about_query(&db).await.unwrap();\n\n    println!(\"===== =====\\n\");\n\n    all_about_mutation(&db).await.unwrap();\n}\n"
  },
  {
    "path": "examples/basic/src/mutation.rs",
    "content": "use super::*;\nuse sea_orm::{DbConn, entity::*, error::*};\n\npub async fn all_about_mutation(db: &DbConn) -> Result<(), DbErr> {\n    insert_and_update(db).await?;\n\n    println!(\"===== =====\\n\");\n\n    save_active_model(db).await?;\n\n    println!(\"===== =====\\n\");\n\n    save_custom_active_model(db).await?;\n\n    Ok(())\n}\n\npub async fn insert_and_update(db: &DbConn) -> Result<(), DbErr> {\n    let pear = fruit::ActiveModel {\n        name: Set(\"pear\".to_owned()),\n        ..Default::default()\n    };\n    let res = Fruit::insert(pear).exec(db).await?;\n\n    println!(\"Inserted: last_insert_id = {}\", res.last_insert_id);\n\n    let pear: Option<fruit::Model> = Fruit::find_by_id(res.last_insert_id).one(db).await?;\n\n    println!(\"Pear: {pear:?}\");\n\n    let mut pear: fruit::ActiveModel = pear.unwrap().into();\n    pear.name = Set(\"Sweet pear\".to_owned());\n\n    let pear: fruit::Model = pear.update(db).await?;\n\n    println!(\"Updated: {pear:?}\");\n\n    let result = pear.delete(db).await?;\n\n    println!(\"Deleted: {result:?}\");\n\n    Ok(())\n}\n\npub async fn save_active_model(db: &DbConn) -> Result<(), DbErr> {\n    let banana = fruit::ActiveModel {\n        name: Set(\"Banana\".to_owned()),\n        ..Default::default()\n    };\n    let mut banana: fruit::ActiveModel = banana.save(db).await?;\n\n    println!(\"Inserted: {banana:?}\");\n\n    banana.name = Set(\"Banana Mongo\".to_owned());\n\n    let banana: fruit::ActiveModel = banana.save(db).await?;\n\n    println!(\"Updated: {banana:?}\");\n\n    let result = banana.delete(db).await?;\n\n    println!(\"Deleted: {result:?}\");\n\n    Ok(())\n}\n\nmod form {\n    use super::fruit::*;\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveIntoActiveModel)]\n    pub struct InputModel {\n        pub name: String,\n    }\n}\n\nasync fn save_custom_active_model(db: &DbConn) -> Result<(), DbErr> {\n    let pineapple = form::InputModel {\n        name: \"Pineapple\".to_owned(),\n    }\n    .into_active_model();\n\n    let pineapple = pineapple.save(db).await?;\n\n    println!(\"Saved: {pineapple:?}\");\n\n    let result = pineapple.delete(db).await?;\n\n    println!(\"Deleted: {result:?}\");\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/basic/src/query.rs",
    "content": "use super::*;\nuse sea_orm::{DbConn, FromQueryResult, entity::*, error::*, query::*};\n\npub async fn all_about_query(db: &DbConn) -> Result<(), DbErr> {\n    find_all(db).await?;\n\n    println!(\"===== =====\\n\");\n\n    find_one(db).await?;\n\n    println!(\"===== =====\\n\");\n\n    find_one_to_one(db).await?;\n\n    println!(\"===== =====\\n\");\n\n    find_one_to_many(db).await?;\n\n    println!(\"===== =====\\n\");\n\n    count_fruits_by_cake(db).await?;\n\n    println!(\"===== =====\\n\");\n\n    find_many_to_many(db).await?;\n\n    if false {\n        println!(\"===== =====\\n\");\n\n        all_about_select_json(db).await?;\n    }\n\n    println!(\"===== =====\\n\");\n\n    find_all_stream(db).await.unwrap();\n\n    println!(\"===== =====\\n\");\n\n    find_first_page(db).await.unwrap();\n\n    println!(\"===== =====\\n\");\n\n    find_num_pages(db).await.unwrap();\n\n    Ok(())\n}\n\nasync fn find_all(db: &DbConn) -> Result<(), DbErr> {\n    print!(\"find all cakes: \");\n\n    let cakes: Vec<cake::Model> = Cake::find().all(db).await?;\n\n    println!();\n    for cc in cakes.iter() {\n        println!(\"{cc:?}\\n\");\n    }\n\n    print!(\"find all fruits: \");\n\n    let fruits = Fruit::find().all(db).await?;\n\n    println!();\n    for ff in fruits.iter() {\n        println!(\"{ff:?}\\n\");\n    }\n\n    Ok(())\n}\n\nasync fn find_one_to_one(db: &DbConn) -> Result<(), DbErr> {\n    print!(\"find fruits and cakes: \");\n\n    let fruits_and_cakes: Vec<(fruit::Model, Option<cake::Model>)> =\n        Fruit::find().find_also_related(Cake).all(db).await?;\n\n    println!(\"with loader: \");\n    let fruits: Vec<fruit::Model> = Fruit::find().all(db).await?;\n    let cakes: Vec<Option<cake::Model>> = fruits.load_one(Cake, db).await?;\n\n    println!();\n    for (left, right) in fruits_and_cakes\n        .into_iter()\n        .zip(fruits.into_iter().zip(cakes.into_iter()))\n    {\n        println!(\"{left:?}\");\n        assert_eq!(left, right);\n    }\n\n    Ok(())\n}\n\nasync fn find_one_to_many(db: &DbConn) -> Result<(), DbErr> {\n    print!(\"find cakes with fruits: \");\n\n    let cakes_with_fruits: Vec<(cake::Model, Vec<fruit::Model>)> = Cake::find()\n        .find_with_related(fruit::Entity)\n        .all(db)\n        .await?;\n\n    println!(\"with loader: \");\n    let cakes: Vec<cake::Model> = Cake::find().all(db).await?;\n    let fruits: Vec<Vec<fruit::Model>> = cakes.load_many(Fruit, db).await?;\n\n    println!();\n    for (left, right) in cakes_with_fruits\n        .into_iter()\n        .zip(cakes.into_iter().zip(fruits.into_iter()))\n    {\n        println!(\"{left:?}\\n\");\n        assert_eq!(left, right);\n    }\n\n    Ok(())\n}\n\nimpl Cake {\n    fn find_by_name(name: &str) -> Select<Self> {\n        Self::find().filter(cake::Column::Name.contains(name))\n    }\n}\n\nasync fn find_one(db: &DbConn) -> Result<(), DbErr> {\n    print!(\"find one by primary key: \");\n\n    let cheese: Option<cake::Model> = Cake::find_by_id(1).one(db).await?;\n    let cheese = cheese.unwrap();\n\n    println!();\n    println!(\"{cheese:?}\");\n    println!();\n\n    print!(\"find one by name: \");\n\n    let chocolate = Cake::find_by_name(\"chocolate\").one(db).await?;\n\n    println!();\n    println!(\"{chocolate:?}\");\n    println!();\n\n    print!(\"find models belong to: \");\n\n    let fruits = cheese.find_related(Fruit).all(db).await?;\n\n    println!();\n    for ff in fruits.iter() {\n        println!(\"{ff:?}\\n\");\n    }\n\n    Ok(())\n}\n\nasync fn count_fruits_by_cake(db: &DbConn) -> Result<(), DbErr> {\n    #[derive(Debug, FromQueryResult)]\n    struct SelectResult {\n        name: String,\n        num_of_fruits: i32,\n    }\n\n    print!(\"count fruits by cake: \");\n\n    let select = Cake::find()\n        .left_join(Fruit)\n        .select_only()\n        .column(cake::Column::Name)\n        .column_as(fruit::Column::Id.count(), \"num_of_fruits\")\n        .group_by(cake::Column::Name);\n\n    let results = select.into_model::<SelectResult>().all(db).await?;\n\n    println!();\n    for rr in results.iter() {\n        println!(\"{rr:?}\\n\");\n    }\n\n    Ok(())\n}\n\nasync fn find_many_to_many(db: &DbConn) -> Result<(), DbErr> {\n    print!(\"find cakes and fillings: \");\n\n    let cakes_with_fillings: Vec<(cake::Model, Vec<filling::Model>)> =\n        Cake::find().find_with_related(Filling).all(db).await?;\n\n    println!(\"with loader: \");\n    let cakes: Vec<cake::Model> = Cake::find().all(db).await?;\n    let fillings: Vec<Vec<filling::Model>> =\n        cakes.load_many_to_many(Filling, CakeFilling, db).await?;\n\n    println!();\n    for (left, right) in cakes_with_fillings\n        .into_iter()\n        .zip(cakes.into_iter().zip(fillings.into_iter()))\n    {\n        println!(\"{left:?}\\n\");\n        assert_eq!(left, right);\n    }\n\n    print!(\"find fillings for cheese cake: \");\n\n    let cheese = Cake::find_by_id(1).one(db).await?;\n\n    if let Some(cheese) = cheese {\n        let fillings: Vec<filling::Model> = cheese.find_related(Filling).all(db).await?;\n\n        println!();\n        for ff in fillings.iter() {\n            println!(\"{ff:?}\\n\");\n        }\n    }\n\n    print!(\"find cakes for lemon: \");\n\n    let lemon = Filling::find_by_id(2).one(db).await?;\n\n    if let Some(lemon) = lemon {\n        let cakes: Vec<cake::Model> = lemon.find_related(Cake).all(db).await?;\n\n        println!();\n        for cc in cakes.iter() {\n            println!(\"{cc:?}\\n\");\n        }\n    }\n\n    Ok(())\n}\n\nasync fn all_about_select_json(db: &DbConn) -> Result<(), DbErr> {\n    find_all_json(db).await?;\n\n    println!(\"===== =====\\n\");\n\n    find_together_json(db).await?;\n\n    println!(\"===== =====\\n\");\n\n    count_fruits_by_cake_json(db).await?;\n\n    Ok(())\n}\n\nasync fn find_all_json(db: &DbConn) -> Result<(), DbErr> {\n    print!(\"find all cakes: \");\n\n    let cakes = Cake::find().into_json().all(db).await?;\n\n    println!(\"\\n{}\\n\", serde_json::to_string_pretty(&cakes).unwrap());\n\n    print!(\"find all fruits: \");\n\n    let fruits = Fruit::find().into_json().all(db).await?;\n\n    println!(\"\\n{}\\n\", serde_json::to_string_pretty(&fruits).unwrap());\n\n    Ok(())\n}\n\nasync fn find_together_json(db: &DbConn) -> Result<(), DbErr> {\n    print!(\"find cakes and fruits: \");\n\n    let cakes_fruits = Cake::find()\n        .find_also_related(Fruit)\n        .into_json()\n        .all(db)\n        .await?;\n\n    println!(\n        \"\\n{}\\n\",\n        serde_json::to_string_pretty(&cakes_fruits).unwrap()\n    );\n\n    Ok(())\n}\n\nasync fn count_fruits_by_cake_json(db: &DbConn) -> Result<(), DbErr> {\n    print!(\"count fruits by cake: \");\n\n    let count = Cake::find()\n        .left_join(Fruit)\n        .select_only()\n        .column(cake::Column::Name)\n        .column_as(fruit::Column::Id.count(), \"num_of_fruits\")\n        .group_by(cake::Column::Name)\n        .into_json()\n        .all(db)\n        .await?;\n\n    println!(\"\\n{}\\n\", serde_json::to_string_pretty(&count).unwrap());\n\n    Ok(())\n}\n\nasync fn find_all_stream(db: &DbConn) -> Result<(), DbErr> {\n    use futures_util::TryStreamExt;\n    use std::time::Duration;\n    use tokio::time::sleep;\n\n    println!(\"find all cakes paginated: \");\n    let mut cake_paginator = cake::Entity::find().paginate(db, 3);\n    while let Some(cake_res) = cake_paginator.fetch_and_next().await? {\n        for cake in cake_res {\n            println!(\"{cake:?}\");\n        }\n    }\n\n    println!();\n    println!(\"find all fruits paginated: \");\n    let mut fruit_paginator = fruit::Entity::find().paginate(db, 3);\n    while let Some(fruit_res) = fruit_paginator.fetch_and_next().await? {\n        for fruit in fruit_res {\n            println!(\"{fruit:?}\");\n        }\n    }\n\n    println!();\n    println!(\"find all fruits with stream: \");\n    let mut fruit_stream = fruit::Entity::find().paginate(db, 3).into_stream();\n    while let Some(fruits) = fruit_stream.try_next().await? {\n        for fruit in fruits {\n            println!(\"{fruit:?}\");\n        }\n        sleep(Duration::from_millis(250)).await;\n    }\n\n    println!();\n    println!(\"find all fruits in json with stream: \");\n    let mut json_stream = fruit::Entity::find()\n        .into_json()\n        .paginate(db, 3)\n        .into_stream();\n    while let Some(jsons) = json_stream.try_next().await? {\n        for json in jsons {\n            println!(\"{json:?}\");\n        }\n        sleep(Duration::from_millis(250)).await;\n    }\n\n    Ok(())\n}\n\nasync fn find_first_page(db: &DbConn) -> Result<(), DbErr> {\n    println!(\"fruits first page: \");\n    let page = fruit::Entity::find().paginate(db, 3).fetch_page(0).await?;\n    for fruit in page {\n        println!(\"{fruit:?}\");\n    }\n\n    Ok(())\n}\n\nasync fn find_num_pages(db: &DbConn) -> Result<(), DbErr> {\n    println!(\"fruits number of page: \");\n    let num_pages = fruit::Entity::find().paginate(db, 3).num_pages().await?;\n    println!(\"{num_pages:?}\");\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/graphql_example/.gitignore",
    "content": "db\ndb-shm\ndb-wal"
  },
  {
    "path": "examples/graphql_example/Cargo.toml",
    "content": "[package]\nauthors      = [\"Aaron Leopold <aaronleopold1221@gmail.com>\"]\nedition      = \"2024\"\nname         = \"sea-orm-graphql-example\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n[workspace]\nmembers = [\".\", \"api\", \"entity\", \"migration\"]\n\n[dependencies]\ngraphql-example-api = { path = \"api\" }\n"
  },
  {
    "path": "examples/graphql_example/README.md",
    "content": "![screenshot](Screenshot1.png)\n\n![screenshot](Screenshot2.png)\n\n# Axum-GraphQL with SeaORM example app\n\n1. Modify the `DATABASE_URL` var in `.env` to point to your chosen database\n\n1. Turn on the appropriate database feature for your chosen db in `api/Cargo.toml` (the `\"sqlx-sqlite\",` line)\n\n1. Execute `cargo run` to start the server\n\n1. Visit [localhost:3000/api/graphql](http://localhost:3000/api/graphql) in browser\n\nRun tests:\n\n```bash\ncd api\ncargo test\n```\n\nRun migration:\n\n```bash\ncargo run -p migration -- up\n```\n"
  },
  {
    "path": "examples/graphql_example/api/Cargo.toml",
    "content": "[package]\nauthors      = [\"Aaron Leopold <aaronleopold1221@gmail.com>\"]\nedition      = \"2024\"\nname         = \"graphql-example-api\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nasync-graphql      = { version = \"7.0.17\" }\nasync-graphql-axum = \"7.0\"\naxum               = \"0.8\"\ndotenvy            = \"0.15.7\"\nentity             = { path = \"../entity\" }\nmigration          = { path = \"../migration\" }\ntokio              = { version = \"1.29\", features = [\"full\"] }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"debug-print\",\n    \"runtime-tokio-native-tls\",\n    # \"sqlx-postgres\",\n    # \"sqlx-mysql\",\n    \"sqlx-sqlite\",\n]\npath = \"../../../\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n"
  },
  {
    "path": "examples/graphql_example/api/src/db.rs",
    "content": "use sea_orm::DatabaseConnection;\n\npub struct Database {\n    pub connection: DatabaseConnection,\n}\n\nimpl Database {\n    pub async fn new() -> Self {\n        let connection = sea_orm::Database::connect(std::env::var(\"DATABASE_URL\").unwrap())\n            .await\n            .expect(\"Could not connect to database\");\n\n        Database { connection }\n    }\n\n    pub fn get_connection(&self) -> &DatabaseConnection {\n        &self.connection\n    }\n}\n"
  },
  {
    "path": "examples/graphql_example/api/src/graphql/mod.rs",
    "content": "pub mod mutation;\npub mod query;\npub mod schema;\n"
  },
  {
    "path": "examples/graphql_example/api/src/graphql/mutation/mod.rs",
    "content": "pub mod note;\n\npub use note::NoteMutation;\n\n// Add your other ones here to create a unified Mutation object\n// e.x. Mutation(NoteMutation, OtherMutation, OtherOtherMutation)\n#[derive(async_graphql::MergedObject, Default)]\npub struct Mutation(NoteMutation);\n"
  },
  {
    "path": "examples/graphql_example/api/src/graphql/mutation/note.rs",
    "content": "use crate::service::Mutation;\nuse async_graphql::{Context, InputObject, Object, Result, SimpleObject};\nuse entity::note;\n\nuse crate::db::Database;\n\n// I normally separate the input types into separate files/modules, but this is just\n// a quick example.\n\n#[derive(InputObject)]\npub struct CreateNoteInput {\n    pub title: String,\n    pub text: String,\n}\n\nimpl CreateNoteInput {\n    fn into_model_with_arbitrary_id(self) -> note::Model {\n        note::Model {\n            id: 0,\n            title: self.title,\n            text: self.text,\n        }\n    }\n}\n\n#[derive(SimpleObject)]\npub struct DeleteResult {\n    pub success: bool,\n    pub rows_affected: u64,\n}\n\n#[derive(Default)]\npub struct NoteMutation;\n\n#[Object]\nimpl NoteMutation {\n    pub async fn create_note(\n        &self,\n        ctx: &Context<'_>,\n        input: CreateNoteInput,\n    ) -> Result<note::Model> {\n        let db = ctx.data::<Database>().unwrap();\n        let conn = db.get_connection();\n\n        Ok(Mutation::create_note(conn, input.into_model_with_arbitrary_id()).await?)\n    }\n\n    pub async fn delete_note(&self, ctx: &Context<'_>, id: i32) -> Result<DeleteResult> {\n        let db = ctx.data::<Database>().unwrap();\n        let conn = db.get_connection();\n\n        let res = Mutation::delete_note(conn, id)\n            .await\n            .expect(\"Cannot delete note\");\n\n        if res.rows_affected <= 1 {\n            Ok(DeleteResult {\n                success: true,\n                rows_affected: res.rows_affected,\n            })\n        } else {\n            unimplemented!()\n        }\n    }\n}\n"
  },
  {
    "path": "examples/graphql_example/api/src/graphql/query/mod.rs",
    "content": "pub mod note;\n\npub use note::NoteQuery;\n\n// Add your other ones here to create a unified Query object\n// e.x. Query(NoteQuery, OtherQuery, OtherOtherQuery)\n#[derive(async_graphql::MergedObject, Default)]\npub struct Query(NoteQuery);\n"
  },
  {
    "path": "examples/graphql_example/api/src/graphql/query/note.rs",
    "content": "use crate::service::Query;\nuse async_graphql::{Context, Object, Result};\nuse entity::note;\n\nuse crate::db::Database;\n\n#[derive(Default)]\npub struct NoteQuery;\n\n#[Object]\nimpl NoteQuery {\n    async fn get_notes(&self, ctx: &Context<'_>) -> Result<Vec<note::Model>> {\n        let db = ctx.data::<Database>().unwrap();\n        let conn = db.get_connection();\n\n        Ok(Query::get_all_notes(conn)\n            .await\n            .map_err(|e| e.to_string())?)\n    }\n\n    async fn get_note_by_id(&self, ctx: &Context<'_>, id: i32) -> Result<Option<note::Model>> {\n        let db = ctx.data::<Database>().unwrap();\n        let conn = db.get_connection();\n\n        Ok(Query::find_note_by_id(conn, id)\n            .await\n            .map_err(|e| e.to_string())?)\n    }\n}\n"
  },
  {
    "path": "examples/graphql_example/api/src/graphql/schema.rs",
    "content": "use async_graphql;\nuse async_graphql::{EmptySubscription, Schema};\nuse migration::{Migrator, MigratorTrait};\n\nuse crate::{\n    db::Database,\n    graphql::{mutation::Mutation, query::Query},\n};\n\npub type AppSchema = Schema<Query, Mutation, EmptySubscription>;\n\n/// Builds the GraphQL Schema, attaching the Database to the context\npub async fn build_schema() -> AppSchema {\n    let db = Database::new().await;\n\n    Migrator::up(db.get_connection(), None).await.unwrap();\n\n    Schema::build(Query::default(), Mutation::default(), EmptySubscription)\n        .data(db)\n        .finish()\n}\n"
  },
  {
    "path": "examples/graphql_example/api/src/lib.rs",
    "content": "mod db;\nmod graphql;\npub mod service;\n\nuse async_graphql::http::{GraphQLPlaygroundConfig, playground_source};\nuse async_graphql_axum::{GraphQLRequest, GraphQLResponse};\nuse axum::{\n    Router,\n    extract::State,\n    response::{Html, IntoResponse},\n    routing::get,\n};\nuse graphql::schema::{AppSchema, build_schema};\n\n#[cfg(debug_assertions)]\nuse dotenvy::dotenv;\n\nasync fn graphql_handler(schema: State<AppSchema>, req: GraphQLRequest) -> GraphQLResponse {\n    schema.execute(req.into_inner()).await.into()\n}\n\nasync fn graphql_playground() -> impl IntoResponse {\n    Html(playground_source(GraphQLPlaygroundConfig::new(\n        \"/api/graphql\",\n    )))\n}\n\n#[tokio::main]\npub async fn main() {\n    #[cfg(debug_assertions)]\n    dotenv().ok();\n\n    let schema = build_schema().await;\n\n    let app = Router::new()\n        .route(\n            \"/api/graphql\",\n            get(graphql_playground).post(graphql_handler),\n        )\n        .with_state(schema);\n\n    println!(\"Playground: http://localhost:3000/api/graphql\");\n\n    let listener = tokio::net::TcpListener::bind(\"0.0.0.0:3000\").await.unwrap();\n    axum::serve(listener, app).await.unwrap();\n}\n"
  },
  {
    "path": "examples/graphql_example/api/src/service/mod.rs",
    "content": "mod mutation;\nmod query;\n\npub use mutation::*;\npub use query::*;\n"
  },
  {
    "path": "examples/graphql_example/api/src/service/mutation.rs",
    "content": "use entity::{note, note::Entity as Note};\nuse sea_orm::{DbConn, DbErr, DeleteResult, entity::*};\n\npub struct Mutation;\n\nimpl Mutation {\n    pub async fn create_note(db: &DbConn, form_data: note::Model) -> Result<note::Model, DbErr> {\n        let active_model = note::ActiveModel {\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n            ..Default::default()\n        };\n        let res = Note::insert(active_model).exec(db).await?;\n\n        Ok(note::Model {\n            id: res.last_insert_id,\n            ..form_data\n        })\n    }\n\n    pub async fn update_note_by_id(\n        db: &DbConn,\n        id: i32,\n        form_data: note::Model,\n    ) -> Result<note::Model, DbErr> {\n        let note: note::ActiveModel = Note::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find note.\".to_owned()))\n            .map(Into::into)?;\n\n        note::ActiveModel {\n            id: note.id,\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n        }\n        .update(db)\n        .await\n    }\n\n    pub async fn delete_note(db: &DbConn, id: i32) -> Result<DeleteResult, DbErr> {\n        let note: note::ActiveModel = Note::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find note.\".to_owned()))\n            .map(Into::into)?;\n\n        note.delete(db).await\n    }\n\n    pub async fn delete_all_notes(db: &DbConn) -> Result<DeleteResult, DbErr> {\n        Note::delete_many().exec(db).await\n    }\n}\n"
  },
  {
    "path": "examples/graphql_example/api/src/service/query.rs",
    "content": "use entity::{note, note::Entity as Note};\nuse sea_orm::{DbConn, DbErr, EntityTrait, PaginatorTrait, QueryOrder};\n\npub struct Query;\n\nimpl Query {\n    pub async fn find_note_by_id(db: &DbConn, id: i32) -> Result<Option<note::Model>, DbErr> {\n        Note::find_by_id(id).one(db).await\n    }\n\n    pub async fn get_all_notes(db: &DbConn) -> Result<Vec<note::Model>, DbErr> {\n        Note::find().all(db).await\n    }\n\n    /// If ok, returns (note models, num pages).\n    pub async fn find_notes_in_page(\n        db: &DbConn,\n        page: u64,\n        notes_per_page: u64,\n    ) -> Result<(Vec<note::Model>, u64), DbErr> {\n        // Setup paginator\n        let paginator = Note::find()\n            .order_by_asc(note::Column::Id)\n            .paginate(db, notes_per_page);\n        let num_pages = paginator.num_pages().await?;\n\n        // Fetch paginated notes\n        paginator.fetch_page(page - 1).await.map(|p| (p, num_pages))\n    }\n}\n"
  },
  {
    "path": "examples/graphql_example/api/tests/crud_tests.rs",
    "content": "use entity::note;\nuse graphql_example_api::service::{Mutation, Query};\nuse sea_orm::{ConnectionTrait, Database, Schema};\n\n#[tokio::test]\nasync fn crud_tests() {\n    let db = &Database::connect(\"sqlite::memory:\").await.unwrap();\n\n    db.execute(&Schema::new(db.get_database_backend()).create_table_from_entity(note::Entity))\n        .await\n        .unwrap();\n\n    {\n        let note = Mutation::create_note(\n            db,\n            note::Model {\n                id: 0,\n                title: \"Title A\".to_owned(),\n                text: \"Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            note,\n            note::Model {\n                id: 1,\n                title: \"Title A\".to_owned(),\n                text: \"Text A\".to_owned(),\n            }\n        );\n    }\n\n    {\n        let note = Mutation::create_note(\n            db,\n            note::Model {\n                id: 0,\n                title: \"Title B\".to_owned(),\n                text: \"Text B\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            note,\n            note::Model {\n                id: 2,\n                title: \"Title B\".to_owned(),\n                text: \"Text B\".to_owned(),\n            }\n        );\n    }\n\n    {\n        let note = Query::find_note_by_id(db, 1).await.unwrap().unwrap();\n\n        assert_eq!(note.id, 1);\n        assert_eq!(note.title, \"Title A\");\n    }\n\n    {\n        let note = Mutation::update_note_by_id(\n            db,\n            1,\n            note::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            note,\n            note::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            }\n        );\n    }\n\n    {\n        let result = Mutation::delete_note(db, 2).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n\n    {\n        let note = Query::find_note_by_id(db, 2).await.unwrap();\n        assert!(note.is_none());\n    }\n\n    {\n        let result = Mutation::delete_all_notes(db).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n}\n"
  },
  {
    "path": "examples/graphql_example/entity/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"entity\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"entity\"\npath = \"src/lib.rs\"\n\n[dependencies]\nserde = { version = \"1\", features = [\"derive\"] }\n\n[dependencies.async-graphql]\nversion = \"7.0\"\n\n[dependencies.sea-orm]\npath    = \"../../../\"    # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n"
  },
  {
    "path": "examples/graphql_example/entity/src/lib.rs",
    "content": "pub mod note;\n"
  },
  {
    "path": "examples/graphql_example/entity/src/note.rs",
    "content": "use async_graphql::*;\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize, SimpleObject)]\n#[sea_orm(table_name = \"note\")]\n#[graphql(concrete(name = \"Note\", params()))]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    pub title: String,\n    pub text: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\nimpl Entity {\n    pub fn find_by_title(title: &str) -> Select<Entity> {\n        Self::find().filter(Column::Title.eq(title))\n    }\n}\n"
  },
  {
    "path": "examples/graphql_example/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nentity = { path = \"../entity\" }\ntokio  = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable following runtime and db backend features if you want to run migration via CLI\n    \"runtime-tokio-native-tls\",\n    \"sqlx-sqlite\",\n]\npath = \"../../../sea-orm-migration\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/graphql_example/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/graphql_example/migration/src/lib.rs",
    "content": "pub use sea_orm_migration::prelude::*;\n\nmod m20220120_000001_create_note_table;\nmod m20220120_000002_seed_notes;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220120_000001_create_note_table::Migration),\n            Box::new(m20220120_000002_seed_notes::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "examples/graphql_example/migration/src/m20220120_000001_create_note_table.rs",
    "content": "use entity::note;\nuse sea_orm_migration::prelude::*;\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        db.get_schema_builder()\n            .register(note::Entity)\n            .sync(db)\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/graphql_example/migration/src/m20220120_000002_seed_notes.rs",
    "content": "use entity::note;\nuse sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};\nuse sea_orm_migration::prelude::*;\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let seed_data = vec![\n            (\"First Note\", \"This is the first note.\"),\n            (\"Second Note\", \"This is another note.\"),\n        ];\n\n        for (title, text) in seed_data {\n            let model = note::ActiveModel {\n                title: Set(title.to_string()),\n                text: Set(text.to_string()),\n                ..Default::default()\n            };\n            model.insert(db).await?;\n        }\n\n        println!(\"Notes table seeded successfully.\");\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let titles_to_delete = vec![\"First Note\", \"Second Note\"];\n        note::Entity::delete_many()\n            .filter(note::Column::Title.is_in(titles_to_delete))\n            .exec(db)\n            .await?;\n\n        println!(\"Notes seeded data removed.\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/graphql_example/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/graphql_example/src/main.rs",
    "content": "fn main() {\n    graphql_example_api::main();\n}\n"
  },
  {
    "path": "examples/jsonrpsee_example/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"sea-orm-jsonrpsee-example\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n[workspace]\nmembers = [\".\", \"api\", \"entity\", \"migration\"]\n\n[dependencies]\njsonrpsee-example-api = { path = \"api\" }\n"
  },
  {
    "path": "examples/jsonrpsee_example/README.md",
    "content": "# jsonrpsee with SeaORM example app\n\n1. Modify the `DATABASE_URL` var in `.env` to point to your chosen database\n\n1. Turn on the appropriate database feature for your chosen db in `api/Cargo.toml` (the `\"sqlx-sqlite\",` line)\n\n1. Execute `cargo run` to start the server\n\n1. Send jsonrpc request to server\n\n#### Insert\n\n```shell\ncurl --location --request POST 'http://127.0.0.1:8000' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\"jsonrpc\": \"2.0\", \"method\": \"Post.Insert\", \"params\": [\n    {\n        \"id\":0,\n        \"title\":\"aaaaaaa\",\n        \"text\":\"aaaaaaa\"\n    }\n], \"id\": 2}'\n```\n\n#### List\n\n```shell\ncurl --location --request POST 'http://127.0.0.1:8000' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"jsonrpc\": \"2.0\",\n    \"method\": \"Post.List\",\n    \"params\": [\n        1,\n        100\n    ],\n    \"id\": 2\n}'\n```\n\n#### Delete\n\n```shell\ncurl --location --request POST 'http://127.0.0.1:8000' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"jsonrpc\": \"2.0\",\n    \"method\": \"Post.Delete\",\n    \"params\": [\n        10\n    ],\n    \"id\": 2\n}'\n```\n\n#### Update\n\n```shell\ncurl --location --request POST 'http://127.0.0.1:8000' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"jsonrpc\": \"2.0\",\n    \"method\": \"Post.Update\",\n    \"params\": [\n        {\n            \"id\": 1,\n            \"title\": \"1111\",\n            \"text\": \"11111\"\n        }\n    ],\n    \"id\": 2\n}'\n```\n\nRun tests:\n\n```bash\ncd api\ncargo test\n```\n\nRun migration:\n\n```bash\ncargo run -p migration -- up\n```\n\nRegenerate entity:\n\n```bash\nsea-orm-cli generate entity --output-dir ./entity/src --lib --entity-format dense --with-serde both\n```"
  },
  {
    "path": "examples/jsonrpsee_example/api/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"jsonrpsee-example-api\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nanyhow         = \"1.0.71\"\nasync-trait    = \"0.1.71\"\ndotenvy        = \"0.15\"\nentity         = { path = \"../entity\" }\njsonrpsee      = { version = \"0.18.2\", features = [\"full\"] }\njsonrpsee-core = \"0.18.2\"\nlog            = { version = \"0.4\", features = [\"std\"] }\nmigration      = { path = \"../migration\" }\nserde          = { version = \"1\", features = [\"derive\"] }\nsimplelog      = \"0.12\"\ntokio          = { version = \"1.29.1\", features = [\"full\"] }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"debug-print\",\n    \"runtime-tokio-native-tls\",\n    \"sqlx-sqlite\",\n    # \"sqlx-postgres\",\n    # \"sqlx-mysql\",\n]\npath = \"../../../\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n"
  },
  {
    "path": "examples/jsonrpsee_example/api/src/lib.rs",
    "content": "pub mod service;\n\nuse std::env;\n\nuse entity::post;\nuse jsonrpsee::core::{RpcResult, async_trait};\nuse jsonrpsee::proc_macros::rpc;\nuse jsonrpsee::server::ServerBuilder;\nuse jsonrpsee::types::error::ErrorObjectOwned;\nuse log::info;\nuse migration::{Migrator, MigratorTrait};\nuse sea_orm::{Database, DatabaseConnection};\nuse service::{Mutation, Query};\nuse simplelog::*;\nuse std::fmt::Display;\nuse std::net::SocketAddr;\nuse tokio::signal::ctrl_c;\n// use tokio::signal::unix::{signal, SignalKind};\n\nconst DEFAULT_POSTS_PER_PAGE: u64 = 5;\n\n#[rpc(server, client)]\ntrait PostRpc {\n    #[method(name = \"Post.List\")]\n    async fn list(\n        &self,\n        page: Option<u64>,\n        posts_per_page: Option<u64>,\n    ) -> RpcResult<Vec<post::Model>>;\n\n    #[method(name = \"Post.Insert\")]\n    async fn insert(&self, p: post::Model) -> RpcResult<i32>;\n\n    #[method(name = \"Post.Update\")]\n    async fn update(&self, p: post::Model) -> RpcResult<bool>;\n\n    #[method(name = \"Post.Delete\")]\n    async fn delete(&self, id: i32) -> RpcResult<bool>;\n}\n\nstruct PpcImpl {\n    conn: DatabaseConnection,\n}\n\n#[async_trait]\nimpl PostRpcServer for PpcImpl {\n    async fn list(\n        &self,\n        page: Option<u64>,\n        posts_per_page: Option<u64>,\n    ) -> RpcResult<Vec<post::Model>> {\n        let page = page.unwrap_or(1);\n        let posts_per_page = posts_per_page.unwrap_or(DEFAULT_POSTS_PER_PAGE);\n\n        Query::find_posts_in_page(&self.conn, page, posts_per_page)\n            .await\n            .map(|(p, _)| p)\n            .internal_call_error()\n    }\n\n    async fn insert(&self, p: post::Model) -> RpcResult<i32> {\n        let new_post = Mutation::create_post(&self.conn, p)\n            .await\n            .internal_call_error()?;\n\n        Ok(new_post.id.unwrap())\n    }\n\n    async fn update(&self, p: post::Model) -> RpcResult<bool> {\n        Mutation::update_post_by_id(&self.conn, p.id, p)\n            .await\n            .map(|_| true)\n            .internal_call_error()\n    }\n    async fn delete(&self, id: i32) -> RpcResult<bool> {\n        Mutation::delete_post(&self.conn, id)\n            .await\n            .map(|res| res.rows_affected == 1)\n            .internal_call_error()\n    }\n}\n\ntrait IntoJsonRpcResult<T> {\n    fn internal_call_error(self) -> RpcResult<T>;\n}\n\nimpl<T, E> IntoJsonRpcResult<T> for Result<T, E>\nwhere\n    E: Display,\n{\n    fn internal_call_error(self) -> RpcResult<T> {\n        // Err(ErrorObjectOwned::owned(1, \"c\", None::<()>))\n        // self.map_err(|e| jsonrpsee::core::Error::Call(CallError::Failed(anyhow!(\"{}\", e))))\n        self.map_err(|e| ErrorObjectOwned::owned(1, format!(\"{}\", e), None::<()>))\n    }\n}\n\n#[tokio::main]\nasync fn start() -> std::io::Result<()> {\n    let _ = TermLogger::init(\n        LevelFilter::Trace,\n        Config::default(),\n        TerminalMode::Mixed,\n        ColorChoice::Auto,\n    );\n\n    // get env vars\n    dotenvy::dotenv().ok();\n    let db_url = env::var(\"DATABASE_URL\").expect(\"DATABASE_URL is not set in .env file\");\n    let host = env::var(\"HOST\").expect(\"HOST is not set in .env file\");\n    let port = env::var(\"PORT\").expect(\"PORT is not set in .env file\");\n    let server_url = format!(\"{host}:{port}\");\n\n    // create post table if not exists\n    let conn = Database::connect(&db_url).await.unwrap();\n    Migrator::up(&conn, None).await.unwrap();\n\n    let server = ServerBuilder::default()\n        .build(server_url.parse::<SocketAddr>().unwrap())\n        .await\n        .unwrap();\n\n    let rpc_impl = PpcImpl { conn };\n    let server_addr = server.local_addr().unwrap();\n    let handle = server.start(rpc_impl.into_rpc()).unwrap();\n\n    info!(\"starting listening {}\", server_addr);\n    // let mut sig_int = signal(SignalKind::interrupt()).unwrap();\n    // let mut sig_term = signal(SignalKind::terminate()).unwrap();\n\n    tokio::select! {\n        // _ = sig_int.recv() => info!(\"receive SIGINT\"),\n        // _ = sig_term.recv() => info!(\"receive SIGTERM\"),\n        _ = ctrl_c() => info!(\"receive Ctrl C\"),\n    }\n    handle.stop().unwrap();\n    info!(\"Shutdown program\");\n    Ok(())\n}\n\npub fn main() {\n    let result = start();\n\n    if let Some(err) = result.err() {\n        println!(\"Error: {err}\");\n    }\n}\n"
  },
  {
    "path": "examples/jsonrpsee_example/api/src/service/mod.rs",
    "content": "mod mutation;\nmod query;\n\npub use mutation::*;\npub use query::*;\n"
  },
  {
    "path": "examples/jsonrpsee_example/api/src/service/mutation.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Mutation;\n\nimpl Mutation {\n    pub async fn create_post(\n        db: &DbConn,\n        form_data: post::Model,\n    ) -> Result<post::ActiveModel, DbErr> {\n        post::ActiveModel {\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n            ..Default::default()\n        }\n        .save(db)\n        .await\n    }\n\n    pub async fn update_post_by_id(\n        db: &DbConn,\n        id: i32,\n        form_data: post::Model,\n    ) -> Result<post::Model, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post::ActiveModel {\n            id: post.id,\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n        }\n        .update(db)\n        .await\n    }\n\n    pub async fn delete_post(db: &DbConn, id: i32) -> Result<DeleteResult, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post.delete(db).await\n    }\n\n    pub async fn delete_all_posts(db: &DbConn) -> Result<DeleteResult, DbErr> {\n        Post::delete_many().exec(db).await\n    }\n}\n"
  },
  {
    "path": "examples/jsonrpsee_example/api/src/service/query.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Query;\n\nimpl Query {\n    pub async fn find_post_by_id(db: &DbConn, id: i32) -> Result<Option<post::Model>, DbErr> {\n        Post::find_by_id(id).one(db).await\n    }\n\n    /// If ok, returns (post models, num pages).\n    pub async fn find_posts_in_page(\n        db: &DbConn,\n        page: u64,\n        posts_per_page: u64,\n    ) -> Result<(Vec<post::Model>, u64), DbErr> {\n        // Setup paginator\n        let paginator = Post::find()\n            .order_by_asc(post::Column::Id)\n            .paginate(db, posts_per_page);\n        let num_pages = paginator.num_pages().await?;\n\n        // Fetch paginated posts\n        paginator.fetch_page(page - 1).await.map(|p| (p, num_pages))\n    }\n}\n"
  },
  {
    "path": "examples/jsonrpsee_example/api/tests/crud_tests.rs",
    "content": "use entity::post;\nuse jsonrpsee_example_api::service::{Mutation, Query};\nuse sea_orm::Database;\n\n#[tokio::test]\nasync fn crud_tests() {\n    let db = &Database::connect(\"sqlite::memory:\").await.unwrap();\n\n    db.get_schema_builder()\n        .register(post::Entity)\n        .apply(db)\n        .await\n        .unwrap();\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title A\".to_owned(),\n                text: \"Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(1),\n                title: sea_orm::ActiveValue::Unchanged(\"Title A\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text A\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title B\".to_owned(),\n                text: \"Text B\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(2),\n                title: sea_orm::ActiveValue::Unchanged(\"Title B\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text B\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 1).await.unwrap().unwrap();\n\n        assert_eq!(post.id, 1);\n        assert_eq!(post.title, \"Title A\");\n    }\n\n    {\n        let post = Mutation::update_post_by_id(\n            db,\n            1,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            }\n        );\n    }\n\n    {\n        let result = Mutation::delete_post(db, 2).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 2).await.unwrap();\n        assert!(post.is_none());\n    }\n\n    {\n        let result = Mutation::delete_all_posts(db).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n}\n"
  },
  {
    "path": "examples/jsonrpsee_example/entity/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"entity\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"entity\"\npath = \"src/lib.rs\"\n\n[dependencies]\nserde = { version = \"1\", features = [\"derive\"] }\n\n[dependencies.sea-orm]\npath    = \"../../../\"    # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n"
  },
  {
    "path": "examples/jsonrpsee_example/entity/src/lib.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub mod prelude;\n\npub mod post;\n"
  },
  {
    "path": "examples/jsonrpsee_example/entity/src/post.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"post\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub title: String,\n    #[sea_orm(column_type = \"Text\")]\n    pub text: String,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/jsonrpsee_example/entity/src/prelude.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub use super::post::Entity as Post;\n"
  },
  {
    "path": "examples/jsonrpsee_example/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nentity = { path = \"../entity\" }\ntokio  = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable following runtime and db backend features if you want to run migration via CLI\n    \"runtime-tokio-native-tls\",\n    \"sqlx-sqlite\",\n]\npath = \"../../../sea-orm-migration\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/jsonrpsee_example/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/jsonrpsee_example/migration/src/lib.rs",
    "content": "pub use sea_orm_migration::prelude::*;\n\nmod m20220120_000001_create_post_table;\nmod m20220120_000002_seed_posts;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220120_000001_create_post_table::Migration),\n            Box::new(m20220120_000002_seed_posts::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "examples/jsonrpsee_example/migration/src/m20220120_000001_create_post_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"post\")\n                    .if_not_exists()\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"title\"))\n                    .col(string(\"text\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"post\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/jsonrpsee_example/migration/src/m20220120_000002_seed_posts.rs",
    "content": "use entity::post;\nuse sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};\nuse sea_orm_migration::prelude::*;\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let seed_data = vec![\n            (\"First Post\", \"This is the first post.\"),\n            (\"Second Post\", \"This is another post.\"),\n        ];\n\n        for (title, text) in seed_data {\n            let model = post::ActiveModel {\n                title: Set(title.to_string()),\n                text: Set(text.to_string()),\n                ..Default::default()\n            };\n            model.insert(db).await?;\n        }\n\n        println!(\"Posts table seeded successfully.\");\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let titles_to_delete = vec![\"First Post\", \"Second Post\"];\n        post::Entity::delete_many()\n            .filter(post::Column::Title.is_in(titles_to_delete))\n            .exec(db)\n            .await?;\n\n        println!(\"Posts seeded data removed.\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/jsonrpsee_example/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/jsonrpsee_example/src/main.rs",
    "content": "fn main() {\n    jsonrpsee_example_api::main();\n}\n"
  },
  {
    "path": "examples/loco_example/.cargo/config.toml",
    "content": "[alias]\nloco       = \"run --\"\nplayground = \"run --example playground\"\n"
  },
  {
    "path": "examples/loco_example/.dockerignore",
    "content": "target\ndockerfile\n.dockerignore\n.git\n.gitignore\n"
  },
  {
    "path": "examples/loco_example/.gitignore",
    "content": "**/config/local.yaml\n**/config/*.local.yaml\n\n# Generated by Cargo\n# will have compiled files and executables\ndebug/\ntarget/\n\n# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries\n# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html\n!Cargo.lock\n\n# These are backup files generated by rustfmt\n**/*.rs.bk\n\n# MSVC Windows builds of rustc generate these, which store debugging information\n*.pdb\n"
  },
  {
    "path": "examples/loco_example/.rustfmt.toml",
    "content": "comment_width        = 80\nformat_strings       = true\ngroup_imports        = \"StdExternalCrate\"\nimports_granularity  = \"Crate\"\nmax_width            = 100\nuse_small_heuristics = \"Default\"\nwrap_comments        = true\n"
  },
  {
    "path": "examples/loco_example/Cargo.lock",
    "content": "# This file is automatically @generated by Cargo.\n# It is not intended for manual editing.\nversion = 4\n\n[[package]]\nname = \"addr2line\"\nversion = \"0.25.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b\"\ndependencies = [\n \"gimli\",\n]\n\n[[package]]\nname = \"adler2\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa\"\n\n[[package]]\nname = \"ahash\"\nversion = \"0.7.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9\"\ndependencies = [\n \"getrandom 0.2.16\",\n \"once_cell\",\n \"version_check\",\n]\n\n[[package]]\nname = \"ahash\"\nversion = \"0.8.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75\"\ndependencies = [\n \"cfg-if\",\n \"getrandom 0.3.3\",\n \"once_cell\",\n \"version_check\",\n \"zerocopy\",\n]\n\n[[package]]\nname = \"aho-corasick\"\nversion = \"1.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"aliasable\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd\"\n\n[[package]]\nname = \"alloc-no-stdlib\"\nversion = \"2.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3\"\n\n[[package]]\nname = \"alloc-stdlib\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece\"\ndependencies = [\n \"alloc-no-stdlib\",\n]\n\n[[package]]\nname = \"allocator-api2\"\nversion = \"0.2.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923\"\n\n[[package]]\nname = \"android_system_properties\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"anstream\"\nversion = \"0.6.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a\"\ndependencies = [\n \"anstyle\",\n \"anstyle-parse\",\n \"anstyle-query\",\n \"anstyle-wincon\",\n \"colorchoice\",\n \"is_terminal_polyfill\",\n \"utf8parse\",\n]\n\n[[package]]\nname = \"anstyle\"\nversion = \"1.0.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78\"\n\n[[package]]\nname = \"anstyle-parse\"\nversion = \"0.2.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2\"\ndependencies = [\n \"utf8parse\",\n]\n\n[[package]]\nname = \"anstyle-query\"\nversion = \"1.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2\"\ndependencies = [\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"anstyle-wincon\"\nversion = \"3.0.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a\"\ndependencies = [\n \"anstyle\",\n \"once_cell_polyfill\",\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"anyhow\"\nversion = \"1.0.100\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61\"\n\n[[package]]\nname = \"argon2\"\nversion = \"0.5.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072\"\ndependencies = [\n \"base64ct\",\n \"blake2\",\n \"cpufeatures\",\n \"password-hash\",\n]\n\n[[package]]\nname = \"arrayvec\"\nversion = \"0.7.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50\"\n\n[[package]]\nname = \"assert-json-diff\"\nversion = \"2.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12\"\ndependencies = [\n \"serde\",\n \"serde_json\",\n]\n\n[[package]]\nname = \"async-compression\"\nversion = \"0.4.32\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0\"\ndependencies = [\n \"compression-codecs\",\n \"compression-core\",\n \"futures-core\",\n \"pin-project-lite\",\n \"tokio\",\n]\n\n[[package]]\nname = \"async-stream\"\nversion = \"0.3.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476\"\ndependencies = [\n \"async-stream-impl\",\n \"futures-core\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"async-stream-impl\"\nversion = \"0.3.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"async-trait\"\nversion = \"0.1.89\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"atoi\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528\"\ndependencies = [\n \"num-traits\",\n]\n\n[[package]]\nname = \"atomic-waker\"\nversion = \"1.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0\"\n\n[[package]]\nname = \"auto-future\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373\"\n\n[[package]]\nname = \"autocfg\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8\"\n\n[[package]]\nname = \"axum\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871\"\ndependencies = [\n \"axum-core\",\n \"axum-macros\",\n \"bytes\",\n \"form_urlencoded\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"hyper\",\n \"hyper-util\",\n \"itoa\",\n \"matchit\",\n \"memchr\",\n \"mime\",\n \"multer\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"serde_core\",\n \"serde_json\",\n \"serde_path_to_error\",\n \"serde_urlencoded\",\n \"sync_wrapper\",\n \"tokio\",\n \"tower 0.5.2\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"axum-core\"\nversion = \"0.5.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"mime\",\n \"pin-project-lite\",\n \"sync_wrapper\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"axum-extra\"\nversion = \"0.10.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9963ff19f40c6102c76756ef0a46004c0d58957d87259fc9208ff8441c12ab96\"\ndependencies = [\n \"axum\",\n \"axum-core\",\n \"bytes\",\n \"cookie\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"mime\",\n \"pin-project-lite\",\n \"rustversion\",\n \"serde_core\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"axum-macros\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"axum-test\"\nversion = \"17.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0eb1dfb84bd48bad8e4aa1acb82ed24c2bb5e855b659959b4e03b4dca118fcac\"\ndependencies = [\n \"anyhow\",\n \"assert-json-diff\",\n \"auto-future\",\n \"axum\",\n \"bytes\",\n \"bytesize\",\n \"cookie\",\n \"http\",\n \"http-body-util\",\n \"hyper\",\n \"hyper-util\",\n \"mime\",\n \"pretty_assertions\",\n \"reserve-port\",\n \"rust-multipart-rfc7578_2\",\n \"serde\",\n \"serde_json\",\n \"serde_urlencoded\",\n \"smallvec\",\n \"tokio\",\n \"tower 0.5.2\",\n \"url\",\n]\n\n[[package]]\nname = \"backon\"\nversion = \"1.5.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"592277618714fbcecda9a02ba7a8781f319d26532a88553bbacc77ba5d2b3a8d\"\ndependencies = [\n \"fastrand\",\n \"gloo-timers\",\n \"tokio\",\n]\n\n[[package]]\nname = \"backtrace\"\nversion = \"0.3.76\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6\"\ndependencies = [\n \"addr2line\",\n \"cfg-if\",\n \"libc\",\n \"miniz_oxide\",\n \"object\",\n \"rustc-demangle\",\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"backtrace_printer\"\nversion = \"1.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e8d28de81c708c843640982b66573df0f0168d87e42854b563971f326745aab7\"\ndependencies = [\n \"btparse-stable\",\n \"colored 2.2.0\",\n \"regex\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"base64\"\nversion = \"0.22.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6\"\n\n[[package]]\nname = \"base64ct\"\nversion = \"1.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba\"\n\n[[package]]\nname = \"bigdecimal\"\nversion = \"0.4.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1a22f228ab7a1b23027ccc6c350b72868017af7ea8356fbdf19f8d991c690013\"\ndependencies = [\n \"autocfg\",\n \"libm\",\n \"num-bigint\",\n \"num-integer\",\n \"num-traits\",\n \"serde\",\n]\n\n[[package]]\nname = \"bitflags\"\nversion = \"1.3.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a\"\n\n[[package]]\nname = \"bitflags\"\nversion = \"2.9.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"bitvec\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c\"\ndependencies = [\n \"funty\",\n \"radium\",\n \"tap\",\n \"wyz\",\n]\n\n[[package]]\nname = \"blake2\"\nversion = \"0.10.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe\"\ndependencies = [\n \"digest\",\n]\n\n[[package]]\nname = \"block-buffer\"\nversion = \"0.10.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71\"\ndependencies = [\n \"generic-array\",\n]\n\n[[package]]\nname = \"borsh\"\nversion = \"1.5.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce\"\ndependencies = [\n \"borsh-derive\",\n \"cfg_aliases\",\n]\n\n[[package]]\nname = \"borsh-derive\"\nversion = \"1.5.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3\"\ndependencies = [\n \"once_cell\",\n \"proc-macro-crate\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"brotli\"\nversion = \"8.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560\"\ndependencies = [\n \"alloc-no-stdlib\",\n \"alloc-stdlib\",\n \"brotli-decompressor\",\n]\n\n[[package]]\nname = \"brotli-decompressor\"\nversion = \"5.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03\"\ndependencies = [\n \"alloc-no-stdlib\",\n \"alloc-stdlib\",\n]\n\n[[package]]\nname = \"bstr\"\nversion = \"1.12.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4\"\ndependencies = [\n \"memchr\",\n \"serde\",\n]\n\n[[package]]\nname = \"btparse-stable\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0d75b8252ed252f881d1dc4482ae3c3854df6ee8183c1906bac50ff358f4f89f\"\n\n[[package]]\nname = \"bumpalo\"\nversion = \"3.19.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43\"\n\n[[package]]\nname = \"byte-unit\"\nversion = \"4.0.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c\"\ndependencies = [\n \"serde\",\n \"utf8-width\",\n]\n\n[[package]]\nname = \"bytecheck\"\nversion = \"0.6.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2\"\ndependencies = [\n \"bytecheck_derive\",\n \"ptr_meta\",\n \"simdutf8\",\n]\n\n[[package]]\nname = \"bytecheck_derive\"\nversion = \"0.6.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"byteorder\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b\"\n\n[[package]]\nname = \"bytes\"\nversion = \"1.10.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a\"\n\n[[package]]\nname = \"bytesize\"\nversion = \"2.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f5c434ae3cf0089ca203e9019ebe529c47ff45cefe8af7c85ecb734ef541822f\"\n\n[[package]]\nname = \"cc\"\nversion = \"1.2.40\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb\"\ndependencies = [\n \"find-msvc-tools\",\n \"jobserver\",\n \"libc\",\n \"shlex\",\n]\n\n[[package]]\nname = \"cfg-if\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9\"\n\n[[package]]\nname = \"cfg_aliases\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724\"\n\n[[package]]\nname = \"chrono\"\nversion = \"0.4.42\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2\"\ndependencies = [\n \"iana-time-zone\",\n \"js-sys\",\n \"num-traits\",\n \"serde\",\n \"wasm-bindgen\",\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"chrono-tz\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb\"\ndependencies = [\n \"chrono\",\n \"chrono-tz-build\",\n \"phf\",\n]\n\n[[package]]\nname = \"chrono-tz-build\"\nversion = \"0.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1\"\ndependencies = [\n \"parse-zoneinfo\",\n \"phf\",\n \"phf_codegen\",\n]\n\n[[package]]\nname = \"chumsky\"\nversion = \"0.9.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9\"\ndependencies = [\n \"hashbrown 0.14.5\",\n \"stacker\",\n]\n\n[[package]]\nname = \"clap\"\nversion = \"4.5.48\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae\"\ndependencies = [\n \"clap_builder\",\n \"clap_derive\",\n]\n\n[[package]]\nname = \"clap_builder\"\nversion = \"4.5.48\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9\"\ndependencies = [\n \"anstream\",\n \"anstyle\",\n \"clap_lex\",\n \"strsim\",\n]\n\n[[package]]\nname = \"clap_derive\"\nversion = \"4.5.47\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c\"\ndependencies = [\n \"heck 0.5.0\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"clap_lex\"\nversion = \"0.7.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675\"\n\n[[package]]\nname = \"colorchoice\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75\"\n\n[[package]]\nname = \"colored\"\nversion = \"2.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c\"\ndependencies = [\n \"lazy_static\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"colored\"\nversion = \"3.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e\"\ndependencies = [\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"combine\"\nversion = \"4.6.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"memchr\",\n \"pin-project-lite\",\n \"tokio\",\n \"tokio-util\",\n]\n\n[[package]]\nname = \"compression-codecs\"\nversion = \"0.4.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23\"\ndependencies = [\n \"brotli\",\n \"compression-core\",\n \"flate2\",\n \"memchr\",\n \"zstd\",\n \"zstd-safe\",\n]\n\n[[package]]\nname = \"compression-core\"\nversion = \"0.4.29\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb\"\n\n[[package]]\nname = \"concurrent-queue\"\nversion = \"2.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"console\"\nversion = \"0.15.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8\"\ndependencies = [\n \"encode_unicode\",\n \"libc\",\n \"once_cell\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"const-oid\"\nversion = \"0.9.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8\"\n\n[[package]]\nname = \"cookie\"\nversion = \"0.18.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747\"\ndependencies = [\n \"percent-encoding\",\n \"time\",\n \"version_check\",\n]\n\n[[package]]\nname = \"core-foundation-sys\"\nversion = \"0.8.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b\"\n\n[[package]]\nname = \"cpufeatures\"\nversion = \"0.2.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"crc\"\nversion = \"3.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675\"\ndependencies = [\n \"crc-catalog\",\n]\n\n[[package]]\nname = \"crc-catalog\"\nversion = \"2.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5\"\n\n[[package]]\nname = \"crc32fast\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511\"\ndependencies = [\n \"cfg-if\",\n]\n\n[[package]]\nname = \"cron\"\nversion = \"0.12.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6f8c3e73077b4b4a6ab1ea5047c37c57aee77657bc8ecd6f29b0af082d0b0c07\"\ndependencies = [\n \"chrono\",\n \"nom 7.1.3\",\n \"once_cell\",\n]\n\n[[package]]\nname = \"crossbeam-channel\"\nversion = \"0.5.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-deque\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51\"\ndependencies = [\n \"crossbeam-epoch\",\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-epoch\"\nversion = \"0.9.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-queue\"\nversion = \"0.3.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-utils\"\nversion = \"0.8.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28\"\n\n[[package]]\nname = \"cruet\"\nversion = \"0.13.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"113a9e83d8f614be76de8df1f25bf9d0ea6e85ea573710a3d3f3abe1438ae49c\"\ndependencies = [\n \"once_cell\",\n \"regex\",\n]\n\n[[package]]\nname = \"cruet\"\nversion = \"0.14.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6132609543972496bc97b1e01f1ce6586768870aeb4cabeb3385f4e05b5caead\"\ndependencies = [\n \"once_cell\",\n \"regex\",\n]\n\n[[package]]\nname = \"crypto-common\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3\"\ndependencies = [\n \"generic-array\",\n \"typenum\",\n]\n\n[[package]]\nname = \"cssparser\"\nversion = \"0.34.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b7c66d1cd8ed61bf80b38432613a7a2f09401ab8d0501110655f8b341484a3e3\"\ndependencies = [\n \"cssparser-macros\",\n \"dtoa-short\",\n \"itoa\",\n \"phf\",\n \"smallvec\",\n]\n\n[[package]]\nname = \"cssparser-macros\"\nversion = \"0.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331\"\ndependencies = [\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"darling\"\nversion = \"0.20.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee\"\ndependencies = [\n \"darling_core\",\n \"darling_macro\",\n]\n\n[[package]]\nname = \"darling_core\"\nversion = \"0.20.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e\"\ndependencies = [\n \"fnv\",\n \"ident_case\",\n \"proc-macro2\",\n \"quote\",\n \"strsim\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"darling_macro\"\nversion = \"0.20.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead\"\ndependencies = [\n \"darling_core\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"dashmap\"\nversion = \"5.5.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856\"\ndependencies = [\n \"cfg-if\",\n \"hashbrown 0.14.5\",\n \"lock_api\",\n \"once_cell\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"dashmap\"\nversion = \"6.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf\"\ndependencies = [\n \"cfg-if\",\n \"crossbeam-utils\",\n \"hashbrown 0.14.5\",\n \"lock_api\",\n \"once_cell\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"der\"\nversion = \"0.7.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb\"\ndependencies = [\n \"const-oid\",\n \"pem-rfc7468\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"deranged\"\nversion = \"0.5.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071\"\ndependencies = [\n \"powerfmt\",\n \"serde_core\",\n]\n\n[[package]]\nname = \"derive_more\"\nversion = \"0.99.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"derive_more\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678\"\ndependencies = [\n \"derive_more-impl\",\n]\n\n[[package]]\nname = \"derive_more-impl\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"unicode-xid\",\n]\n\n[[package]]\nname = \"deunicode\"\nversion = \"1.6.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04\"\n\n[[package]]\nname = \"diff\"\nversion = \"0.1.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8\"\n\n[[package]]\nname = \"digest\"\nversion = \"0.10.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292\"\ndependencies = [\n \"block-buffer\",\n \"const-oid\",\n \"crypto-common\",\n \"subtle\",\n]\n\n[[package]]\nname = \"displaydoc\"\nversion = \"0.2.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"dotenvy\"\nversion = \"0.15.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b\"\n\n[[package]]\nname = \"dtoa\"\nversion = \"1.0.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04\"\n\n[[package]]\nname = \"dtoa-short\"\nversion = \"0.3.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87\"\ndependencies = [\n \"dtoa\",\n]\n\n[[package]]\nname = \"duct\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d7478638a31d1f1f3d6c9f5e57c76b906a04ac4879d6fd0fb6245bc88f73fd0b\"\ndependencies = [\n \"libc\",\n \"os_pipe\",\n \"shared_child\",\n \"shared_thread\",\n]\n\n[[package]]\nname = \"duct_sh\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8139179d1d133ab7153920ba3812915b17c61e2514a6f98b1fd03f2c07668d1\"\ndependencies = [\n \"duct\",\n]\n\n[[package]]\nname = \"ego-tree\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7c6ba7d4eec39eaa9ab24d44a0e73a7949a1095a8b3f3abb11eddf27dbb56a53\"\n\n[[package]]\nname = \"either\"\nversion = \"1.15.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"email-encoding\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9298e6504d9b9e780ed3f7dfd43a61be8cd0e09eb07f7706a945b0072b6670b6\"\ndependencies = [\n \"base64\",\n \"memchr\",\n]\n\n[[package]]\nname = \"email_address\"\nversion = \"0.2.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449\"\n\n[[package]]\nname = \"encode_unicode\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0\"\n\n[[package]]\nname = \"encoding_rs\"\nversion = \"0.8.35\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3\"\ndependencies = [\n \"cfg-if\",\n]\n\n[[package]]\nname = \"english-to-cron\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e26fb7377cbec9a94f60428e6e6afbe10c699a14639b4d3d4b67b25c0bbe0806\"\ndependencies = [\n \"regex\",\n]\n\n[[package]]\nname = \"equivalent\"\nversion = \"1.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f\"\n\n[[package]]\nname = \"etcetera\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943\"\ndependencies = [\n \"cfg-if\",\n \"home\",\n \"windows-sys 0.48.0\",\n]\n\n[[package]]\nname = \"event-listener\"\nversion = \"5.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab\"\ndependencies = [\n \"concurrent-queue\",\n \"parking\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"eyre\"\nversion = \"0.6.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec\"\ndependencies = [\n \"indenter\",\n \"once_cell\",\n]\n\n[[package]]\nname = \"fastrand\"\nversion = \"2.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be\"\n\n[[package]]\nname = \"find-msvc-tools\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3\"\n\n[[package]]\nname = \"flate2\"\nversion = \"1.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9\"\ndependencies = [\n \"crc32fast\",\n \"miniz_oxide\",\n]\n\n[[package]]\nname = \"flume\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095\"\ndependencies = [\n \"futures-core\",\n \"futures-sink\",\n \"spin\",\n]\n\n[[package]]\nname = \"fnv\"\nversion = \"1.0.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1\"\n\n[[package]]\nname = \"foldhash\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2\"\n\n[[package]]\nname = \"form_urlencoded\"\nversion = \"1.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf\"\ndependencies = [\n \"percent-encoding\",\n]\n\n[[package]]\nname = \"fs-err\"\nversion = \"2.11.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41\"\ndependencies = [\n \"autocfg\",\n]\n\n[[package]]\nname = \"fsevent-sys\"\nversion = \"4.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"funty\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c\"\n\n[[package]]\nname = \"futf\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843\"\ndependencies = [\n \"mac\",\n \"new_debug_unreachable\",\n]\n\n[[package]]\nname = \"futures\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"futures-executor\",\n \"futures-io\",\n \"futures-sink\",\n \"futures-task\",\n \"futures-util\",\n]\n\n[[package]]\nname = \"futures-channel\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10\"\ndependencies = [\n \"futures-core\",\n \"futures-sink\",\n]\n\n[[package]]\nname = \"futures-core\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e\"\n\n[[package]]\nname = \"futures-executor\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f\"\ndependencies = [\n \"futures-core\",\n \"futures-task\",\n \"futures-util\",\n]\n\n[[package]]\nname = \"futures-intrusive\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f\"\ndependencies = [\n \"futures-core\",\n \"lock_api\",\n \"parking_lot\",\n]\n\n[[package]]\nname = \"futures-io\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6\"\n\n[[package]]\nname = \"futures-macro\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"futures-sink\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7\"\n\n[[package]]\nname = \"futures-task\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988\"\n\n[[package]]\nname = \"futures-timer\"\nversion = \"3.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24\"\n\n[[package]]\nname = \"futures-util\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"futures-io\",\n \"futures-macro\",\n \"futures-sink\",\n \"futures-task\",\n \"memchr\",\n \"pin-project-lite\",\n \"pin-utils\",\n \"slab\",\n]\n\n[[package]]\nname = \"fxhash\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c\"\ndependencies = [\n \"byteorder\",\n]\n\n[[package]]\nname = \"generic-array\"\nversion = \"0.14.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a\"\ndependencies = [\n \"typenum\",\n \"version_check\",\n]\n\n[[package]]\nname = \"getopts\"\nversion = \"0.2.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df\"\ndependencies = [\n \"unicode-width\",\n]\n\n[[package]]\nname = \"getrandom\"\nversion = \"0.2.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592\"\ndependencies = [\n \"cfg-if\",\n \"js-sys\",\n \"libc\",\n \"wasi 0.11.1+wasi-snapshot-preview1\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"getrandom\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"r-efi\",\n \"wasi 0.14.7+wasi-0.2.4\",\n]\n\n[[package]]\nname = \"gimli\"\nversion = \"0.32.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7\"\n\n[[package]]\nname = \"glob\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280\"\n\n[[package]]\nname = \"globset\"\nversion = \"0.4.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5\"\ndependencies = [\n \"aho-corasick\",\n \"bstr\",\n \"log\",\n \"regex-automata\",\n \"regex-syntax\",\n]\n\n[[package]]\nname = \"globwalk\"\nversion = \"0.9.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"ignore\",\n \"walkdir\",\n]\n\n[[package]]\nname = \"gloo-timers\"\nversion = \"0.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"js-sys\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.12.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888\"\ndependencies = [\n \"ahash 0.7.8\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.14.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1\"\ndependencies = [\n \"ahash 0.8.12\",\n \"allocator-api2\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.15.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1\"\ndependencies = [\n \"allocator-api2\",\n \"equivalent\",\n \"foldhash\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.16.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d\"\n\n[[package]]\nname = \"hashlink\"\nversion = \"0.10.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1\"\ndependencies = [\n \"hashbrown 0.15.5\",\n]\n\n[[package]]\nname = \"heck\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8\"\n\n[[package]]\nname = \"heck\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea\"\n\n[[package]]\nname = \"hex\"\nversion = \"0.4.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70\"\n\n[[package]]\nname = \"hkdf\"\nversion = \"0.12.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7\"\ndependencies = [\n \"hmac\",\n]\n\n[[package]]\nname = \"hmac\"\nversion = \"0.12.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e\"\ndependencies = [\n \"digest\",\n]\n\n[[package]]\nname = \"home\"\nversion = \"0.5.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf\"\ndependencies = [\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"hostname\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"windows-link 0.1.3\",\n]\n\n[[package]]\nname = \"html5ever\"\nversion = \"0.29.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c\"\ndependencies = [\n \"log\",\n \"mac\",\n \"markup5ever\",\n \"match_token\",\n]\n\n[[package]]\nname = \"http\"\nversion = \"1.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565\"\ndependencies = [\n \"bytes\",\n \"fnv\",\n \"itoa\",\n]\n\n[[package]]\nname = \"http-body\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184\"\ndependencies = [\n \"bytes\",\n \"http\",\n]\n\n[[package]]\nname = \"http-body-util\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"http\",\n \"http-body\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"http-range-header\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c\"\n\n[[package]]\nname = \"httparse\"\nversion = \"1.10.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87\"\n\n[[package]]\nname = \"httpdate\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9\"\n\n[[package]]\nname = \"humansize\"\nversion = \"2.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7\"\ndependencies = [\n \"libm\",\n]\n\n[[package]]\nname = \"hyper\"\nversion = \"1.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e\"\ndependencies = [\n \"atomic-waker\",\n \"bytes\",\n \"futures-channel\",\n \"futures-core\",\n \"http\",\n \"http-body\",\n \"httparse\",\n \"httpdate\",\n \"itoa\",\n \"pin-project-lite\",\n \"pin-utils\",\n \"smallvec\",\n \"tokio\",\n \"want\",\n]\n\n[[package]]\nname = \"hyper-util\"\nversion = \"0.1.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8\"\ndependencies = [\n \"base64\",\n \"bytes\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"hyper\",\n \"ipnet\",\n \"libc\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"socket2 0.6.0\",\n \"tokio\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"iana-time-zone\"\nversion = \"0.1.64\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb\"\ndependencies = [\n \"android_system_properties\",\n \"core-foundation-sys\",\n \"iana-time-zone-haiku\",\n \"js-sys\",\n \"log\",\n \"wasm-bindgen\",\n \"windows-core\",\n]\n\n[[package]]\nname = \"iana-time-zone-haiku\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f\"\ndependencies = [\n \"cc\",\n]\n\n[[package]]\nname = \"icu_collections\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47\"\ndependencies = [\n \"displaydoc\",\n \"potential_utf\",\n \"yoke\",\n \"zerofrom\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_locale_core\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a\"\ndependencies = [\n \"displaydoc\",\n \"litemap\",\n \"tinystr\",\n \"writeable\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_normalizer\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979\"\ndependencies = [\n \"displaydoc\",\n \"icu_collections\",\n \"icu_normalizer_data\",\n \"icu_properties\",\n \"icu_provider\",\n \"smallvec\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_normalizer_data\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3\"\n\n[[package]]\nname = \"icu_properties\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b\"\ndependencies = [\n \"displaydoc\",\n \"icu_collections\",\n \"icu_locale_core\",\n \"icu_properties_data\",\n \"icu_provider\",\n \"potential_utf\",\n \"zerotrie\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_properties_data\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632\"\n\n[[package]]\nname = \"icu_provider\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af\"\ndependencies = [\n \"displaydoc\",\n \"icu_locale_core\",\n \"stable_deref_trait\",\n \"tinystr\",\n \"writeable\",\n \"yoke\",\n \"zerofrom\",\n \"zerotrie\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"ident_case\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39\"\n\n[[package]]\nname = \"idna\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de\"\ndependencies = [\n \"idna_adapter\",\n \"smallvec\",\n \"utf8_iter\",\n]\n\n[[package]]\nname = \"idna_adapter\"\nversion = \"1.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344\"\ndependencies = [\n \"icu_normalizer\",\n \"icu_properties\",\n]\n\n[[package]]\nname = \"ignore\"\nversion = \"0.4.23\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b\"\ndependencies = [\n \"crossbeam-deque\",\n \"globset\",\n \"log\",\n \"memchr\",\n \"regex-automata\",\n \"same-file\",\n \"walkdir\",\n \"winapi-util\",\n]\n\n[[package]]\nname = \"include_dir\"\nversion = \"0.7.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd\"\ndependencies = [\n \"include_dir_macros\",\n]\n\n[[package]]\nname = \"include_dir_macros\"\nversion = \"0.7.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n]\n\n[[package]]\nname = \"indenter\"\nversion = \"0.3.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5\"\n\n[[package]]\nname = \"indexmap\"\nversion = \"2.11.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5\"\ndependencies = [\n \"equivalent\",\n \"hashbrown 0.16.0\",\n]\n\n[[package]]\nname = \"indoc\"\nversion = \"2.0.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706\"\ndependencies = [\n \"rustversion\",\n]\n\n[[package]]\nname = \"inherent\"\nversion = \"1.0.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c727f80bfa4a6c6e2508d2f05b6f4bfce242030bd88ed15ae5331c5b5d30fba7\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"inotify\"\nversion = \"0.11.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"inotify-sys\",\n \"libc\",\n]\n\n[[package]]\nname = \"inotify-sys\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"insta\"\nversion = \"1.43.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"46fdb647ebde000f43b5b53f773c30cf9b0cb4300453208713fa38b2c70935a0\"\ndependencies = [\n \"console\",\n \"once_cell\",\n \"pest\",\n \"pest_derive\",\n \"regex\",\n \"serde\",\n \"similar\",\n]\n\n[[package]]\nname = \"io-uring\"\nversion = \"0.7.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"cfg-if\",\n \"libc\",\n]\n\n[[package]]\nname = \"ipnet\"\nversion = \"2.11.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130\"\n\n[[package]]\nname = \"ipnetwork\"\nversion = \"0.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"iri-string\"\nversion = \"0.7.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2\"\ndependencies = [\n \"memchr\",\n \"serde\",\n]\n\n[[package]]\nname = \"is_terminal_polyfill\"\nversion = \"1.70.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf\"\n\n[[package]]\nname = \"itertools\"\nversion = \"0.14.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285\"\ndependencies = [\n \"either\",\n]\n\n[[package]]\nname = \"itoa\"\nversion = \"1.0.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c\"\n\n[[package]]\nname = \"jobserver\"\nversion = \"0.1.34\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33\"\ndependencies = [\n \"getrandom 0.3.3\",\n \"libc\",\n]\n\n[[package]]\nname = \"js-sys\"\nversion = \"0.3.81\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305\"\ndependencies = [\n \"once_cell\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"jsonwebtoken\"\nversion = \"9.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde\"\ndependencies = [\n \"base64\",\n \"js-sys\",\n \"pem\",\n \"ring\",\n \"serde\",\n \"serde_json\",\n \"simple_asn1\",\n]\n\n[[package]]\nname = \"kqueue\"\nversion = \"1.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a\"\ndependencies = [\n \"kqueue-sys\",\n \"libc\",\n]\n\n[[package]]\nname = \"kqueue-sys\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b\"\ndependencies = [\n \"bitflags 1.3.2\",\n \"libc\",\n]\n\n[[package]]\nname = \"lazy_static\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe\"\ndependencies = [\n \"spin\",\n]\n\n[[package]]\nname = \"lettre\"\nversion = \"0.11.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5cb54db6ff7a89efac87dba5baeac57bb9ccd726b49a9b6f21fb92b3966aaf56\"\ndependencies = [\n \"async-trait\",\n \"base64\",\n \"chumsky\",\n \"email-encoding\",\n \"email_address\",\n \"fastrand\",\n \"futures-io\",\n \"futures-util\",\n \"hostname\",\n \"httpdate\",\n \"idna\",\n \"mime\",\n \"nom 8.0.0\",\n \"percent-encoding\",\n \"quoted_printable\",\n \"rustls\",\n \"socket2 0.6.0\",\n \"tokio\",\n \"tokio-rustls\",\n \"url\",\n \"webpki-roots 1.0.2\",\n]\n\n[[package]]\nname = \"libc\"\nversion = \"0.2.176\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174\"\n\n[[package]]\nname = \"libm\"\nversion = \"0.2.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de\"\n\n[[package]]\nname = \"libredox\"\nversion = \"0.1.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"libc\",\n \"redox_syscall\",\n]\n\n[[package]]\nname = \"libsqlite3-sys\"\nversion = \"0.30.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149\"\ndependencies = [\n \"cc\",\n \"pkg-config\",\n \"vcpkg\",\n]\n\n[[package]]\nname = \"litemap\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956\"\n\n[[package]]\nname = \"lock_api\"\nversion = \"0.4.14\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965\"\ndependencies = [\n \"scopeguard\",\n]\n\n[[package]]\nname = \"loco-gen\"\nversion = \"0.16.3\"\nsource = \"git+https://github.com/SeaQL/loco?branch=master#0e2860b7885e6c00e013b3618896a78095809ede\"\ndependencies = [\n \"chrono\",\n \"clap\",\n \"colored 3.0.0\",\n \"cruet 0.14.0\",\n \"duct\",\n \"heck 0.4.1\",\n \"include_dir\",\n \"regex\",\n \"rrgen\",\n \"serde\",\n \"serde_json\",\n \"tera\",\n \"thiserror 1.0.69\",\n \"tracing\",\n]\n\n[[package]]\nname = \"loco-rs\"\nversion = \"0.16.3\"\nsource = \"git+https://github.com/SeaQL/loco?branch=master#0e2860b7885e6c00e013b3618896a78095809ede\"\ndependencies = [\n \"argon2\",\n \"async-trait\",\n \"axum\",\n \"axum-extra\",\n \"axum-test\",\n \"backtrace_printer\",\n \"byte-unit\",\n \"bytes\",\n \"chrono\",\n \"clap\",\n \"colored 3.0.0\",\n \"cruet 0.13.3\",\n \"dashmap 6.1.0\",\n \"duct\",\n \"duct_sh\",\n \"english-to-cron\",\n \"futures-util\",\n \"heck 0.4.1\",\n \"include_dir\",\n \"ipnetwork\",\n \"jsonwebtoken\",\n \"lettre\",\n \"loco-gen\",\n \"moka\",\n \"notify\",\n \"opendal\",\n \"rand 0.9.2\",\n \"redis\",\n \"regex\",\n \"scraper\",\n \"sea-orm\",\n \"sea-orm-migration\",\n \"semver\",\n \"serde\",\n \"serde_json\",\n \"serde_variant\",\n \"serde_yaml\",\n \"sqlx\",\n \"tera\",\n \"thiserror 1.0.69\",\n \"tokio\",\n \"tokio-cron-scheduler\",\n \"tokio-util\",\n \"toml\",\n \"tower 0.4.13\",\n \"tower-http\",\n \"tracing\",\n \"tracing-appender\",\n \"tracing-subscriber\",\n \"tree-fs\",\n \"ulid\",\n \"uuid\",\n \"validator\",\n]\n\n[[package]]\nname = \"log\"\nversion = \"0.4.28\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432\"\n\n[[package]]\nname = \"mac\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4\"\n\n[[package]]\nname = \"markup5ever\"\nversion = \"0.14.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18\"\ndependencies = [\n \"log\",\n \"phf\",\n \"phf_codegen\",\n \"string_cache\",\n \"string_cache_codegen\",\n \"tendril\",\n]\n\n[[package]]\nname = \"match_token\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"matchers\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9\"\ndependencies = [\n \"regex-automata\",\n]\n\n[[package]]\nname = \"matchit\"\nversion = \"0.8.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3\"\n\n[[package]]\nname = \"md-5\"\nversion = \"0.10.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf\"\ndependencies = [\n \"cfg-if\",\n \"digest\",\n]\n\n[[package]]\nname = \"memchr\"\nversion = \"2.7.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273\"\n\n[[package]]\nname = \"migration\"\nversion = \"0.1.0\"\ndependencies = [\n \"loco-rs\",\n \"sea-orm-migration\",\n \"tokio\",\n]\n\n[[package]]\nname = \"mime\"\nversion = \"0.3.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a\"\n\n[[package]]\nname = \"mime_guess\"\nversion = \"2.0.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e\"\ndependencies = [\n \"mime\",\n \"unicase\",\n]\n\n[[package]]\nname = \"minimal-lexical\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a\"\n\n[[package]]\nname = \"miniz_oxide\"\nversion = \"0.8.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316\"\ndependencies = [\n \"adler2\",\n \"simd-adler32\",\n]\n\n[[package]]\nname = \"mio\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c\"\ndependencies = [\n \"libc\",\n \"log\",\n \"wasi 0.11.1+wasi-snapshot-preview1\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"moka\"\nversion = \"0.12.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8261cd88c312e0004c1d51baad2980c66528dfdb2bee62003e643a4d8f86b077\"\ndependencies = [\n \"crossbeam-channel\",\n \"crossbeam-epoch\",\n \"crossbeam-utils\",\n \"equivalent\",\n \"parking_lot\",\n \"portable-atomic\",\n \"rustc_version\",\n \"smallvec\",\n \"tagptr\",\n \"uuid\",\n]\n\n[[package]]\nname = \"multer\"\nversion = \"3.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b\"\ndependencies = [\n \"bytes\",\n \"encoding_rs\",\n \"futures-util\",\n \"http\",\n \"httparse\",\n \"memchr\",\n \"mime\",\n \"spin\",\n \"version_check\",\n]\n\n[[package]]\nname = \"new_debug_unreachable\"\nversion = \"1.0.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086\"\n\n[[package]]\nname = \"nom\"\nversion = \"7.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a\"\ndependencies = [\n \"memchr\",\n \"minimal-lexical\",\n]\n\n[[package]]\nname = \"nom\"\nversion = \"8.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"notify\"\nversion = \"8.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"fsevent-sys\",\n \"inotify\",\n \"kqueue\",\n \"libc\",\n \"log\",\n \"mio\",\n \"notify-types\",\n \"walkdir\",\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"notify-types\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d\"\n\n[[package]]\nname = \"nu-ansi-term\"\nversion = \"0.50.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399\"\ndependencies = [\n \"windows-sys 0.52.0\",\n]\n\n[[package]]\nname = \"num-bigint\"\nversion = \"0.4.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9\"\ndependencies = [\n \"num-integer\",\n \"num-traits\",\n]\n\n[[package]]\nname = \"num-bigint-dig\"\nversion = \"0.8.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151\"\ndependencies = [\n \"byteorder\",\n \"lazy_static\",\n \"libm\",\n \"num-integer\",\n \"num-iter\",\n \"num-traits\",\n \"rand 0.8.5\",\n \"smallvec\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"num-conv\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9\"\n\n[[package]]\nname = \"num-derive\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"num-integer\"\nversion = \"0.1.46\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f\"\ndependencies = [\n \"num-traits\",\n]\n\n[[package]]\nname = \"num-iter\"\nversion = \"0.1.45\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf\"\ndependencies = [\n \"autocfg\",\n \"num-integer\",\n \"num-traits\",\n]\n\n[[package]]\nname = \"num-traits\"\nversion = \"0.2.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841\"\ndependencies = [\n \"autocfg\",\n \"libm\",\n]\n\n[[package]]\nname = \"object\"\nversion = \"0.37.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"once_cell\"\nversion = \"1.21.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d\"\n\n[[package]]\nname = \"once_cell_polyfill\"\nversion = \"1.70.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad\"\n\n[[package]]\nname = \"opendal\"\nversion = \"0.54.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ffb9838d0575c6dbaf3fcec7255af8d5771996d4af900bbb6fa9a314dec00a1a\"\ndependencies = [\n \"anyhow\",\n \"backon\",\n \"base64\",\n \"bytes\",\n \"chrono\",\n \"futures\",\n \"getrandom 0.2.16\",\n \"http\",\n \"http-body\",\n \"log\",\n \"md-5\",\n \"percent-encoding\",\n \"quick-xml\",\n \"reqwest\",\n \"serde\",\n \"serde_json\",\n \"tokio\",\n \"uuid\",\n]\n\n[[package]]\nname = \"ordered-float\"\nversion = \"4.6.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951\"\ndependencies = [\n \"num-traits\",\n]\n\n[[package]]\nname = \"os_pipe\"\nversion = \"1.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"db335f4760b14ead6290116f2427bf33a14d4f0617d49f78a246de10c1831224\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"ouroboros\"\nversion = \"0.18.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59\"\ndependencies = [\n \"aliasable\",\n \"ouroboros_macro\",\n \"static_assertions\",\n]\n\n[[package]]\nname = \"ouroboros_macro\"\nversion = \"0.18.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0\"\ndependencies = [\n \"heck 0.4.1\",\n \"proc-macro2\",\n \"proc-macro2-diagnostics\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"parking\"\nversion = \"2.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba\"\n\n[[package]]\nname = \"parking_lot\"\nversion = \"0.12.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a\"\ndependencies = [\n \"lock_api\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"parking_lot_core\"\nversion = \"0.9.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"redox_syscall\",\n \"smallvec\",\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"parse-zoneinfo\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24\"\ndependencies = [\n \"regex\",\n]\n\n[[package]]\nname = \"password-hash\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166\"\ndependencies = [\n \"base64ct\",\n \"rand_core 0.6.4\",\n \"subtle\",\n]\n\n[[package]]\nname = \"pem\"\nversion = \"3.0.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3\"\ndependencies = [\n \"base64\",\n \"serde\",\n]\n\n[[package]]\nname = \"pem-rfc7468\"\nversion = \"0.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412\"\ndependencies = [\n \"base64ct\",\n]\n\n[[package]]\nname = \"percent-encoding\"\nversion = \"2.3.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220\"\n\n[[package]]\nname = \"pest\"\nversion = \"2.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4\"\ndependencies = [\n \"memchr\",\n \"ucd-trie\",\n]\n\n[[package]]\nname = \"pest_derive\"\nversion = \"2.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de\"\ndependencies = [\n \"pest\",\n \"pest_generator\",\n]\n\n[[package]]\nname = \"pest_generator\"\nversion = \"2.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843\"\ndependencies = [\n \"pest\",\n \"pest_meta\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"pest_meta\"\nversion = \"2.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a\"\ndependencies = [\n \"pest\",\n \"sha2\",\n]\n\n[[package]]\nname = \"pgvector\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fc58e2d255979a31caa7cabfa7aac654af0354220719ab7a68520ae7a91e8c0b\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"phf\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078\"\ndependencies = [\n \"phf_macros\",\n \"phf_shared\",\n]\n\n[[package]]\nname = \"phf_codegen\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a\"\ndependencies = [\n \"phf_generator\",\n \"phf_shared\",\n]\n\n[[package]]\nname = \"phf_generator\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d\"\ndependencies = [\n \"phf_shared\",\n \"rand 0.8.5\",\n]\n\n[[package]]\nname = \"phf_macros\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216\"\ndependencies = [\n \"phf_generator\",\n \"phf_shared\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"phf_shared\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5\"\ndependencies = [\n \"siphasher\",\n]\n\n[[package]]\nname = \"pin-project-lite\"\nversion = \"0.2.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b\"\n\n[[package]]\nname = \"pin-utils\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184\"\n\n[[package]]\nname = \"pkcs1\"\nversion = \"0.7.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f\"\ndependencies = [\n \"der\",\n \"pkcs8\",\n \"spki\",\n]\n\n[[package]]\nname = \"pkcs8\"\nversion = \"0.10.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7\"\ndependencies = [\n \"der\",\n \"spki\",\n]\n\n[[package]]\nname = \"pkg-config\"\nversion = \"0.3.32\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c\"\n\n[[package]]\nname = \"pluralizer\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4b3eba432a00a1f6c16f39147847a870e94e2e9b992759b503e330efec778cbe\"\ndependencies = [\n \"once_cell\",\n \"regex\",\n]\n\n[[package]]\nname = \"portable-atomic\"\nversion = \"1.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483\"\n\n[[package]]\nname = \"potential_utf\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a\"\ndependencies = [\n \"zerovec\",\n]\n\n[[package]]\nname = \"powerfmt\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391\"\n\n[[package]]\nname = \"ppv-lite86\"\nversion = \"0.2.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9\"\ndependencies = [\n \"zerocopy\",\n]\n\n[[package]]\nname = \"precomputed-hash\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c\"\n\n[[package]]\nname = \"pretty_assertions\"\nversion = \"1.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d\"\ndependencies = [\n \"diff\",\n \"yansi\",\n]\n\n[[package]]\nname = \"proc-macro-crate\"\nversion = \"3.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983\"\ndependencies = [\n \"toml_edit 0.23.6\",\n]\n\n[[package]]\nname = \"proc-macro-error-attr2\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n]\n\n[[package]]\nname = \"proc-macro-error2\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802\"\ndependencies = [\n \"proc-macro-error-attr2\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"proc-macro2\"\nversion = \"1.0.101\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de\"\ndependencies = [\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"proc-macro2-diagnostics\"\nversion = \"0.10.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"version_check\",\n \"yansi\",\n]\n\n[[package]]\nname = \"psm\"\nversion = \"0.1.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e66fcd288453b748497d8fb18bccc83a16b0518e3906d4b8df0a8d42d93dbb1c\"\ndependencies = [\n \"cc\",\n]\n\n[[package]]\nname = \"ptr_meta\"\nversion = \"0.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1\"\ndependencies = [\n \"ptr_meta_derive\",\n]\n\n[[package]]\nname = \"ptr_meta_derive\"\nversion = \"0.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"quick-xml\"\nversion = \"0.37.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb\"\ndependencies = [\n \"memchr\",\n \"serde\",\n]\n\n[[package]]\nname = \"quote\"\nversion = \"1.0.41\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1\"\ndependencies = [\n \"proc-macro2\",\n]\n\n[[package]]\nname = \"quoted_printable\"\nversion = \"0.5.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"640c9bd8497b02465aeef5375144c26062e0dcd5939dfcbb0f5db76cb8c17c73\"\n\n[[package]]\nname = \"r-efi\"\nversion = \"5.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f\"\n\n[[package]]\nname = \"radium\"\nversion = \"0.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09\"\n\n[[package]]\nname = \"rand\"\nversion = \"0.8.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404\"\ndependencies = [\n \"libc\",\n \"rand_chacha 0.3.1\",\n \"rand_core 0.6.4\",\n]\n\n[[package]]\nname = \"rand\"\nversion = \"0.9.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1\"\ndependencies = [\n \"rand_chacha 0.9.0\",\n \"rand_core 0.9.3\",\n]\n\n[[package]]\nname = \"rand_chacha\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88\"\ndependencies = [\n \"ppv-lite86\",\n \"rand_core 0.6.4\",\n]\n\n[[package]]\nname = \"rand_chacha\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb\"\ndependencies = [\n \"ppv-lite86\",\n \"rand_core 0.9.3\",\n]\n\n[[package]]\nname = \"rand_core\"\nversion = \"0.6.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c\"\ndependencies = [\n \"getrandom 0.2.16\",\n]\n\n[[package]]\nname = \"rand_core\"\nversion = \"0.9.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38\"\ndependencies = [\n \"getrandom 0.3.3\",\n]\n\n[[package]]\nname = \"redis\"\nversion = \"0.31.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0bc1ea653e0b2e097db3ebb5b7f678be339620b8041f66b30a308c1d45d36a7f\"\ndependencies = [\n \"bytes\",\n \"cfg-if\",\n \"combine\",\n \"futures-util\",\n \"itoa\",\n \"num-bigint\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"ryu\",\n \"sha1_smol\",\n \"socket2 0.5.10\",\n \"tokio\",\n \"tokio-util\",\n \"url\",\n]\n\n[[package]]\nname = \"redox_syscall\"\nversion = \"0.5.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d\"\ndependencies = [\n \"bitflags 2.9.4\",\n]\n\n[[package]]\nname = \"regex\"\nversion = \"1.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c\"\ndependencies = [\n \"aho-corasick\",\n \"memchr\",\n \"regex-automata\",\n \"regex-syntax\",\n]\n\n[[package]]\nname = \"regex-automata\"\nversion = \"0.4.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad\"\ndependencies = [\n \"aho-corasick\",\n \"memchr\",\n \"regex-syntax\",\n]\n\n[[package]]\nname = \"regex-syntax\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001\"\n\n[[package]]\nname = \"relative-path\"\nversion = \"1.9.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2\"\n\n[[package]]\nname = \"rend\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c\"\ndependencies = [\n \"bytecheck\",\n]\n\n[[package]]\nname = \"reqwest\"\nversion = \"0.12.23\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb\"\ndependencies = [\n \"base64\",\n \"bytes\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"hyper\",\n \"hyper-util\",\n \"js-sys\",\n \"log\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"serde\",\n \"serde_json\",\n \"serde_urlencoded\",\n \"sync_wrapper\",\n \"tokio\",\n \"tokio-util\",\n \"tower 0.5.2\",\n \"tower-http\",\n \"tower-service\",\n \"url\",\n \"wasm-bindgen\",\n \"wasm-bindgen-futures\",\n \"wasm-streams\",\n \"web-sys\",\n]\n\n[[package]]\nname = \"reserve-port\"\nversion = \"2.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"21918d6644020c6f6ef1993242989bf6d4952d2e025617744f184c02df51c356\"\ndependencies = [\n \"thiserror 2.0.17\",\n]\n\n[[package]]\nname = \"ring\"\nversion = \"0.17.14\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7\"\ndependencies = [\n \"cc\",\n \"cfg-if\",\n \"getrandom 0.2.16\",\n \"libc\",\n \"untrusted\",\n \"windows-sys 0.52.0\",\n]\n\n[[package]]\nname = \"rkyv\"\nversion = \"0.7.45\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b\"\ndependencies = [\n \"bitvec\",\n \"bytecheck\",\n \"bytes\",\n \"hashbrown 0.12.3\",\n \"ptr_meta\",\n \"rend\",\n \"rkyv_derive\",\n \"seahash\",\n \"tinyvec\",\n \"uuid\",\n]\n\n[[package]]\nname = \"rkyv_derive\"\nversion = \"0.7.45\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"rrgen\"\nversion = \"0.5.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ee7a7ede035354391a37e42aa4935b3d8921f0ded896d2ce44bb1a3b6dd76bab\"\ndependencies = [\n \"cruet 0.13.3\",\n \"fs-err\",\n \"glob\",\n \"heck 0.4.1\",\n \"regex\",\n \"serde\",\n \"serde_json\",\n \"serde_regex\",\n \"serde_yaml\",\n \"tera\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"rsa\"\nversion = \"0.9.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b\"\ndependencies = [\n \"const-oid\",\n \"digest\",\n \"num-bigint-dig\",\n \"num-integer\",\n \"num-traits\",\n \"pkcs1\",\n \"pkcs8\",\n \"rand_core 0.6.4\",\n \"signature\",\n \"spki\",\n \"subtle\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"rstest\"\nversion = \"0.18.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"97eeab2f3c0a199bc4be135c36c924b6590b88c377d416494288c14f2db30199\"\ndependencies = [\n \"futures\",\n \"futures-timer\",\n \"rstest_macros\",\n \"rustc_version\",\n]\n\n[[package]]\nname = \"rstest_macros\"\nversion = \"0.18.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d428f8247852f894ee1be110b375111b586d4fa431f6c46e64ba5a0dcccbe605\"\ndependencies = [\n \"cfg-if\",\n \"glob\",\n \"proc-macro2\",\n \"quote\",\n \"regex\",\n \"relative-path\",\n \"rustc_version\",\n \"syn 2.0.106\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"rust-multipart-rfc7578_2\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c839d037155ebc06a571e305af66ff9fd9063a6e662447051737e1ac75beea41\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"mime\",\n \"rand 0.9.2\",\n \"thiserror 2.0.17\",\n]\n\n[[package]]\nname = \"rust_decimal\"\nversion = \"1.38.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8975fc98059f365204d635119cf9c5a60ae67b841ed49b5422a9a7e56cdfac0\"\ndependencies = [\n \"arrayvec\",\n \"borsh\",\n \"bytes\",\n \"num-traits\",\n \"rand 0.8.5\",\n \"rkyv\",\n \"serde\",\n \"serde_json\",\n]\n\n[[package]]\nname = \"rustc-demangle\"\nversion = \"0.1.26\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace\"\n\n[[package]]\nname = \"rustc_version\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92\"\ndependencies = [\n \"semver\",\n]\n\n[[package]]\nname = \"rustls\"\nversion = \"0.23.32\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40\"\ndependencies = [\n \"log\",\n \"once_cell\",\n \"ring\",\n \"rustls-pki-types\",\n \"rustls-webpki\",\n \"subtle\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"rustls-pki-types\"\nversion = \"1.12.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79\"\ndependencies = [\n \"zeroize\",\n]\n\n[[package]]\nname = \"rustls-webpki\"\nversion = \"0.103.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf\"\ndependencies = [\n \"ring\",\n \"rustls-pki-types\",\n \"untrusted\",\n]\n\n[[package]]\nname = \"rustversion\"\nversion = \"1.0.22\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d\"\n\n[[package]]\nname = \"ryu\"\nversion = \"1.0.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f\"\n\n[[package]]\nname = \"same-file\"\nversion = \"1.0.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502\"\ndependencies = [\n \"winapi-util\",\n]\n\n[[package]]\nname = \"scopeguard\"\nversion = \"1.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49\"\n\n[[package]]\nname = \"scraper\"\nversion = \"0.21.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b0e749d29b2064585327af5038a5a8eb73aeebad4a3472e83531a436563f7208\"\ndependencies = [\n \"ahash 0.8.12\",\n \"cssparser\",\n \"ego-tree\",\n \"getopts\",\n \"html5ever\",\n \"indexmap\",\n \"precomputed-hash\",\n \"selectors\",\n \"tendril\",\n]\n\n[[package]]\nname = \"sea-bae\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f694a6ab48f14bc063cfadff30ab551d3c7e46d8f81836c51989d548f44a2a25\"\ndependencies = [\n \"heck 0.4.1\",\n \"proc-macro-error2\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"sea-orm\"\nversion = \"2.0.0-rc.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"880cc0a64f1ee0320d7d6cd2b9290c27e89750669cfc5b6afdce1654755a2983\"\ndependencies = [\n \"async-stream\",\n \"async-trait\",\n \"bigdecimal\",\n \"chrono\",\n \"derive_more 2.0.1\",\n \"futures-util\",\n \"itertools\",\n \"log\",\n \"ouroboros\",\n \"pgvector\",\n \"rust_decimal\",\n \"sea-orm-macros\",\n \"sea-query\",\n \"sea-query-sqlx\",\n \"sea-schema\",\n \"serde\",\n \"serde_json\",\n \"sqlx\",\n \"strum\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tracing\",\n \"url\",\n \"uuid\",\n]\n\n[[package]]\nname = \"sea-orm-cli\"\nversion = \"2.0.0-rc.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ce69601010a0507a7e465a63bb63064984f7cfd05d04af39df70834e5713aeb6\"\ndependencies = [\n \"chrono\",\n \"clap\",\n \"dotenvy\",\n \"glob\",\n \"indoc\",\n \"regex\",\n \"sea-schema\",\n \"sqlx\",\n \"tokio\",\n \"tracing\",\n \"tracing-subscriber\",\n \"url\",\n]\n\n[[package]]\nname = \"sea-orm-macros\"\nversion = \"2.0.0-rc.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8aae91cb86cf389da96119df71967ffb1b3caf1687303def77336f8dc9d33e78\"\ndependencies = [\n \"heck 0.5.0\",\n \"pluralizer\",\n \"proc-macro2\",\n \"quote\",\n \"sea-bae\",\n \"syn 2.0.106\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"sea-orm-migration\"\nversion = \"2.0.0-rc.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0ab8128cb63269debc8a88dbef5577076a5b53f8d0055d2d0939f1533154e2ef\"\ndependencies = [\n \"async-trait\",\n \"clap\",\n \"dotenvy\",\n \"sea-orm\",\n \"sea-orm-cli\",\n \"sea-schema\",\n \"tracing\",\n \"tracing-subscriber\",\n]\n\n[[package]]\nname = \"sea-query\"\nversion = \"1.0.0-rc.22\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"58df33eded14fba318338034b4bd197973fd7570a9f93ee5f88a27a7731f44f3\"\ndependencies = [\n \"bigdecimal\",\n \"chrono\",\n \"inherent\",\n \"ordered-float\",\n \"rust_decimal\",\n \"sea-query-derive\",\n \"serde_json\",\n \"time\",\n \"uuid\",\n]\n\n[[package]]\nname = \"sea-query-derive\"\nversion = \"1.0.0-rc.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"217e9422de35f26c16c5f671fce3c075a65e10322068dbc66078428634af6195\"\ndependencies = [\n \"darling\",\n \"heck 0.4.1\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"thiserror 2.0.17\",\n]\n\n[[package]]\nname = \"sea-query-sqlx\"\nversion = \"0.8.0-rc.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"68873fa1776b4c25a26e7679f8ee22332978c721168ec1b0b32b6583d5a9381d\"\ndependencies = [\n \"bigdecimal\",\n \"chrono\",\n \"rust_decimal\",\n \"sea-query\",\n \"serde_json\",\n \"sqlx\",\n \"time\",\n \"uuid\",\n]\n\n[[package]]\nname = \"sea-schema\"\nversion = \"0.17.0-rc.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"845b7ed3e7a4f4458fe7218931b54e92be0dce01fc3c310d996c7b76d9a37ea5\"\ndependencies = [\n \"async-trait\",\n \"sea-query\",\n \"sea-query-sqlx\",\n \"sea-schema-derive\",\n \"sqlx\",\n]\n\n[[package]]\nname = \"sea-schema-derive\"\nversion = \"0.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"debdc8729c37fdbf88472f97fd470393089f997a909e535ff67c544d18cfccf0\"\ndependencies = [\n \"heck 0.4.1\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"seahash\"\nversion = \"4.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b\"\n\n[[package]]\nname = \"selectors\"\nversion = \"0.26.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fd568a4c9bb598e291a08244a5c1f5a8a6650bee243b5b0f8dbb3d9cc1d87fe8\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"cssparser\",\n \"derive_more 0.99.20\",\n \"fxhash\",\n \"log\",\n \"new_debug_unreachable\",\n \"phf\",\n \"phf_codegen\",\n \"precomputed-hash\",\n \"servo_arc\",\n \"smallvec\",\n]\n\n[[package]]\nname = \"semver\"\nversion = \"1.0.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2\"\n\n[[package]]\nname = \"serde\"\nversion = \"1.0.228\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e\"\ndependencies = [\n \"serde_core\",\n \"serde_derive\",\n]\n\n[[package]]\nname = \"serde_core\"\nversion = \"1.0.228\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad\"\ndependencies = [\n \"serde_derive\",\n]\n\n[[package]]\nname = \"serde_derive\"\nversion = \"1.0.228\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"serde_json\"\nversion = \"1.0.145\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c\"\ndependencies = [\n \"itoa\",\n \"memchr\",\n \"ryu\",\n \"serde\",\n \"serde_core\",\n]\n\n[[package]]\nname = \"serde_path_to_error\"\nversion = \"0.1.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457\"\ndependencies = [\n \"itoa\",\n \"serde\",\n \"serde_core\",\n]\n\n[[package]]\nname = \"serde_regex\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf\"\ndependencies = [\n \"regex\",\n \"serde\",\n]\n\n[[package]]\nname = \"serde_spanned\"\nversion = \"0.6.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"serde_urlencoded\"\nversion = \"0.7.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd\"\ndependencies = [\n \"form_urlencoded\",\n \"itoa\",\n \"ryu\",\n \"serde\",\n]\n\n[[package]]\nname = \"serde_variant\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0a0068df419f9d9b6488fdded3f1c818522cdea328e02ce9d9f147380265a432\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"serde_yaml\"\nversion = \"0.9.34+deprecated\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47\"\ndependencies = [\n \"indexmap\",\n \"itoa\",\n \"ryu\",\n \"serde\",\n \"unsafe-libyaml\",\n]\n\n[[package]]\nname = \"serial_test\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d\"\ndependencies = [\n \"dashmap 5.5.3\",\n \"futures\",\n \"lazy_static\",\n \"log\",\n \"parking_lot\",\n \"serial_test_derive\",\n]\n\n[[package]]\nname = \"serial_test_derive\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"servo_arc\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"204ea332803bd95a0b60388590d59cf6468ec9becf626e2451f1d26a1d972de4\"\ndependencies = [\n \"stable_deref_trait\",\n]\n\n[[package]]\nname = \"sha1\"\nversion = \"0.10.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba\"\ndependencies = [\n \"cfg-if\",\n \"cpufeatures\",\n \"digest\",\n]\n\n[[package]]\nname = \"sha1_smol\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d\"\n\n[[package]]\nname = \"sha2\"\nversion = \"0.10.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283\"\ndependencies = [\n \"cfg-if\",\n \"cpufeatures\",\n \"digest\",\n]\n\n[[package]]\nname = \"sharded-slab\"\nversion = \"0.1.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6\"\ndependencies = [\n \"lazy_static\",\n]\n\n[[package]]\nname = \"shared_child\"\nversion = \"1.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e362d9935bc50f019969e2f9ecd66786612daae13e8f277be7bfb66e8bed3f7\"\ndependencies = [\n \"libc\",\n \"sigchld\",\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"shared_thread\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"52b86057fcb5423f5018e331ac04623e32d6b5ce85e33300f92c79a1973928b0\"\n\n[[package]]\nname = \"shlex\"\nversion = \"1.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64\"\n\n[[package]]\nname = \"sigchld\"\nversion = \"0.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47106eded3c154e70176fc83df9737335c94ce22f821c32d17ed1db1f83badb1\"\ndependencies = [\n \"libc\",\n \"os_pipe\",\n \"signal-hook\",\n]\n\n[[package]]\nname = \"signal-hook\"\nversion = \"0.3.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2\"\ndependencies = [\n \"libc\",\n \"signal-hook-registry\",\n]\n\n[[package]]\nname = \"signal-hook-registry\"\nversion = \"1.4.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"signature\"\nversion = \"2.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de\"\ndependencies = [\n \"digest\",\n \"rand_core 0.6.4\",\n]\n\n[[package]]\nname = \"simd-adler32\"\nversion = \"0.3.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe\"\n\n[[package]]\nname = \"simdutf8\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e\"\n\n[[package]]\nname = \"similar\"\nversion = \"2.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa\"\n\n[[package]]\nname = \"simple_asn1\"\nversion = \"0.6.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb\"\ndependencies = [\n \"num-bigint\",\n \"num-traits\",\n \"thiserror 2.0.17\",\n \"time\",\n]\n\n[[package]]\nname = \"siphasher\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d\"\n\n[[package]]\nname = \"slab\"\nversion = \"0.4.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589\"\n\n[[package]]\nname = \"slug\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724\"\ndependencies = [\n \"deunicode\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"smallvec\"\nversion = \"1.15.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"socket2\"\nversion = \"0.5.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.52.0\",\n]\n\n[[package]]\nname = \"socket2\"\nversion = \"0.6.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"spin\"\nversion = \"0.9.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67\"\ndependencies = [\n \"lock_api\",\n]\n\n[[package]]\nname = \"spki\"\nversion = \"0.7.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d\"\ndependencies = [\n \"base64ct\",\n \"der\",\n]\n\n[[package]]\nname = \"sqlx\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc\"\ndependencies = [\n \"sqlx-core\",\n \"sqlx-macros\",\n \"sqlx-mysql\",\n \"sqlx-postgres\",\n \"sqlx-sqlite\",\n]\n\n[[package]]\nname = \"sqlx-core\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6\"\ndependencies = [\n \"base64\",\n \"bigdecimal\",\n \"bytes\",\n \"chrono\",\n \"crc\",\n \"crossbeam-queue\",\n \"either\",\n \"event-listener\",\n \"futures-core\",\n \"futures-intrusive\",\n \"futures-io\",\n \"futures-util\",\n \"hashbrown 0.15.5\",\n \"hashlink\",\n \"indexmap\",\n \"log\",\n \"memchr\",\n \"once_cell\",\n \"percent-encoding\",\n \"rust_decimal\",\n \"rustls\",\n \"serde\",\n \"serde_json\",\n \"sha2\",\n \"smallvec\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tokio\",\n \"tokio-stream\",\n \"tracing\",\n \"url\",\n \"uuid\",\n \"webpki-roots 0.26.11\",\n]\n\n[[package]]\nname = \"sqlx-macros\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"sqlx-core\",\n \"sqlx-macros-core\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"sqlx-macros-core\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b\"\ndependencies = [\n \"dotenvy\",\n \"either\",\n \"heck 0.5.0\",\n \"hex\",\n \"once_cell\",\n \"proc-macro2\",\n \"quote\",\n \"serde\",\n \"serde_json\",\n \"sha2\",\n \"sqlx-core\",\n \"sqlx-mysql\",\n \"sqlx-postgres\",\n \"sqlx-sqlite\",\n \"syn 2.0.106\",\n \"tokio\",\n \"url\",\n]\n\n[[package]]\nname = \"sqlx-mysql\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526\"\ndependencies = [\n \"atoi\",\n \"base64\",\n \"bigdecimal\",\n \"bitflags 2.9.4\",\n \"byteorder\",\n \"bytes\",\n \"chrono\",\n \"crc\",\n \"digest\",\n \"dotenvy\",\n \"either\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-io\",\n \"futures-util\",\n \"generic-array\",\n \"hex\",\n \"hkdf\",\n \"hmac\",\n \"itoa\",\n \"log\",\n \"md-5\",\n \"memchr\",\n \"once_cell\",\n \"percent-encoding\",\n \"rand 0.8.5\",\n \"rsa\",\n \"rust_decimal\",\n \"serde\",\n \"sha1\",\n \"sha2\",\n \"smallvec\",\n \"sqlx-core\",\n \"stringprep\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tracing\",\n \"uuid\",\n \"whoami\",\n]\n\n[[package]]\nname = \"sqlx-postgres\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46\"\ndependencies = [\n \"atoi\",\n \"base64\",\n \"bigdecimal\",\n \"bitflags 2.9.4\",\n \"byteorder\",\n \"chrono\",\n \"crc\",\n \"dotenvy\",\n \"etcetera\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-util\",\n \"hex\",\n \"hkdf\",\n \"hmac\",\n \"home\",\n \"itoa\",\n \"log\",\n \"md-5\",\n \"memchr\",\n \"num-bigint\",\n \"once_cell\",\n \"rand 0.8.5\",\n \"rust_decimal\",\n \"serde\",\n \"serde_json\",\n \"sha2\",\n \"smallvec\",\n \"sqlx-core\",\n \"stringprep\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tracing\",\n \"uuid\",\n \"whoami\",\n]\n\n[[package]]\nname = \"sqlx-sqlite\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea\"\ndependencies = [\n \"atoi\",\n \"chrono\",\n \"flume\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-executor\",\n \"futures-intrusive\",\n \"futures-util\",\n \"libsqlite3-sys\",\n \"log\",\n \"percent-encoding\",\n \"serde\",\n \"serde_urlencoded\",\n \"sqlx-core\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tracing\",\n \"url\",\n \"uuid\",\n]\n\n[[package]]\nname = \"stable_deref_trait\"\nversion = \"1.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3\"\n\n[[package]]\nname = \"stacker\"\nversion = \"0.1.22\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e1f8b29fb42aafcea4edeeb6b2f2d7ecd0d969c48b4cf0d2e64aafc471dd6e59\"\ndependencies = [\n \"cc\",\n \"cfg-if\",\n \"libc\",\n \"psm\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"static_assertions\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f\"\n\n[[package]]\nname = \"string_cache\"\nversion = \"0.8.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f\"\ndependencies = [\n \"new_debug_unreachable\",\n \"parking_lot\",\n \"phf_shared\",\n \"precomputed-hash\",\n \"serde\",\n]\n\n[[package]]\nname = \"string_cache_codegen\"\nversion = \"0.5.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0\"\ndependencies = [\n \"phf_generator\",\n \"phf_shared\",\n \"proc-macro2\",\n \"quote\",\n]\n\n[[package]]\nname = \"stringprep\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1\"\ndependencies = [\n \"unicode-bidi\",\n \"unicode-normalization\",\n \"unicode-properties\",\n]\n\n[[package]]\nname = \"strsim\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f\"\n\n[[package]]\nname = \"strum\"\nversion = \"0.27.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf\"\n\n[[package]]\nname = \"subtle\"\nversion = \"2.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292\"\n\n[[package]]\nname = \"syn\"\nversion = \"1.0.109\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"syn\"\nversion = \"2.0.106\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"sync_wrapper\"\nversion = \"1.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263\"\ndependencies = [\n \"futures-core\",\n]\n\n[[package]]\nname = \"synstructure\"\nversion = \"0.13.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"tagptr\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417\"\n\n[[package]]\nname = \"tap\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369\"\n\n[[package]]\nname = \"tendril\"\nversion = \"0.4.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0\"\ndependencies = [\n \"futf\",\n \"mac\",\n \"utf-8\",\n]\n\n[[package]]\nname = \"tera\"\nversion = \"1.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ab9d851b45e865f178319da0abdbfe6acbc4328759ff18dafc3a41c16b4cd2ee\"\ndependencies = [\n \"chrono\",\n \"chrono-tz\",\n \"globwalk\",\n \"humansize\",\n \"lazy_static\",\n \"percent-encoding\",\n \"pest\",\n \"pest_derive\",\n \"rand 0.8.5\",\n \"regex\",\n \"serde\",\n \"serde_json\",\n \"slug\",\n \"unic-segment\",\n]\n\n[[package]]\nname = \"thiserror\"\nversion = \"1.0.69\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52\"\ndependencies = [\n \"thiserror-impl 1.0.69\",\n]\n\n[[package]]\nname = \"thiserror\"\nversion = \"2.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8\"\ndependencies = [\n \"thiserror-impl 2.0.17\",\n]\n\n[[package]]\nname = \"thiserror-impl\"\nversion = \"1.0.69\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"thiserror-impl\"\nversion = \"2.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"thread_local\"\nversion = \"1.1.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185\"\ndependencies = [\n \"cfg-if\",\n]\n\n[[package]]\nname = \"time\"\nversion = \"0.3.44\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d\"\ndependencies = [\n \"deranged\",\n \"itoa\",\n \"num-conv\",\n \"powerfmt\",\n \"serde\",\n \"time-core\",\n \"time-macros\",\n]\n\n[[package]]\nname = \"time-core\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b\"\n\n[[package]]\nname = \"time-macros\"\nversion = \"0.2.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3\"\ndependencies = [\n \"num-conv\",\n \"time-core\",\n]\n\n[[package]]\nname = \"tinystr\"\nversion = \"0.8.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b\"\ndependencies = [\n \"displaydoc\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"tinyvec\"\nversion = \"1.10.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa\"\ndependencies = [\n \"tinyvec_macros\",\n]\n\n[[package]]\nname = \"tinyvec_macros\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20\"\n\n[[package]]\nname = \"todolist\"\nversion = \"0.1.0\"\ndependencies = [\n \"async-trait\",\n \"axum\",\n \"chrono\",\n \"eyre\",\n \"include_dir\",\n \"insta\",\n \"loco-rs\",\n \"migration\",\n \"rstest\",\n \"sea-orm\",\n \"serde\",\n \"serde_json\",\n \"serial_test\",\n \"tokio\",\n \"tracing\",\n \"tracing-subscriber\",\n \"uuid\",\n \"validator\",\n]\n\n[[package]]\nname = \"tokio\"\nversion = \"1.47.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038\"\ndependencies = [\n \"backtrace\",\n \"bytes\",\n \"io-uring\",\n \"libc\",\n \"mio\",\n \"pin-project-lite\",\n \"signal-hook-registry\",\n \"slab\",\n \"socket2 0.6.0\",\n \"tokio-macros\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"tokio-cron-scheduler\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f2594dd7c2abbbafbb1c78d167fd10860dc7bd75f814cb051a1e0d3e796b9702\"\ndependencies = [\n \"chrono\",\n \"cron\",\n \"num-derive\",\n \"num-traits\",\n \"tokio\",\n \"tracing\",\n \"uuid\",\n]\n\n[[package]]\nname = \"tokio-macros\"\nversion = \"2.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"tokio-rustls\"\nversion = \"0.26.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61\"\ndependencies = [\n \"rustls\",\n \"tokio\",\n]\n\n[[package]]\nname = \"tokio-stream\"\nversion = \"0.1.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047\"\ndependencies = [\n \"futures-core\",\n \"pin-project-lite\",\n \"tokio\",\n]\n\n[[package]]\nname = \"tokio-util\"\nversion = \"0.7.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"futures-sink\",\n \"pin-project-lite\",\n \"tokio\",\n]\n\n[[package]]\nname = \"toml\"\nversion = \"0.8.23\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362\"\ndependencies = [\n \"serde\",\n \"serde_spanned\",\n \"toml_datetime 0.6.11\",\n \"toml_edit 0.22.27\",\n]\n\n[[package]]\nname = \"toml_datetime\"\nversion = \"0.6.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"toml_datetime\"\nversion = \"0.7.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1\"\ndependencies = [\n \"serde_core\",\n]\n\n[[package]]\nname = \"toml_edit\"\nversion = \"0.22.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a\"\ndependencies = [\n \"indexmap\",\n \"serde\",\n \"serde_spanned\",\n \"toml_datetime 0.6.11\",\n \"toml_write\",\n \"winnow\",\n]\n\n[[package]]\nname = \"toml_edit\"\nversion = \"0.23.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b\"\ndependencies = [\n \"indexmap\",\n \"toml_datetime 0.7.2\",\n \"toml_parser\",\n \"winnow\",\n]\n\n[[package]]\nname = \"toml_parser\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627\"\ndependencies = [\n \"winnow\",\n]\n\n[[package]]\nname = \"toml_write\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801\"\n\n[[package]]\nname = \"tower\"\nversion = \"0.4.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c\"\ndependencies = [\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"tower\"\nversion = \"0.5.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9\"\ndependencies = [\n \"futures-core\",\n \"futures-util\",\n \"pin-project-lite\",\n \"sync_wrapper\",\n \"tokio\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"tower-http\"\nversion = \"0.6.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2\"\ndependencies = [\n \"async-compression\",\n \"bitflags 2.9.4\",\n \"bytes\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"http-range-header\",\n \"httpdate\",\n \"iri-string\",\n \"mime\",\n \"mime_guess\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"tokio\",\n \"tokio-util\",\n \"tower 0.5.2\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"tower-layer\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e\"\n\n[[package]]\nname = \"tower-service\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3\"\n\n[[package]]\nname = \"tracing\"\nversion = \"0.1.41\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0\"\ndependencies = [\n \"log\",\n \"pin-project-lite\",\n \"tracing-attributes\",\n \"tracing-core\",\n]\n\n[[package]]\nname = \"tracing-appender\"\nversion = \"0.2.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf\"\ndependencies = [\n \"crossbeam-channel\",\n \"thiserror 1.0.69\",\n \"time\",\n \"tracing-subscriber\",\n]\n\n[[package]]\nname = \"tracing-attributes\"\nversion = \"0.1.30\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"tracing-core\"\nversion = \"0.1.34\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678\"\ndependencies = [\n \"once_cell\",\n \"valuable\",\n]\n\n[[package]]\nname = \"tracing-log\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3\"\ndependencies = [\n \"log\",\n \"once_cell\",\n \"tracing-core\",\n]\n\n[[package]]\nname = \"tracing-serde\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1\"\ndependencies = [\n \"serde\",\n \"tracing-core\",\n]\n\n[[package]]\nname = \"tracing-subscriber\"\nversion = \"0.3.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5\"\ndependencies = [\n \"matchers\",\n \"nu-ansi-term\",\n \"once_cell\",\n \"regex-automata\",\n \"serde\",\n \"serde_json\",\n \"sharded-slab\",\n \"smallvec\",\n \"thread_local\",\n \"tracing\",\n \"tracing-core\",\n \"tracing-log\",\n \"tracing-serde\",\n]\n\n[[package]]\nname = \"tree-fs\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5c6115680fa5fdb99b4ff19c9c3217e75116d2bb0eae82458c4e1818be6a10c7\"\ndependencies = [\n \"rand 0.9.2\",\n \"serde\",\n]\n\n[[package]]\nname = \"try-lock\"\nversion = \"0.2.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b\"\n\n[[package]]\nname = \"typenum\"\nversion = \"1.19.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb\"\n\n[[package]]\nname = \"ucd-trie\"\nversion = \"0.1.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971\"\n\n[[package]]\nname = \"ulid\"\nversion = \"1.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"470dbf6591da1b39d43c14523b2b469c86879a53e8b758c8e090a470fe7b1fbe\"\ndependencies = [\n \"rand 0.9.2\",\n \"web-time\",\n]\n\n[[package]]\nname = \"unic-char-property\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221\"\ndependencies = [\n \"unic-char-range\",\n]\n\n[[package]]\nname = \"unic-char-range\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc\"\n\n[[package]]\nname = \"unic-common\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc\"\n\n[[package]]\nname = \"unic-segment\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23\"\ndependencies = [\n \"unic-ucd-segment\",\n]\n\n[[package]]\nname = \"unic-ucd-segment\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700\"\ndependencies = [\n \"unic-char-property\",\n \"unic-char-range\",\n \"unic-ucd-version\",\n]\n\n[[package]]\nname = \"unic-ucd-version\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4\"\ndependencies = [\n \"unic-common\",\n]\n\n[[package]]\nname = \"unicase\"\nversion = \"2.8.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539\"\n\n[[package]]\nname = \"unicode-bidi\"\nversion = \"0.3.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5\"\n\n[[package]]\nname = \"unicode-ident\"\nversion = \"1.0.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d\"\n\n[[package]]\nname = \"unicode-normalization\"\nversion = \"0.1.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956\"\ndependencies = [\n \"tinyvec\",\n]\n\n[[package]]\nname = \"unicode-properties\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0\"\n\n[[package]]\nname = \"unicode-width\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254\"\n\n[[package]]\nname = \"unicode-xid\"\nversion = \"0.2.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853\"\n\n[[package]]\nname = \"unsafe-libyaml\"\nversion = \"0.2.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861\"\n\n[[package]]\nname = \"untrusted\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1\"\n\n[[package]]\nname = \"url\"\nversion = \"2.5.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b\"\ndependencies = [\n \"form_urlencoded\",\n \"idna\",\n \"percent-encoding\",\n \"serde\",\n]\n\n[[package]]\nname = \"utf-8\"\nversion = \"0.7.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9\"\n\n[[package]]\nname = \"utf8-width\"\nversion = \"0.1.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3\"\n\n[[package]]\nname = \"utf8_iter\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be\"\n\n[[package]]\nname = \"utf8parse\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821\"\n\n[[package]]\nname = \"uuid\"\nversion = \"1.18.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2\"\ndependencies = [\n \"getrandom 0.3.3\",\n \"js-sys\",\n \"rand 0.9.2\",\n \"serde\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"validator\"\nversion = \"0.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"43fb22e1a008ece370ce08a3e9e4447a910e92621bb49b85d6e48a45397e7cfa\"\ndependencies = [\n \"idna\",\n \"once_cell\",\n \"regex\",\n \"serde\",\n \"serde_derive\",\n \"serde_json\",\n \"url\",\n \"validator_derive\",\n]\n\n[[package]]\nname = \"validator_derive\"\nversion = \"0.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b7df16e474ef958526d1205f6dda359fdfab79d9aa6d54bafcb92dcd07673dca\"\ndependencies = [\n \"darling\",\n \"once_cell\",\n \"proc-macro-error2\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"valuable\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65\"\n\n[[package]]\nname = \"vcpkg\"\nversion = \"0.2.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426\"\n\n[[package]]\nname = \"version_check\"\nversion = \"0.9.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a\"\n\n[[package]]\nname = \"walkdir\"\nversion = \"2.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b\"\ndependencies = [\n \"same-file\",\n \"winapi-util\",\n]\n\n[[package]]\nname = \"want\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e\"\ndependencies = [\n \"try-lock\",\n]\n\n[[package]]\nname = \"wasi\"\nversion = \"0.11.1+wasi-snapshot-preview1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b\"\n\n[[package]]\nname = \"wasi\"\nversion = \"0.14.7+wasi-0.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c\"\ndependencies = [\n \"wasip2\",\n]\n\n[[package]]\nname = \"wasip2\"\nversion = \"1.0.1+wasi-0.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7\"\ndependencies = [\n \"wit-bindgen\",\n]\n\n[[package]]\nname = \"wasite\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b\"\n\n[[package]]\nname = \"wasm-bindgen\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d\"\ndependencies = [\n \"cfg-if\",\n \"once_cell\",\n \"rustversion\",\n \"wasm-bindgen-macro\",\n \"wasm-bindgen-shared\",\n]\n\n[[package]]\nname = \"wasm-bindgen-backend\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19\"\ndependencies = [\n \"bumpalo\",\n \"log\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"wasm-bindgen-shared\",\n]\n\n[[package]]\nname = \"wasm-bindgen-futures\"\nversion = \"0.4.54\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c\"\ndependencies = [\n \"cfg-if\",\n \"js-sys\",\n \"once_cell\",\n \"wasm-bindgen\",\n \"web-sys\",\n]\n\n[[package]]\nname = \"wasm-bindgen-macro\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119\"\ndependencies = [\n \"quote\",\n \"wasm-bindgen-macro-support\",\n]\n\n[[package]]\nname = \"wasm-bindgen-macro-support\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"wasm-bindgen-backend\",\n \"wasm-bindgen-shared\",\n]\n\n[[package]]\nname = \"wasm-bindgen-shared\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1\"\ndependencies = [\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"wasm-streams\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65\"\ndependencies = [\n \"futures-util\",\n \"js-sys\",\n \"wasm-bindgen\",\n \"wasm-bindgen-futures\",\n \"web-sys\",\n]\n\n[[package]]\nname = \"web-sys\"\nversion = \"0.3.81\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120\"\ndependencies = [\n \"js-sys\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"web-time\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb\"\ndependencies = [\n \"js-sys\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"webpki-roots\"\nversion = \"0.26.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9\"\ndependencies = [\n \"webpki-roots 1.0.2\",\n]\n\n[[package]]\nname = \"webpki-roots\"\nversion = \"1.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2\"\ndependencies = [\n \"rustls-pki-types\",\n]\n\n[[package]]\nname = \"whoami\"\nversion = \"1.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d\"\ndependencies = [\n \"libredox\",\n \"wasite\",\n]\n\n[[package]]\nname = \"winapi-util\"\nversion = \"0.1.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22\"\ndependencies = [\n \"windows-sys 0.61.2\",\n]\n\n[[package]]\nname = \"windows-core\"\nversion = \"0.62.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb\"\ndependencies = [\n \"windows-implement\",\n \"windows-interface\",\n \"windows-link 0.2.1\",\n \"windows-result\",\n \"windows-strings\",\n]\n\n[[package]]\nname = \"windows-implement\"\nversion = \"0.60.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"windows-interface\"\nversion = \"0.59.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"windows-link\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a\"\n\n[[package]]\nname = \"windows-link\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5\"\n\n[[package]]\nname = \"windows-result\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5\"\ndependencies = [\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"windows-strings\"\nversion = \"0.5.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091\"\ndependencies = [\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.48.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9\"\ndependencies = [\n \"windows-targets 0.48.5\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.52.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d\"\ndependencies = [\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.59.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b\"\ndependencies = [\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.60.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb\"\ndependencies = [\n \"windows-targets 0.53.5\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.61.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc\"\ndependencies = [\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c\"\ndependencies = [\n \"windows_aarch64_gnullvm 0.48.5\",\n \"windows_aarch64_msvc 0.48.5\",\n \"windows_i686_gnu 0.48.5\",\n \"windows_i686_msvc 0.48.5\",\n \"windows_x86_64_gnu 0.48.5\",\n \"windows_x86_64_gnullvm 0.48.5\",\n \"windows_x86_64_msvc 0.48.5\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973\"\ndependencies = [\n \"windows_aarch64_gnullvm 0.52.6\",\n \"windows_aarch64_msvc 0.52.6\",\n \"windows_i686_gnu 0.52.6\",\n \"windows_i686_gnullvm 0.52.6\",\n \"windows_i686_msvc 0.52.6\",\n \"windows_x86_64_gnu 0.52.6\",\n \"windows_x86_64_gnullvm 0.52.6\",\n \"windows_x86_64_msvc 0.52.6\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.53.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3\"\ndependencies = [\n \"windows-link 0.2.1\",\n \"windows_aarch64_gnullvm 0.53.1\",\n \"windows_aarch64_msvc 0.53.1\",\n \"windows_i686_gnu 0.53.1\",\n \"windows_i686_gnullvm 0.53.1\",\n \"windows_i686_msvc 0.53.1\",\n \"windows_x86_64_gnu 0.53.1\",\n \"windows_x86_64_gnullvm 0.53.1\",\n \"windows_x86_64_msvc 0.53.1\",\n]\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8\"\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3\"\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3\"\n\n[[package]]\nname = \"windows_i686_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66\"\n\n[[package]]\nname = \"windows_i686_gnullvm\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650\"\n\n[[package]]\nname = \"winnow\"\nversion = \"0.7.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"wit-bindgen\"\nversion = \"0.46.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59\"\n\n[[package]]\nname = \"writeable\"\nversion = \"0.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb\"\n\n[[package]]\nname = \"wyz\"\nversion = \"0.5.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed\"\ndependencies = [\n \"tap\",\n]\n\n[[package]]\nname = \"yansi\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049\"\n\n[[package]]\nname = \"yoke\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc\"\ndependencies = [\n \"serde\",\n \"stable_deref_trait\",\n \"yoke-derive\",\n \"zerofrom\",\n]\n\n[[package]]\nname = \"yoke-derive\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"synstructure\",\n]\n\n[[package]]\nname = \"zerocopy\"\nversion = \"0.8.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c\"\ndependencies = [\n \"zerocopy-derive\",\n]\n\n[[package]]\nname = \"zerocopy-derive\"\nversion = \"0.8.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"zerofrom\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5\"\ndependencies = [\n \"zerofrom-derive\",\n]\n\n[[package]]\nname = \"zerofrom-derive\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"synstructure\",\n]\n\n[[package]]\nname = \"zeroize\"\nversion = \"1.8.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0\"\n\n[[package]]\nname = \"zerotrie\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595\"\ndependencies = [\n \"displaydoc\",\n \"yoke\",\n \"zerofrom\",\n]\n\n[[package]]\nname = \"zerovec\"\nversion = \"0.11.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b\"\ndependencies = [\n \"yoke\",\n \"zerofrom\",\n \"zerovec-derive\",\n]\n\n[[package]]\nname = \"zerovec-derive\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"zstd\"\nversion = \"0.13.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a\"\ndependencies = [\n \"zstd-safe\",\n]\n\n[[package]]\nname = \"zstd-safe\"\nversion = \"7.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d\"\ndependencies = [\n \"zstd-sys\",\n]\n\n[[package]]\nname = \"zstd-sys\"\nversion = \"2.0.16+zstd.1.5.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748\"\ndependencies = [\n \"cc\",\n \"pkg-config\",\n]\n"
  },
  {
    "path": "examples/loco_example/Cargo.toml",
    "content": "[workspace]\n\n[package]\nedition      = \"2024\"\nname         = \"todolist\"\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n\nloco-rs   = { version = \"0.16\" }\nmigration = { path = \"migration\" }\n\nasync-trait        = \"0.1.74\"\naxum               = \"0.8\"\nchrono             = \"0.4\"\neyre               = \"0.6\"\ninclude_dir        = \"0.7\"\nserde              = { version = \"1\", features = [\"derive\"] }\nserde_json         = \"1\"\ntokio              = { version = \"1.33.0\", default-features = false }\ntracing            = \"0.1.40\"\ntracing-subscriber = { version = \"0.3.17\", features = [\"env-filter\", \"json\"] }\nuuid               = { version = \"1.6.0\", features = [\"v4\"] }\nvalidator          = { version = \"0.20\" }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"sqlx-sqlite\",\n    \"sqlx-postgres\",\n    \"runtime-tokio-rustls\",\n    \"macros\",\n]\nversion = \"~2.0.0-rc.37\" # sea-orm version\n\n[[bin]]\nname              = \"todolist-cli\"\npath              = \"src/bin/main.rs\"\nrequired-features = []\n\n[dev-dependencies]\ninsta       = { version = \"1.34.0\", features = [\"redactions\", \"yaml\", \"filters\"] }\nloco-rs     = { version = \"0.16\", features = [\"testing\"] }\nrstest      = \"0.18.2\"\nserial_test = \"2.0.0\"\n\n[patch.crates-io]\nloco-rs = { git = \"https://github.com/SeaQL/loco\", branch = \"master\" }\n"
  },
  {
    "path": "examples/loco_example/README.md",
    "content": "![screenshot](Screenshot.png)\n\n> Adapted from https://github.com/loco-rs/todo-list\n\n# Loco with SeaORM example todo list\n\nBuild your own todo list website using Loco. Follow the step-by-step guide [here](<(https://loco.rs/blog/frontend-website/)>) to create it effortlessly.\n\n## Build Client\n\nNavigate to the `frontend` directory and build the client:\n\n```sh\n$ cd frontend && yarn install && yarn build\n\nvite v5.0.8 building for production...\n✓ 120 modules transformed.\ndist/index.html                   0.46 kB │ gzip:  0.30 kB\ndist/assets/index-AbTMZIjW.css    1.26 kB │ gzip:  0.65 kB\ndist/assets/index-MJFpQvzE.js   235.64 kB │ gzip: 75.58 kB\n✓ built in 2.01s\n```\n\n## Run Locally\n\nYou need:\n\n* A local postgres instance\n\nCheck out your development [configuration](config/development.yaml).\n\n> To configure a database , please run a local postgres database with <code>loco:loco</code> and a db named <code>[app name]_development.</code>: \n<code>docker run -d -p 5432:5432 -e POSTGRES_USER=loco -e POSTGRES_DB=[app name]_development -e POSTGRES_PASSWORD=\"loco\" postgres:15.3-alpine</code>\n\nExecute the following command to run your todo list website locally, serving static assets from `frontend/dist`:\n\n```sh\n$ cargo loco start\n\n    Finished dev [unoptimized + debuginfo] target(s) in 0.53s\n     Running `target/debug/todolist-cli start`\n2024-02-01T08:49:41.070430Z  INFO loco_rs::db: auto migrating\n2024-02-01T08:49:41.073698Z  INFO sea_orm_migration::migrator: Applying all pending migrations\n2024-02-01T08:49:41.078191Z  INFO sea_orm_migration::migrator: No pending migrations\n2024-02-01T08:49:41.100557Z  INFO loco_rs::controller::app_routes: [GET] /api/_ping\n2024-02-01T08:49:41.100617Z  INFO loco_rs::controller::app_routes: [GET] /api/_health\n2024-02-01T08:49:41.100667Z  INFO loco_rs::controller::app_routes: [GET] /api/notes\n2024-02-01T08:49:41.100702Z  INFO loco_rs::controller::app_routes: [POST] /api/notes\n2024-02-01T08:49:41.100738Z  INFO loco_rs::controller::app_routes: [GET] /api/notes/{id}\n2024-02-01T08:49:41.100791Z  INFO loco_rs::controller::app_routes: [DELETE] /api/notes/{id}\n2024-02-01T08:49:41.100817Z  INFO loco_rs::controller::app_routes: [POST] /api/notes/{id}\n2024-02-01T08:49:41.100934Z  INFO loco_rs::controller::app_routes: [Middleware] Adding limit payload data=\"5mb\"\n2024-02-01T08:49:41.101017Z  INFO loco_rs::controller::app_routes: [Middleware] Adding log trace id\n2024-02-01T08:49:41.101057Z  INFO loco_rs::controller::app_routes: [Middleware] Adding timeout layer\n2024-02-01T08:49:41.101192Z  INFO loco_rs::controller::app_routes: [Middleware] Adding cors\n2024-02-01T08:49:41.101241Z  INFO loco_rs::controller::app_routes: [Middleware] Adding static\n\n                      ▄     ▀\n                                 ▀  ▄\n                  ▄       ▀     ▄  ▄ ▄▀\n                                    ▄ ▀▄▄\n                        ▄     ▀    ▀  ▀▄▀█▄\n                                          ▀█▄\n▄▄▄▄▄▄▄  ▄▄▄▄▄▄▄▄▄   ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄ ▀▀█\n ██████  █████   ███ █████   ███ █████   ███ ▀█\n ██████  █████   ███ █████   ▀▀▀ █████   ███ ▄█▄\n ██████  █████   ███ █████       █████   ███ ████▄\n ██████  █████   ███ █████   ▄▄▄ █████   ███ █████\n ██████  █████   ███  ████   ███ █████   ███ ████▀\n   ▀▀▀██▄ ▀▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀▀▀  ▀▀▀▀▀▀▀▀▀▀ ██▀\n       ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\n                https://loco.rs\n\nenvironment: development\n   database: automigrate\n     logger: debug\ncompilation: debug\n      modes: server\n\nlistening on port 3000\n```\n\n## Development\n\nTo develop the UI, run the following commands:\n\n```sh\n$ cd frontend && yarn install && yarn dev\n```\n\nTo run the server:\n\n```sh\n$ cargo loco start\n```\n"
  },
  {
    "path": "examples/loco_example/config/development.yaml",
    "content": "# Loco configuration file documentation\n\n# Application logging configuration\nlogger:\n  # Enable or disable logging.\n  enable: true\n  # Log level, options: trace, debug, info, warn or error.\n  level: debug\n  # Define the logging format. options: compact, pretty or Json\n  format: compact\n  # By default the logger has filtering only logs that came from your code or logs that came from `loco` framework. to see all third party libraries\n  # Uncomment the line below to override to see all third party libraries you can enable this config and override the logger filters.\n  # override_filter: trace\n\n# Web server configuration\nserver:\n  # Port on which the server will listen. the server binding is 0.0.0.0:{PORT}\n  port: 3000\n  # The UI hostname or IP address that mailers will point to.\n  host: http://localhost\n  # Out of the box middleware configuration. to disable middleware you can changed the `enable` field to `false` of comment the middleware block\n  middlewares:\n    # Allows to limit the payload size request. payload that bigger than this file will blocked the request.\n    limit_payload:\n      # Enable/Disable the middleware.\n      enable: true\n      # the limit size. can be b,kb,kib,mb,mib,gb,gib\n      body_limit: 5mb\n    # Generating a unique request ID and enhancing logging with additional information such as the start and completion of request processing, latency, status code, and other request details.\n    logger:\n      # Enable/Disable the middleware.\n      enable: true\n    # when your code is panicked, the request still returns 500 status code.\n    catch_panic:\n      # Enable/Disable the middleware.\n      enable: true\n    # Timeout for incoming requests middleware. requests that take more time from the configuration will cute and 408 status code will returned.\n    timeout_request:\n      # Enable/Disable the middleware.\n      enable: true\n      # Duration time in milliseconds.\n      timeout: 5000\n    cors:\n      enable: true\n    static:\n      enable: true\n      must_exist: true\n      folder:\n        uri: \"/\"\n        path: \"frontend/dist\"\n      fallback: \"frontend/dist/index.html\"\n\n# Database Configuration\ndatabase:\n  # Database connection URI\n  uri: postgres://loco:loco@localhost:5432/loco_app\n  # When enabled, the sql query will be logged.\n  enable_logging: false\n  # Set the timeout duration when acquiring a connection.\n  connect_timeout: 500\n  # Set the idle duration before closing a connection.\n  idle_timeout: 500\n  # Minimum number of connections for a pool.\n  min_connections: 1\n  # Maximum number of connections for a pool.\n  max_connections: 1\n  # Run migration up when application loaded\n  auto_migrate: true\n  # Truncate database when application loaded. This is a dangerous operation, make sure that you using this flag only on dev environments or test mode\n  dangerously_truncate: false\n  # Recreating schema when application loaded.  This is a dangerous operation, make sure that you using this flag only on dev environments or test mode\n  dangerously_recreate: false\n"
  },
  {
    "path": "examples/loco_example/dockerfile",
    "content": "FROM rust:1.74-slim as builder\n\nWORKDIR /usr/src/\n\nCOPY . .\n\nRUN cargo build --release\n\nFROM debian:bookworm-slim\n\nWORKDIR /usr/app\n\nCOPY --from=builder /usr/src/frontend/dist /usr/app/frontend/dist\nCOPY --from=builder /usr/src/frontend/dist/index.html /usr/app/frontend/dist/index.html\nCOPY --from=builder /usr/src/config /usr/app/config\nCOPY --from=builder /usr/src/target/release/todolist-cli /usr/app/todolist-cli\n\nENTRYPOINT [\"/usr/app/todolist-cli\"]"
  },
  {
    "path": "examples/loco_example/frontend/.eslintrc.cjs",
    "content": "module.exports = {\n  root: true,\n  env: { browser: true, es2020: true },\n  extends: [\n    'eslint:recommended',\n    'plugin:react/recommended',\n    'plugin:react/jsx-runtime',\n    'plugin:react-hooks/recommended',\n  ],\n  ignorePatterns: ['dist', '.eslintrc.cjs'],\n  parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },\n  settings: { react: { version: '18.2' } },\n  plugins: ['react-refresh'],\n  rules: {\n    'react-refresh/only-export-components': [\n      'warn',\n      { allowConstantExport: true },\n    ],\n  },\n}\n"
  },
  {
    "path": "examples/loco_example/frontend/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\ndist\ndist-ssr\n*.local\n.yarn\n.yarnrc.yml\n.pnp.*\n\n# Editor directories and files\n.vscode/*\n!.vscode/extensions.json\n.idea\n.DS_Store\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n"
  },
  {
    "path": "examples/loco_example/frontend/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <link rel=\"icon\" type=\"image/svg+xml\" href=\"/vite.svg\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Vite + React</title>\n  </head>\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"/src/main.jsx\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/loco_example/frontend/package.json",
    "content": "{\n  \"name\": \"frontend\",\n  \"private\": true,\n  \"version\": \"0.0.0\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"lint\": \"eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0\",\n    \"preview\": \"vite preview\"\n  },\n  \"dependencies\": {\n    \"axios\": \"^1.6.2\",\n    \"react\": \"18.2.0\",\n    \"react-dom\": \"18.2.0\",\n    \"react-query\": \"3.39.3\",\n    \"react-router-dom\": \"6.15.0\"\n  },\n  \"devDependencies\": {\n    \"@types/react\": \"18.2.43\",\n    \"@types/react-dom\": \"18.2.17\",\n    \"@vitejs/plugin-react\": \"4.2.1\",\n    \"eslint\": \"8.55.0\",\n    \"eslint-plugin-react\": \"7.33.2\",\n    \"eslint-plugin-react-hooks\": \"4.6.0\",\n    \"eslint-plugin-react-refresh\": \"0.4.5\",\n    \"vite\": \"5.0.8\"\n  }\n}\n"
  },
  {
    "path": "examples/loco_example/frontend/src/App.css",
    "content": "#root {\n  max-width: 1280px;\n  margin: 0 auto;\n  text-align: center;\n}\n\n.logo {\n  height: 10em;\n  padding: 1.5em;\n  will-change: filter;\n  transition: filter 300ms;\n}\n.logo:hover {\n  filter: drop-shadow(0 0 2em #ff1111aa);\n}\n\n.todo-list {\n  text-align: left;\n}\n\n.todo-list .todo{\n  margin-top: 10px;\n}\n\n.todo-add {\n  margin-top: 20px;\n  text-align: left;\n  \n}\n\n.todo-add input{\n  width: 70%;\n  height: 30px;\n}\n.todo-add button{\n  float: right;\n}"
  },
  {
    "path": "examples/loco_example/frontend/src/App.jsx",
    "content": "import {\n  useQuery,\n  useMutation,\n  useQueryClient,\n} from 'react-query'\nimport axios from 'axios';\nimport './App.css'\nimport { Routes, Route, Outlet, Link } from \"react-router-dom\";\n\nimport { useState } from \"react\";\n\nexport default function App() {\n\n  return (\n    <div>\n      <h1>Loco Todo List</h1>\n      <Routes >\n        <Route path=\"/\" element={<Layout />}>\n          <Route index element={<TodoList />} />\n          <Route path=\"*\" element={<NoMatch />} />\n        </Route>\n      </Routes>\n    </div>\n  )\n}\n\n\nfunction Layout() {\n  return (\n    <div>\n      <div>\n        <a href=\"https://loco.rs\" target=\"_blank\" rel=\"noreferrer\">\n          <img src=\"https://raw.githubusercontent.com/loco-rs/todo-list-example/4b8ade3ddfb5a2e076e5188cdc8f6cd404f3fdd1/frontend/src/assets/loco.svg\" className=\"logo\" alt=\"Loco logo\" />\n        </a>\n      </div>\n      <hr />\n      <Outlet />\n    </div>\n  );\n}\n\nfunction TodoList() {\n\n  const queryClient = useQueryClient();\n\n  const fetchTodos = async () => {\n    const { data } = await axios.get(`api/notes`)\n    return data;\n  }\n\n  const { isLoading, isError, data = [] } = useQuery([\"todos\"], fetchTodos); // a hook provided by react-query, it takes a key(name) and function that returns a promise\n\n\n  const remove = async (id) => {\n    try {\n      const response = await axios.delete(`api/notes/${id}`);\n      return response.data;\n    } catch (error) {\n      console.error('Error posting todo:', error);\n      throw error;\n    }\n  };\n\n\n  const mutation = useMutation(remove, {\n    onSuccess: () => {\n      queryClient.invalidateQueries([\"todos\"]);\n    },\n  });\n\n  console.log(data)\n  if (isLoading)\n    return (\n      <div className=\"App\">\n        <p>isLoading...</p>\n      </div>\n    );\n\n  if (isError)\n    return (\n      <div className=\"App\">\n        <p>Could not get todo list from the server</p>\n      </div>\n    );\n\n\n  return (\n    <div>\n      <AddTodo />\n      <div className=\"todo-list\">\n        {data.map((todo) => (\n          <div key={todo.id} className=\"todo\" >\n            <div>\n              <div> <button onClick={() => {\n                mutation.mutate(todo.id);\n              }}>x</button> {todo.title}</div>\n            </div>\n\n          </div>\n        ))}\n      </div>\n    </div>\n  );\n}\n\n\nfunction AddTodo() {\n  const [todo, setTodo] = useState(\"\");\n  const queryClient = useQueryClient();\n\n  const add = async (newTodo) => {\n    try {\n      const response = await axios.post(`api/notes`, {\n        title: newTodo,\n        content: newTodo,\n      });\n      return response.data;\n    } catch (error) {\n      console.error('Error posting todo:', error);\n      throw error;\n    }\n  };\n\n\n  const mutation = useMutation(add, {\n    onSuccess: () => {\n      setTodo(\"\")\n      queryClient.invalidateQueries([\"todos\"]);\n    },\n  });\n\n  return (\n    <div className='todo-add'>\n      <input\n        value={todo}\n        onChange={(event) => {\n          setTodo(event.target.value);\n        }}\n        type=\"text\"\n      />\n      <button\n        onClick={() => {\n          if (todo !== \"\") {\n            mutation.mutate(todo);\n          }\n        }}\n      >\n        Add\n      </button>\n    </div>\n  );\n}\n\nfunction NoMatch() {\n  return (\n    <div>\n      <h2>Sorry, this page not found</h2>\n      <p>\n        <Link to=\"/\">Go to the todo list page</Link>\n      </p>\n    </div>\n  );\n}\n"
  },
  {
    "path": "examples/loco_example/frontend/src/index.css",
    "content": ":root {\n  font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;\n  line-height: 1.5;\n  font-weight: 400;\n\n  color-scheme: light dark;\n  color: rgba(255, 255, 255, 0.87);\n  background-color: #242424;\n\n  font-synthesis: none;\n  text-rendering: optimizeLegibility;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\na {\n  font-weight: 500;\n  color: #646cff;\n  text-decoration: inherit;\n}\na:hover {\n  color: #535bf2;\n}\n\nbody {\n  margin: 0;\n  display: flex;\n  place-items: center;\n  min-width: 320px;\n  min-height: 100vh;\n}\n\nh1 {\n  font-size: 3.2em;\n  line-height: 1.1;\n}\n\nbutton {\n  border-radius: 8px;\n  border: 1px solid transparent;\n  padding: 0.6em 1.2em;\n  font-size: 1em;\n  font-weight: 500;\n  font-family: inherit;\n  background-color: #1a1a1a;\n  cursor: pointer;\n  transition: border-color 0.25s;\n}\nbutton:hover {\n  border-color: #646cff;\n}\nbutton:focus,\nbutton:focus-visible {\n  outline: 4px auto -webkit-focus-ring-color;\n}\n\n@media (prefers-color-scheme: light) {\n  :root {\n    color: #213547;\n    background-color: #ffffff;\n  }\n  a:hover {\n    color: #747bff;\n  }\n  button {\n    background-color: #f9f9f9;\n  }\n}\n"
  },
  {
    "path": "examples/loco_example/frontend/src/main.jsx",
    "content": "import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport { BrowserRouter } from \"react-router-dom\";\nimport App from './App.jsx'\nimport './index.css'\nimport {\n  QueryClient,\n  QueryClientProvider,\n} from 'react-query'\n\nconst queryClient = new QueryClient();\n\nReactDOM.createRoot(document.getElementById('root')).render(\n  <React.StrictMode>\n    <QueryClientProvider client={queryClient}>\n    <BrowserRouter>\n      <App />\n      </BrowserRouter>\n      </QueryClientProvider>\n  </React.StrictMode>\n)\n"
  },
  {
    "path": "examples/loco_example/frontend/vite.config.js",
    "content": "import { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\n\n// https://vitejs.dev/config/\nexport default defineConfig({\n  plugins: [react()],\n  server: {\n    proxy: {\n      \"/api\": {\n        target: \"http://127.0.0.1:3000\",\n        changeOrigin: true,\n        secure: false,\n      },\n    },\n  },\n})\n"
  },
  {
    "path": "examples/loco_example/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nloco-rs = { version = \"0.16\" }\ntokio   = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.\n    # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.\n    # e.g.\n    \"runtime-tokio-rustls\", # `ASYNC_RUNTIME` feature\n]\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/loco_example/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Generate a new migration file\n    ```sh\n    cargo run -- migrate generate MIGRATION_NAME\n    ```\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/loco_example/migration/src/lib.rs",
    "content": "#![allow(elided_lifetimes_in_paths)]\n#![allow(clippy::wildcard_imports)]\npub use sea_orm_migration::prelude::*;\n\nmod m20231103_114510_notes;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![Box::new(m20231103_114510_notes::Migration)]\n    }\n}\n"
  },
  {
    "path": "examples/loco_example/migration/src/m20231103_114510_notes.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                table_auto(\"notes\")\n                    .col(pk_auto(\"id\"))\n                    .col(string_null(\"title\"))\n                    .col(string_null(\"content\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"notes\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/loco_example/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/loco_example/src/app.rs",
    "content": "use std::path::Path;\n\nuse async_trait::async_trait;\nuse loco_rs::{\n    Result,\n    app::{AppContext, Hooks},\n    bgworker::Queue,\n    boot::{BootResult, StartMode, create_app},\n    config::Config,\n    controller::AppRoutes,\n    db::{self, truncate_table},\n    environment::Environment,\n    task::Tasks,\n};\nuse migration::Migrator;\n\nuse crate::{controllers, models::_entities::notes};\n\npub struct App;\n#[async_trait]\nimpl Hooks for App {\n    fn app_name() -> &'static str {\n        env!(\"CARGO_CRATE_NAME\")\n    }\n\n    async fn boot(\n        mode: StartMode,\n        environment: &Environment,\n        config: Config,\n    ) -> Result<BootResult> {\n        create_app::<Self, Migrator>(mode, environment, config).await\n    }\n\n    fn routes(_ctx: &AppContext) -> AppRoutes {\n        AppRoutes::with_default_routes()\n            .prefix(\"/api\")\n            .add_route(controllers::notes::routes())\n    }\n\n    async fn connect_workers(_ctx: &AppContext, _queue: &Queue) -> Result<()> {\n        Ok(())\n    }\n\n    fn register_tasks(_tasks: &mut Tasks) {}\n\n    async fn truncate(ctx: &AppContext) -> Result<()> {\n        let db = &ctx.db;\n        truncate_table(db, notes::Entity).await?;\n        Ok(())\n    }\n\n    async fn seed(ctx: &AppContext, base: &Path) -> Result<()> {\n        let db = &ctx.db;\n        db::seed::<notes::ActiveModel>(db, &base.join(\"notes.yaml\").display().to_string()).await?;\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/loco_example/src/bin/main.rs",
    "content": "use loco_rs::cli;\nuse migration::Migrator;\nuse todolist::app::App;\n\n#[tokio::main]\nasync fn main() -> eyre::Result<()> {\n    cli::main::<App, Migrator>().await?;\n    Ok(())\n}\n"
  },
  {
    "path": "examples/loco_example/src/controllers/mod.rs",
    "content": "pub mod notes;\n"
  },
  {
    "path": "examples/loco_example/src/controllers/notes.rs",
    "content": "#![allow(clippy::missing_errors_doc)]\n#![allow(clippy::unnecessary_struct_initialization)]\n#![allow(clippy::unused_async)]\nuse loco_rs::prelude::*;\nuse serde::{Deserialize, Serialize};\n\nuse crate::models::_entities::notes::{ActiveModel, Entity, Model};\n\n#[derive(Clone, Debug, Serialize, Deserialize)]\npub struct Params {\n    pub title: Option<String>,\n    pub content: Option<String>,\n}\n\nimpl Params {\n    fn update(&self, item: &mut ActiveModel) {\n        item.title = Set(self.title.clone());\n        item.content = Set(self.content.clone());\n    }\n}\n\nasync fn load_item(ctx: &AppContext, id: i32) -> Result<Model> {\n    let item = Entity::find_by_id(id).one(&ctx.db).await?;\n    item.ok_or_else(|| Error::NotFound)\n}\n\npub async fn list(State(ctx): State<AppContext>) -> Result<Response> {\n    format::json(Entity::find().all(&ctx.db).await?)\n}\n\npub async fn add(State(ctx): State<AppContext>, Json(params): Json<Params>) -> Result<Response> {\n    let mut item = ActiveModel {\n        ..Default::default()\n    };\n    params.update(&mut item);\n    let item = item.insert(&ctx.db).await?;\n    format::json(item)\n}\n\npub async fn update(\n    Path(id): Path<i32>,\n    State(ctx): State<AppContext>,\n    Json(params): Json<Params>,\n) -> Result<Response> {\n    let item = load_item(&ctx, id).await?;\n    let mut item = item.into_active_model();\n    params.update(&mut item);\n    let item = item.update(&ctx.db).await?;\n    format::json(item)\n}\n\npub async fn remove(Path(id): Path<i32>, State(ctx): State<AppContext>) -> Result<Response> {\n    load_item(&ctx, id).await?.delete(&ctx.db).await?;\n    format::empty()\n}\n\npub async fn get_one(Path(id): Path<i32>, State(ctx): State<AppContext>) -> Result<Response> {\n    format::json(load_item(&ctx, id).await?)\n}\n\npub fn routes() -> Routes {\n    Routes::new()\n        .prefix(\"notes\")\n        .add(\"/\", get(list))\n        .add(\"/\", post(add))\n        .add(\"/{id}\", get(get_one))\n        .add(\"/{id}\", delete(remove))\n        .add(\"/{id}\", post(update))\n}\n"
  },
  {
    "path": "examples/loco_example/src/fixtures/notes.yaml",
    "content": "---\n- id: 1\n  title: Loco note 1\n  content: Loco note 1 content\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n- id: 2\n  title: Loco note 1\n  content: Loco note 1 content\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n"
  },
  {
    "path": "examples/loco_example/src/lib.rs",
    "content": "pub mod app;\npub mod controllers;\npub mod models;\n"
  },
  {
    "path": "examples/loco_example/src/models/_entities/mod.rs",
    "content": "//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.4\n\npub mod prelude;\n\npub mod notes;\n"
  },
  {
    "path": "examples/loco_example/src/models/_entities/notes.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.10\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"notes\")]\npub struct Model {\n    pub created_at: DateTime,\n    pub updated_at: DateTime,\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub title: Option<String>,\n    pub content: Option<String>,\n}\n"
  },
  {
    "path": "examples/loco_example/src/models/_entities/prelude.rs",
    "content": "//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.4\n\npub use super::notes::Entity as Notes;\n"
  },
  {
    "path": "examples/loco_example/src/models/mod.rs",
    "content": "pub mod _entities;\npub mod notes;\n"
  },
  {
    "path": "examples/loco_example/src/models/notes.rs",
    "content": "use sea_orm::entity::prelude::*;\n\nuse super::_entities::notes::ActiveModel;\n\nimpl ActiveModelBehavior for ActiveModel {\n    // extend activemodel below (keep comment for generators)\n}\n"
  },
  {
    "path": "examples/loco_example/tests/mod.rs",
    "content": "mod models;\nmod requests;\nmod tasks;\n"
  },
  {
    "path": "examples/loco_example/tests/models/mod.rs",
    "content": "\n"
  },
  {
    "path": "examples/loco_example/tests/requests/mod.rs",
    "content": "mod notes;\n"
  },
  {
    "path": "examples/loco_example/tests/requests/notes.rs",
    "content": "use insta::{assert_debug_snapshot, with_settings};\nuse loco_rs::testing;\nuse migration::Migrator;\nuse sea_orm::entity::prelude::*;\nuse serial_test::serial;\nuse todolist::{app::App, models::_entities::notes::Entity};\n\n// TODO: see how to dedup / extract this to app-local test utils\n// not to framework, because that would require a runtime dep on insta\nmacro_rules! configure_insta {\n    ($($expr:expr),*) => {\n        let mut settings = insta::Settings::clone_current();\n        settings.set_prepend_module_to_snapshot(false);\n        settings.set_snapshot_suffix(\"notes_request\");\n        let _guard = settings.bind_to_scope();\n    };\n}\n\n// Disabled integration test for GitHub CI\n/*\n#[tokio::test]\n#[serial]\nasync fn can_get_notes() {\n    configure_insta!();\n\n    testing::request::<App, Migrator, _, _>(|request, ctx| async move {\n        testing::seed::<App>(&ctx.db).await.unwrap();\n\n        let notes = request.get(\"/api/notes\").await;\n\n        with_settings!({\n            filters => {\n                 let mut combined_filters = testing::CLEANUP_DATE.to_vec();\n                    combined_filters.extend(vec![(r#\"\\\"id\\\\\":\\d+\"#, r#\"\"id\\\":ID\"#)]);\n                    combined_filters\n            }\n        }, {\n            assert_debug_snapshot!(\n            (notes.status_code(), notes.text())\n        );\n        });\n    })\n    .await;\n}\n\n#[tokio::test]\n#[serial]\nasync fn can_add_note() {\n    configure_insta!();\n\n    testing::request::<App, Migrator, _, _>(|request, _ctx| async move {\n        let payload = serde_json::json!({\n            \"title\": \"loco\",\n            \"content\": \"loco note test\",\n        });\n\n        let add_note_request = request.post(\"/api/notes\").json(&payload).await;\n\n        with_settings!({\n            filters => {\n                 let mut combined_filters = testing::CLEANUP_DATE.to_vec();\n                    combined_filters.extend(vec![(r#\"\\\"id\\\\\":\\d+\"#, r#\"\"id\\\":ID\"#)]);\n                    combined_filters\n            }\n        }, {\n            assert_debug_snapshot!(\n            (add_note_request.status_code(), add_note_request.text())\n        );\n        });\n    })\n    .await;\n}\n\n#[tokio::test]\n#[serial]\nasync fn can_get_note() {\n    configure_insta!();\n\n    testing::request::<App, Migrator, _, _>(|request, ctx| async move {\n        testing::seed::<App>(&ctx.db).await.unwrap();\n\n        let add_note_request = request.get(\"/api/notes/1\").await;\n\n        with_settings!({\n            filters => {\n                 let mut combined_filters = testing::CLEANUP_DATE.to_vec();\n                    combined_filters.extend(vec![(r#\"\\\"id\\\\\":\\d+\"#, r#\"\"id\\\":ID\"#)]);\n                    combined_filters\n            }\n        }, {\n            assert_debug_snapshot!(\n            (add_note_request.status_code(), add_note_request.text())\n        );\n        });\n    })\n    .await;\n}\n\n#[tokio::test]\n#[serial]\nasync fn can_delete_note() {\n    configure_insta!();\n\n    testing::request::<App, Migrator, _, _>(|request, ctx| async move {\n        testing::seed::<App>(&ctx.db).await.unwrap();\n\n        let count_before_delete = Entity::find().all(&ctx.db).await.unwrap().len();\n        let delete_note_request = request.delete(\"/api/notes/1\").await;\n\n        with_settings!({\n            filters => {\n                 let mut combined_filters = testing::CLEANUP_DATE.to_vec();\n                    combined_filters.extend(vec![(r#\"\\\"id\\\\\":\\d+\"#, r#\"\"id\\\":ID\"#)]);\n                    combined_filters\n            }\n        }, {\n            assert_debug_snapshot!(\n            (delete_note_request.status_code(), delete_note_request.text())\n        );\n        });\n\n        let count_after_delete = Entity::find().all(&ctx.db).await.unwrap().len();\n        assert_eq!(count_after_delete, count_before_delete - 1);\n    })\n    .await;\n}\n*/\n"
  },
  {
    "path": "examples/loco_example/tests/requests/snapshots/can_add_note@notes_request.snap",
    "content": "---\nsource: tests/requests/notes.rs\nexpression: \"(add_note_request.status_code(), add_note_request.text())\"\n---\n(\n    200,\n    \"{\\\"created_at\\\":\\\"DATE\\\",\\\"updated_at\\\":\\\"DATE\\\",\\\"id\\\":ID,\\\"title\\\":\\\"loco\\\",\\\"content\\\":\\\"loco note test\\\"}\",\n)\n"
  },
  {
    "path": "examples/loco_example/tests/requests/snapshots/can_delete_note@notes_request.snap",
    "content": "---\nsource: tests/requests/notes.rs\nexpression: \"(delete_note_request.status_code(), delete_note_request.text())\"\n---\n(\n    200,\n    \"\",\n)\n"
  },
  {
    "path": "examples/loco_example/tests/requests/snapshots/can_get_note@notes_request.snap",
    "content": "---\nsource: tests/requests/notes.rs\nexpression: \"(add_note_request.status_code(), add_note_request.text())\"\n---\n(\n    200,\n    \"{\\\"created_at\\\":\\\"DATE\\\",\\\"updated_at\\\":\\\"DATE\\\",\\\"id\\\":ID,\\\"title\\\":\\\"Loco note 1\\\",\\\"content\\\":\\\"Loco note 1 content\\\"}\",\n)\n"
  },
  {
    "path": "examples/loco_example/tests/requests/snapshots/can_get_notes@notes_request.snap",
    "content": "---\nsource: tests/requests/notes.rs\nexpression: \"(notes.status_code(), notes.text())\"\n---\n(\n    200,\n    \"[{\\\"created_at\\\":\\\"DATE\\\",\\\"updated_at\\\":\\\"DATE\\\",\\\"id\\\":ID,\\\"title\\\":\\\"Loco note 1\\\",\\\"content\\\":\\\"Loco note 1 content\\\"},{\\\"created_at\\\":\\\"DATE\\\",\\\"updated_at\\\":\\\"DATE\\\",\\\"id\\\":ID,\\\"title\\\":\\\"Loco note 1\\\",\\\"content\\\":\\\"Loco note 1 content\\\"}]\",\n)\n"
  },
  {
    "path": "examples/loco_example/tests/tasks/mod.rs",
    "content": "pub mod seed;\n"
  },
  {
    "path": "examples/loco_example/tests/tasks/seed.rs",
    "content": "//! This task implements data seeding functionality for initializing new\n//! development/demo environments.\n//!\n//! # Example\n//!\n//! Run the task with the following command:\n//! ```sh\n//! cargo run task\n//! ```\n//!\n//! To override existing data and reset the data structure, use the following\n//! command with the `refresh:true` argument:\n//! ```sh\n//! cargo run task seed_data refresh:true\n//! ```\n\nuse loco_rs::{db, prelude::*};\nuse migration::Migrator;\nuse todolist::app::App;\n\n#[allow(clippy::module_name_repetitions)]\npub struct SeedData;\n#[async_trait]\nimpl Task for SeedData {\n    fn task(&self) -> TaskInfo {\n        TaskInfo {\n            name: \"seed_data\".to_string(),\n            detail: \"Task for seeding data\".to_string(),\n        }\n    }\n    async fn run(&self, app_context: &AppContext, vars: &task::Vars) -> Result<()> {\n        let refresh = vars\n            .cli_arg(\"refresh\")\n            .is_ok_and(|refresh| refresh == \"true\");\n\n        if refresh {\n            db::reset::<Migrator>(&app_context.db).await?;\n        }\n        let path = std::path::Path::new(\"src/fixtures\");\n        db::run_app_seed::<App>(app_context, path).await?;\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/.cargo/config.toml",
    "content": "[alias]\nloco       = \"run --\"\nplayground = \"run --example playground\"\n"
  },
  {
    "path": "examples/loco_seaography/.devcontainer/Dockerfile",
    "content": "FROM mcr.microsoft.com/devcontainers/rust:1\n\nRUN apt-get update && export DEBIAN_FRONTEND=noninteractive \\\n     && apt-get -y install --no-install-recommends postgresql-client \\\n     && cargo install sea-orm-cli cargo-insta \\\n     && chown -R vscode /usr/local/cargo\n\nCOPY .env /.env\n"
  },
  {
    "path": "examples/loco_seaography/.devcontainer/devcontainer.json",
    "content": "{\n    \"name\": \"Loco\",\n    \"dockerComposeFile\": \"docker-compose.yml\",\n    \"service\": \"app\",\n    \"workspaceFolder\": \"/workspaces/${localWorkspaceFolderBasename}\",\n    \"forwardPorts\": [\n        3000\n    ]\n}"
  },
  {
    "path": "examples/loco_seaography/.devcontainer/docker-compose.yml",
    "content": "version: \"3\"\n\nservices:\n  app:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    command: sleep infinity\n    networks:\n      - db\n      - redis\n      - mailer\n    volumes:\n      - ../..:/workspaces:cached\n    env_file:\n      - .env\n  db:\n    image: postgres:15.3-alpine\n    restart: unless-stopped\n    ports:\n      - 5432:5432\n    networks:\n      - db\n    volumes:\n      - postgres-data:/var/lib/postgresql/data\n    env_file:\n      - .env\n  redis:\n    image: redis:latest\n    restart: unless-stopped\n    ports:\n      - 6379:6379\n    networks:\n      - redis\n  mailer:\n    image: mailtutan/mailtutan:latest\n    restart: unless-stopped\n    ports:\n      - 1080:1080\n      - 1025:1025\n    networks:\n      - mailer\n\nvolumes:\n  postgres-data:\n\nnetworks:\n  db:\n  redis:\n  mailer:\n"
  },
  {
    "path": "examples/loco_seaography/.github/workflows/ci.yaml",
    "content": "name: CI\non:\n  push:\n    branches:\n      - master\n      - main\n  pull_request:\n\nenv:\n  RUST_TOOLCHAIN: stable\n  TOOLCHAIN_PROFILE: minimal\n\njobs:\n  rustfmt:\n    name: Check Style\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: read\n\n    steps:\n      - name: Checkout the code\n        uses: actions/checkout@v4\n      - uses: actions-rs/toolchain@v1\n        with:\n          profile: ${{ env.TOOLCHAIN_PROFILE }}\n          toolchain: ${{ env.RUST_TOOLCHAIN }}\n          override: true\n          components: rustfmt\n      - name: Run cargo fmt\n        uses: actions-rs/cargo@v1\n        with:\n          command: fmt\n          args: --all -- --check\n\n  clippy:\n    name: Run Clippy\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: read\n\n    steps:\n      - name: Checkout the code\n        uses: actions/checkout@v4\n      - uses: actions-rs/toolchain@v1\n        with:\n          profile: ${{ env.TOOLCHAIN_PROFILE }}\n          toolchain: ${{ env.RUST_TOOLCHAIN }}\n          override: true\n      - name: Setup Rust cache\n        uses: Swatinem/rust-cache@v2\n      - name: Run cargo clippy\n        uses: actions-rs/cargo@v1\n        with:\n          command: clippy\n          args: --all-features -- -D warnings -W clippy::pedantic -W clippy::nursery -W rust-2018-idioms\n\n  test:\n    name: Run Tests\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: read\n\n    services:\n      redis:\n        image: redis\n        options: >-\n          --health-cmd \"redis-cli ping\"\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n        ports:\n          - \"6379:6379\"\n      postgres:\n        image: postgres\n        env:\n          POSTGRES_DB: postgres_test\n          POSTGRES_USER: postgres\n          POSTGRES_PASSWORD: postgres\n        ports:\n          - \"5432:5432\"\n        # Set health checks to wait until postgres has started\n        options: --health-cmd pg_isready\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n\n    steps:\n      - name: Checkout the code\n        uses: actions/checkout@v4\n      - uses: actions-rs/toolchain@v1\n        with:\n          profile: ${{ env.TOOLCHAIN_PROFILE }}\n          toolchain: ${{ env.RUST_TOOLCHAIN }}\n          override: true\n      - name: Setup Rust cache\n        uses: Swatinem/rust-cache@v2\n      - name: Run cargo test\n        uses: actions-rs/cargo@v1\n        with:\n          command: test\n          args: --all-features --all\n        env:\n          REDIS_URL: redis://localhost:${{job.services.redis.ports[6379]}}\n          DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres_test\n"
  },
  {
    "path": "examples/loco_seaography/.gitignore",
    "content": "**/config/local.yaml\n**/config/*.local.yaml\n**/config/production.yaml\n\n# Generated by Cargo\n# will have compiled files and executables\ndebug/\ntarget/\n\n# include cargo lock\n!Cargo.lock\n\n# These are backup files generated by rustfmt\n**/*.rs.bk\n\n# MSVC Windows builds of rustc generate these, which store debugging information\n*.pdb\n\n# Temporary upload directory\nuploads\n\n# Local SQLite databases\n*.db"
  },
  {
    "path": "examples/loco_seaography/.rustfmt.toml",
    "content": "comment_width        = 80\nformat_strings       = true\ngroup_imports        = \"StdExternalCrate\"\nimports_granularity  = \"Crate\"\nmax_width            = 100\nuse_small_heuristics = \"Default\"\nwrap_comments        = true\n"
  },
  {
    "path": "examples/loco_seaography/Cargo.lock",
    "content": "# This file is automatically @generated by Cargo.\n# It is not intended for manual editing.\nversion = 4\n\n[[package]]\nname = \"Inflector\"\nversion = \"0.11.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3\"\ndependencies = [\n \"lazy_static\",\n \"regex\",\n]\n\n[[package]]\nname = \"addr2line\"\nversion = \"0.25.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b\"\ndependencies = [\n \"gimli\",\n]\n\n[[package]]\nname = \"adler2\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa\"\n\n[[package]]\nname = \"ahash\"\nversion = \"0.7.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9\"\ndependencies = [\n \"getrandom 0.2.16\",\n \"once_cell\",\n \"version_check\",\n]\n\n[[package]]\nname = \"ahash\"\nversion = \"0.8.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75\"\ndependencies = [\n \"cfg-if\",\n \"getrandom 0.3.3\",\n \"once_cell\",\n \"version_check\",\n \"zerocopy\",\n]\n\n[[package]]\nname = \"aho-corasick\"\nversion = \"1.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"aliasable\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd\"\n\n[[package]]\nname = \"alloc-no-stdlib\"\nversion = \"2.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3\"\n\n[[package]]\nname = \"alloc-stdlib\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece\"\ndependencies = [\n \"alloc-no-stdlib\",\n]\n\n[[package]]\nname = \"allocator-api2\"\nversion = \"0.2.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923\"\n\n[[package]]\nname = \"android_system_properties\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"anstream\"\nversion = \"0.6.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a\"\ndependencies = [\n \"anstyle\",\n \"anstyle-parse\",\n \"anstyle-query\",\n \"anstyle-wincon\",\n \"colorchoice\",\n \"is_terminal_polyfill\",\n \"utf8parse\",\n]\n\n[[package]]\nname = \"anstyle\"\nversion = \"1.0.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78\"\n\n[[package]]\nname = \"anstyle-parse\"\nversion = \"0.2.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2\"\ndependencies = [\n \"utf8parse\",\n]\n\n[[package]]\nname = \"anstyle-query\"\nversion = \"1.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2\"\ndependencies = [\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"anstyle-wincon\"\nversion = \"3.0.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a\"\ndependencies = [\n \"anstyle\",\n \"once_cell_polyfill\",\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"anyhow\"\nversion = \"1.0.100\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61\"\n\n[[package]]\nname = \"argon2\"\nversion = \"0.5.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072\"\ndependencies = [\n \"base64ct\",\n \"blake2\",\n \"cpufeatures\",\n \"password-hash\",\n]\n\n[[package]]\nname = \"arrayvec\"\nversion = \"0.7.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50\"\n\n[[package]]\nname = \"assert-json-diff\"\nversion = \"2.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12\"\ndependencies = [\n \"serde\",\n \"serde_json\",\n]\n\n[[package]]\nname = \"async-compression\"\nversion = \"0.4.32\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0\"\ndependencies = [\n \"compression-codecs\",\n \"compression-core\",\n \"futures-core\",\n \"pin-project-lite\",\n \"tokio\",\n]\n\n[[package]]\nname = \"async-graphql\"\nversion = \"7.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"036618f842229ba0b89652ffe425f96c7c16a49f7e3cb23b56fca7f61fd74980\"\ndependencies = [\n \"async-graphql-derive\",\n \"async-graphql-parser\",\n \"async-graphql-value\",\n \"async-stream\",\n \"async-trait\",\n \"base64\",\n \"bytes\",\n \"chrono\",\n \"fnv\",\n \"futures-channel\",\n \"futures-timer\",\n \"futures-util\",\n \"http\",\n \"indexmap\",\n \"lru\",\n \"mime\",\n \"multer\",\n \"num-traits\",\n \"pin-project-lite\",\n \"regex\",\n \"rust_decimal\",\n \"serde\",\n \"serde_json\",\n \"serde_urlencoded\",\n \"static_assertions_next\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"async-graphql-axum\"\nversion = \"7.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8725874ecfbf399e071150b8619c4071d7b2b7a2f117e173dddef53c6bdb6bb1\"\ndependencies = [\n \"async-graphql\",\n \"axum\",\n \"bytes\",\n \"futures-util\",\n \"serde_json\",\n \"tokio\",\n \"tokio-stream\",\n \"tokio-util\",\n \"tower-service\",\n]\n\n[[package]]\nname = \"async-graphql-derive\"\nversion = \"7.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fd45deb3dbe5da5cdb8d6a670a7736d735ba65b455328440f236dfb113727a3d\"\ndependencies = [\n \"Inflector\",\n \"async-graphql-parser\",\n \"darling 0.20.11\",\n \"proc-macro-crate\",\n \"proc-macro2\",\n \"quote\",\n \"strum 0.26.3\",\n \"syn 2.0.106\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"async-graphql-parser\"\nversion = \"7.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"60b7607e59424a35dadbc085b0d513aa54ec28160ee640cf79ec3b634eba66d3\"\ndependencies = [\n \"async-graphql-value\",\n \"pest\",\n \"serde\",\n \"serde_json\",\n]\n\n[[package]]\nname = \"async-graphql-value\"\nversion = \"7.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34ecdaff7c9cffa3614a9f9999bf9ee4c3078fe3ce4d6a6e161736b56febf2de\"\ndependencies = [\n \"bytes\",\n \"indexmap\",\n \"serde\",\n \"serde_json\",\n]\n\n[[package]]\nname = \"async-stream\"\nversion = \"0.3.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476\"\ndependencies = [\n \"async-stream-impl\",\n \"futures-core\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"async-stream-impl\"\nversion = \"0.3.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"async-trait\"\nversion = \"0.1.89\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"atoi\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528\"\ndependencies = [\n \"num-traits\",\n]\n\n[[package]]\nname = \"atomic-waker\"\nversion = \"1.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0\"\n\n[[package]]\nname = \"auto-future\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373\"\n\n[[package]]\nname = \"autocfg\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8\"\n\n[[package]]\nname = \"axum\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871\"\ndependencies = [\n \"axum-core\",\n \"axum-macros\",\n \"base64\",\n \"bytes\",\n \"form_urlencoded\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"hyper\",\n \"hyper-util\",\n \"itoa\",\n \"matchit\",\n \"memchr\",\n \"mime\",\n \"multer\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"serde_core\",\n \"serde_json\",\n \"serde_path_to_error\",\n \"serde_urlencoded\",\n \"sha1\",\n \"sync_wrapper\",\n \"tokio\",\n \"tokio-tungstenite\",\n \"tower 0.5.2\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"axum-core\"\nversion = \"0.5.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"mime\",\n \"pin-project-lite\",\n \"sync_wrapper\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"axum-extra\"\nversion = \"0.10.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9963ff19f40c6102c76756ef0a46004c0d58957d87259fc9208ff8441c12ab96\"\ndependencies = [\n \"axum\",\n \"axum-core\",\n \"bytes\",\n \"cookie\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"mime\",\n \"pin-project-lite\",\n \"rustversion\",\n \"serde_core\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"axum-macros\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"axum-test\"\nversion = \"17.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0eb1dfb84bd48bad8e4aa1acb82ed24c2bb5e855b659959b4e03b4dca118fcac\"\ndependencies = [\n \"anyhow\",\n \"assert-json-diff\",\n \"auto-future\",\n \"axum\",\n \"bytes\",\n \"bytesize\",\n \"cookie\",\n \"http\",\n \"http-body-util\",\n \"hyper\",\n \"hyper-util\",\n \"mime\",\n \"pretty_assertions\",\n \"reserve-port\",\n \"rust-multipart-rfc7578_2\",\n \"serde\",\n \"serde_json\",\n \"serde_urlencoded\",\n \"smallvec\",\n \"tokio\",\n \"tower 0.5.2\",\n \"url\",\n]\n\n[[package]]\nname = \"backon\"\nversion = \"1.5.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"592277618714fbcecda9a02ba7a8781f319d26532a88553bbacc77ba5d2b3a8d\"\ndependencies = [\n \"fastrand\",\n \"gloo-timers\",\n \"tokio\",\n]\n\n[[package]]\nname = \"backtrace\"\nversion = \"0.3.76\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6\"\ndependencies = [\n \"addr2line\",\n \"cfg-if\",\n \"libc\",\n \"miniz_oxide\",\n \"object\",\n \"rustc-demangle\",\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"backtrace_printer\"\nversion = \"1.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e8d28de81c708c843640982b66573df0f0168d87e42854b563971f326745aab7\"\ndependencies = [\n \"btparse-stable\",\n \"colored 2.2.0\",\n \"regex\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"base64\"\nversion = \"0.22.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6\"\n\n[[package]]\nname = \"base64ct\"\nversion = \"1.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba\"\n\n[[package]]\nname = \"bigdecimal\"\nversion = \"0.4.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1a22f228ab7a1b23027ccc6c350b72868017af7ea8356fbdf19f8d991c690013\"\ndependencies = [\n \"autocfg\",\n \"libm\",\n \"num-bigint\",\n \"num-integer\",\n \"num-traits\",\n \"serde\",\n]\n\n[[package]]\nname = \"bitflags\"\nversion = \"1.3.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a\"\n\n[[package]]\nname = \"bitflags\"\nversion = \"2.9.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"bitvec\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c\"\ndependencies = [\n \"funty\",\n \"radium\",\n \"tap\",\n \"wyz\",\n]\n\n[[package]]\nname = \"blake2\"\nversion = \"0.10.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe\"\ndependencies = [\n \"digest\",\n]\n\n[[package]]\nname = \"block-buffer\"\nversion = \"0.10.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71\"\ndependencies = [\n \"generic-array\",\n]\n\n[[package]]\nname = \"borsh\"\nversion = \"1.5.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce\"\ndependencies = [\n \"borsh-derive\",\n \"cfg_aliases\",\n]\n\n[[package]]\nname = \"borsh-derive\"\nversion = \"1.5.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3\"\ndependencies = [\n \"once_cell\",\n \"proc-macro-crate\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"brotli\"\nversion = \"8.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560\"\ndependencies = [\n \"alloc-no-stdlib\",\n \"alloc-stdlib\",\n \"brotli-decompressor\",\n]\n\n[[package]]\nname = \"brotli-decompressor\"\nversion = \"5.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03\"\ndependencies = [\n \"alloc-no-stdlib\",\n \"alloc-stdlib\",\n]\n\n[[package]]\nname = \"bstr\"\nversion = \"1.12.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4\"\ndependencies = [\n \"memchr\",\n \"serde\",\n]\n\n[[package]]\nname = \"btparse-stable\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0d75b8252ed252f881d1dc4482ae3c3854df6ee8183c1906bac50ff358f4f89f\"\n\n[[package]]\nname = \"bumpalo\"\nversion = \"3.19.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43\"\n\n[[package]]\nname = \"byte-unit\"\nversion = \"4.0.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c\"\ndependencies = [\n \"serde\",\n \"utf8-width\",\n]\n\n[[package]]\nname = \"bytecheck\"\nversion = \"0.6.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2\"\ndependencies = [\n \"bytecheck_derive\",\n \"ptr_meta\",\n \"simdutf8\",\n]\n\n[[package]]\nname = \"bytecheck_derive\"\nversion = \"0.6.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"byteorder\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b\"\n\n[[package]]\nname = \"bytes\"\nversion = \"1.10.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"bytesize\"\nversion = \"2.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f5c434ae3cf0089ca203e9019ebe529c47ff45cefe8af7c85ecb734ef541822f\"\n\n[[package]]\nname = \"cc\"\nversion = \"1.2.40\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb\"\ndependencies = [\n \"find-msvc-tools\",\n \"jobserver\",\n \"libc\",\n \"shlex\",\n]\n\n[[package]]\nname = \"cfg-if\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9\"\n\n[[package]]\nname = \"cfg_aliases\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724\"\n\n[[package]]\nname = \"chrono\"\nversion = \"0.4.42\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2\"\ndependencies = [\n \"iana-time-zone\",\n \"js-sys\",\n \"num-traits\",\n \"serde\",\n \"wasm-bindgen\",\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"chrono-tz\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb\"\ndependencies = [\n \"chrono\",\n \"chrono-tz-build\",\n \"phf\",\n]\n\n[[package]]\nname = \"chrono-tz-build\"\nversion = \"0.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1\"\ndependencies = [\n \"parse-zoneinfo\",\n \"phf\",\n \"phf_codegen\",\n]\n\n[[package]]\nname = \"chumsky\"\nversion = \"0.9.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9\"\ndependencies = [\n \"hashbrown 0.14.5\",\n \"stacker\",\n]\n\n[[package]]\nname = \"clap\"\nversion = \"4.5.48\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae\"\ndependencies = [\n \"clap_builder\",\n \"clap_derive\",\n]\n\n[[package]]\nname = \"clap_builder\"\nversion = \"4.5.48\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9\"\ndependencies = [\n \"anstream\",\n \"anstyle\",\n \"clap_lex\",\n \"strsim\",\n]\n\n[[package]]\nname = \"clap_derive\"\nversion = \"4.5.47\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c\"\ndependencies = [\n \"heck 0.5.0\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"clap_lex\"\nversion = \"0.7.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675\"\n\n[[package]]\nname = \"colorchoice\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75\"\n\n[[package]]\nname = \"colored\"\nversion = \"2.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c\"\ndependencies = [\n \"lazy_static\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"colored\"\nversion = \"3.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e\"\ndependencies = [\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"combine\"\nversion = \"4.6.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"memchr\",\n \"pin-project-lite\",\n \"tokio\",\n \"tokio-util\",\n]\n\n[[package]]\nname = \"compression-codecs\"\nversion = \"0.4.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23\"\ndependencies = [\n \"brotli\",\n \"compression-core\",\n \"flate2\",\n \"memchr\",\n \"zstd\",\n \"zstd-safe\",\n]\n\n[[package]]\nname = \"compression-core\"\nversion = \"0.4.29\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb\"\n\n[[package]]\nname = \"concurrent-queue\"\nversion = \"2.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"console\"\nversion = \"0.15.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8\"\ndependencies = [\n \"encode_unicode\",\n \"libc\",\n \"once_cell\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"const-oid\"\nversion = \"0.9.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8\"\n\n[[package]]\nname = \"cookie\"\nversion = \"0.18.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747\"\ndependencies = [\n \"percent-encoding\",\n \"time\",\n \"version_check\",\n]\n\n[[package]]\nname = \"core-foundation-sys\"\nversion = \"0.8.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b\"\n\n[[package]]\nname = \"cpufeatures\"\nversion = \"0.2.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"crc\"\nversion = \"3.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675\"\ndependencies = [\n \"crc-catalog\",\n]\n\n[[package]]\nname = \"crc-catalog\"\nversion = \"2.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5\"\n\n[[package]]\nname = \"crc32fast\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511\"\ndependencies = [\n \"cfg-if\",\n]\n\n[[package]]\nname = \"cron\"\nversion = \"0.12.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6f8c3e73077b4b4a6ab1ea5047c37c57aee77657bc8ecd6f29b0af082d0b0c07\"\ndependencies = [\n \"chrono\",\n \"nom 7.1.3\",\n \"once_cell\",\n]\n\n[[package]]\nname = \"crossbeam-channel\"\nversion = \"0.5.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-deque\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51\"\ndependencies = [\n \"crossbeam-epoch\",\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-epoch\"\nversion = \"0.9.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-queue\"\nversion = \"0.3.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-utils\"\nversion = \"0.8.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28\"\n\n[[package]]\nname = \"cruet\"\nversion = \"0.13.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"113a9e83d8f614be76de8df1f25bf9d0ea6e85ea573710a3d3f3abe1438ae49c\"\ndependencies = [\n \"once_cell\",\n \"regex\",\n]\n\n[[package]]\nname = \"cruet\"\nversion = \"0.14.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6132609543972496bc97b1e01f1ce6586768870aeb4cabeb3385f4e05b5caead\"\ndependencies = [\n \"once_cell\",\n \"regex\",\n]\n\n[[package]]\nname = \"crypto-common\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3\"\ndependencies = [\n \"generic-array\",\n \"typenum\",\n]\n\n[[package]]\nname = \"cssparser\"\nversion = \"0.34.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b7c66d1cd8ed61bf80b38432613a7a2f09401ab8d0501110655f8b341484a3e3\"\ndependencies = [\n \"cssparser-macros\",\n \"dtoa-short\",\n \"itoa\",\n \"phf\",\n \"smallvec\",\n]\n\n[[package]]\nname = \"cssparser-macros\"\nversion = \"0.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331\"\ndependencies = [\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"darling\"\nversion = \"0.20.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee\"\ndependencies = [\n \"darling_core 0.20.11\",\n \"darling_macro 0.20.11\",\n]\n\n[[package]]\nname = \"darling\"\nversion = \"0.21.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0\"\ndependencies = [\n \"darling_core 0.21.3\",\n \"darling_macro 0.21.3\",\n]\n\n[[package]]\nname = \"darling_core\"\nversion = \"0.20.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e\"\ndependencies = [\n \"fnv\",\n \"ident_case\",\n \"proc-macro2\",\n \"quote\",\n \"strsim\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"darling_core\"\nversion = \"0.21.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4\"\ndependencies = [\n \"fnv\",\n \"ident_case\",\n \"proc-macro2\",\n \"quote\",\n \"strsim\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"darling_macro\"\nversion = \"0.20.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead\"\ndependencies = [\n \"darling_core 0.20.11\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"darling_macro\"\nversion = \"0.21.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81\"\ndependencies = [\n \"darling_core 0.21.3\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"dashmap\"\nversion = \"5.5.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856\"\ndependencies = [\n \"cfg-if\",\n \"hashbrown 0.14.5\",\n \"lock_api\",\n \"once_cell\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"dashmap\"\nversion = \"6.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf\"\ndependencies = [\n \"cfg-if\",\n \"crossbeam-utils\",\n \"hashbrown 0.14.5\",\n \"lock_api\",\n \"once_cell\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"data-encoding\"\nversion = \"2.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476\"\n\n[[package]]\nname = \"der\"\nversion = \"0.7.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb\"\ndependencies = [\n \"const-oid\",\n \"pem-rfc7468\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"deranged\"\nversion = \"0.5.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071\"\ndependencies = [\n \"powerfmt\",\n \"serde_core\",\n]\n\n[[package]]\nname = \"derive_more\"\nversion = \"0.99.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"derive_more\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678\"\ndependencies = [\n \"derive_more-impl\",\n]\n\n[[package]]\nname = \"derive_more-impl\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"unicode-xid\",\n]\n\n[[package]]\nname = \"deunicode\"\nversion = \"1.6.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04\"\n\n[[package]]\nname = \"diff\"\nversion = \"0.1.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8\"\n\n[[package]]\nname = \"digest\"\nversion = \"0.10.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292\"\ndependencies = [\n \"block-buffer\",\n \"const-oid\",\n \"crypto-common\",\n \"subtle\",\n]\n\n[[package]]\nname = \"displaydoc\"\nversion = \"0.2.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"dotenvy\"\nversion = \"0.15.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b\"\n\n[[package]]\nname = \"dtoa\"\nversion = \"1.0.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04\"\n\n[[package]]\nname = \"dtoa-short\"\nversion = \"0.3.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87\"\ndependencies = [\n \"dtoa\",\n]\n\n[[package]]\nname = \"duct\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d7478638a31d1f1f3d6c9f5e57c76b906a04ac4879d6fd0fb6245bc88f73fd0b\"\ndependencies = [\n \"libc\",\n \"os_pipe\",\n \"shared_child\",\n \"shared_thread\",\n]\n\n[[package]]\nname = \"duct_sh\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8139179d1d133ab7153920ba3812915b17c61e2514a6f98b1fd03f2c07668d1\"\ndependencies = [\n \"duct\",\n]\n\n[[package]]\nname = \"ego-tree\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7c6ba7d4eec39eaa9ab24d44a0e73a7949a1095a8b3f3abb11eddf27dbb56a53\"\n\n[[package]]\nname = \"either\"\nversion = \"1.15.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"email-encoding\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9298e6504d9b9e780ed3f7dfd43a61be8cd0e09eb07f7706a945b0072b6670b6\"\ndependencies = [\n \"base64\",\n \"memchr\",\n]\n\n[[package]]\nname = \"email_address\"\nversion = \"0.2.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449\"\n\n[[package]]\nname = \"encode_unicode\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0\"\n\n[[package]]\nname = \"encoding_rs\"\nversion = \"0.8.35\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3\"\ndependencies = [\n \"cfg-if\",\n]\n\n[[package]]\nname = \"english-to-cron\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e26fb7377cbec9a94f60428e6e6afbe10c699a14639b4d3d4b67b25c0bbe0806\"\ndependencies = [\n \"regex\",\n]\n\n[[package]]\nname = \"equivalent\"\nversion = \"1.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f\"\n\n[[package]]\nname = \"etcetera\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943\"\ndependencies = [\n \"cfg-if\",\n \"home\",\n \"windows-sys 0.48.0\",\n]\n\n[[package]]\nname = \"event-listener\"\nversion = \"5.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab\"\ndependencies = [\n \"concurrent-queue\",\n \"parking\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"eyre\"\nversion = \"0.6.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec\"\ndependencies = [\n \"indenter\",\n \"once_cell\",\n]\n\n[[package]]\nname = \"fastrand\"\nversion = \"2.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be\"\n\n[[package]]\nname = \"find-msvc-tools\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3\"\n\n[[package]]\nname = \"flate2\"\nversion = \"1.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9\"\ndependencies = [\n \"crc32fast\",\n \"miniz_oxide\",\n]\n\n[[package]]\nname = \"flume\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095\"\ndependencies = [\n \"futures-core\",\n \"futures-sink\",\n \"spin\",\n]\n\n[[package]]\nname = \"fnv\"\nversion = \"1.0.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1\"\n\n[[package]]\nname = \"foldhash\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2\"\n\n[[package]]\nname = \"form_urlencoded\"\nversion = \"1.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf\"\ndependencies = [\n \"percent-encoding\",\n]\n\n[[package]]\nname = \"fs-err\"\nversion = \"2.11.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41\"\ndependencies = [\n \"autocfg\",\n]\n\n[[package]]\nname = \"fsevent-sys\"\nversion = \"4.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"funty\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c\"\n\n[[package]]\nname = \"futf\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843\"\ndependencies = [\n \"mac\",\n \"new_debug_unreachable\",\n]\n\n[[package]]\nname = \"futures\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"futures-executor\",\n \"futures-io\",\n \"futures-sink\",\n \"futures-task\",\n \"futures-util\",\n]\n\n[[package]]\nname = \"futures-channel\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10\"\ndependencies = [\n \"futures-core\",\n \"futures-sink\",\n]\n\n[[package]]\nname = \"futures-core\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e\"\n\n[[package]]\nname = \"futures-executor\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f\"\ndependencies = [\n \"futures-core\",\n \"futures-task\",\n \"futures-util\",\n]\n\n[[package]]\nname = \"futures-intrusive\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f\"\ndependencies = [\n \"futures-core\",\n \"lock_api\",\n \"parking_lot\",\n]\n\n[[package]]\nname = \"futures-io\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6\"\n\n[[package]]\nname = \"futures-macro\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"futures-sink\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7\"\n\n[[package]]\nname = \"futures-task\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988\"\n\n[[package]]\nname = \"futures-timer\"\nversion = \"3.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24\"\n\n[[package]]\nname = \"futures-util\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"futures-io\",\n \"futures-macro\",\n \"futures-sink\",\n \"futures-task\",\n \"memchr\",\n \"pin-project-lite\",\n \"pin-utils\",\n \"slab\",\n]\n\n[[package]]\nname = \"fxhash\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c\"\ndependencies = [\n \"byteorder\",\n]\n\n[[package]]\nname = \"generic-array\"\nversion = \"0.14.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a\"\ndependencies = [\n \"typenum\",\n \"version_check\",\n]\n\n[[package]]\nname = \"getopts\"\nversion = \"0.2.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df\"\ndependencies = [\n \"unicode-width\",\n]\n\n[[package]]\nname = \"getrandom\"\nversion = \"0.2.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592\"\ndependencies = [\n \"cfg-if\",\n \"js-sys\",\n \"libc\",\n \"wasi 0.11.1+wasi-snapshot-preview1\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"getrandom\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"r-efi\",\n \"wasi 0.14.7+wasi-0.2.4\",\n]\n\n[[package]]\nname = \"gimli\"\nversion = \"0.32.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7\"\n\n[[package]]\nname = \"glob\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280\"\n\n[[package]]\nname = \"globset\"\nversion = \"0.4.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5\"\ndependencies = [\n \"aho-corasick\",\n \"bstr\",\n \"log\",\n \"regex-automata\",\n \"regex-syntax\",\n]\n\n[[package]]\nname = \"globwalk\"\nversion = \"0.9.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"ignore\",\n \"walkdir\",\n]\n\n[[package]]\nname = \"gloo-timers\"\nversion = \"0.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"js-sys\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.12.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888\"\ndependencies = [\n \"ahash 0.7.8\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.14.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1\"\ndependencies = [\n \"ahash 0.8.12\",\n \"allocator-api2\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.15.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1\"\ndependencies = [\n \"allocator-api2\",\n \"equivalent\",\n \"foldhash\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.16.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d\"\n\n[[package]]\nname = \"hashlink\"\nversion = \"0.10.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1\"\ndependencies = [\n \"hashbrown 0.15.5\",\n]\n\n[[package]]\nname = \"heck\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8\"\n\n[[package]]\nname = \"heck\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea\"\n\n[[package]]\nname = \"hex\"\nversion = \"0.4.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70\"\n\n[[package]]\nname = \"hkdf\"\nversion = \"0.12.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7\"\ndependencies = [\n \"hmac\",\n]\n\n[[package]]\nname = \"hmac\"\nversion = \"0.12.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e\"\ndependencies = [\n \"digest\",\n]\n\n[[package]]\nname = \"home\"\nversion = \"0.5.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf\"\ndependencies = [\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"hostname\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"windows-link 0.1.3\",\n]\n\n[[package]]\nname = \"html5ever\"\nversion = \"0.29.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c\"\ndependencies = [\n \"log\",\n \"mac\",\n \"markup5ever\",\n \"match_token\",\n]\n\n[[package]]\nname = \"http\"\nversion = \"1.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565\"\ndependencies = [\n \"bytes\",\n \"fnv\",\n \"itoa\",\n]\n\n[[package]]\nname = \"http-body\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184\"\ndependencies = [\n \"bytes\",\n \"http\",\n]\n\n[[package]]\nname = \"http-body-util\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"http\",\n \"http-body\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"http-range-header\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c\"\n\n[[package]]\nname = \"httparse\"\nversion = \"1.10.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87\"\n\n[[package]]\nname = \"httpdate\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9\"\n\n[[package]]\nname = \"humansize\"\nversion = \"2.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7\"\ndependencies = [\n \"libm\",\n]\n\n[[package]]\nname = \"hyper\"\nversion = \"1.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e\"\ndependencies = [\n \"atomic-waker\",\n \"bytes\",\n \"futures-channel\",\n \"futures-core\",\n \"http\",\n \"http-body\",\n \"httparse\",\n \"httpdate\",\n \"itoa\",\n \"pin-project-lite\",\n \"pin-utils\",\n \"smallvec\",\n \"tokio\",\n \"want\",\n]\n\n[[package]]\nname = \"hyper-util\"\nversion = \"0.1.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8\"\ndependencies = [\n \"base64\",\n \"bytes\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"hyper\",\n \"ipnet\",\n \"libc\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"socket2 0.5.10\",\n \"tokio\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"iana-time-zone\"\nversion = \"0.1.64\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb\"\ndependencies = [\n \"android_system_properties\",\n \"core-foundation-sys\",\n \"iana-time-zone-haiku\",\n \"js-sys\",\n \"log\",\n \"wasm-bindgen\",\n \"windows-core\",\n]\n\n[[package]]\nname = \"iana-time-zone-haiku\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f\"\ndependencies = [\n \"cc\",\n]\n\n[[package]]\nname = \"icu_collections\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47\"\ndependencies = [\n \"displaydoc\",\n \"potential_utf\",\n \"yoke\",\n \"zerofrom\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_locale_core\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a\"\ndependencies = [\n \"displaydoc\",\n \"litemap\",\n \"tinystr\",\n \"writeable\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_normalizer\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979\"\ndependencies = [\n \"displaydoc\",\n \"icu_collections\",\n \"icu_normalizer_data\",\n \"icu_properties\",\n \"icu_provider\",\n \"smallvec\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_normalizer_data\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3\"\n\n[[package]]\nname = \"icu_properties\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b\"\ndependencies = [\n \"displaydoc\",\n \"icu_collections\",\n \"icu_locale_core\",\n \"icu_properties_data\",\n \"icu_provider\",\n \"potential_utf\",\n \"zerotrie\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_properties_data\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632\"\n\n[[package]]\nname = \"icu_provider\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af\"\ndependencies = [\n \"displaydoc\",\n \"icu_locale_core\",\n \"stable_deref_trait\",\n \"tinystr\",\n \"writeable\",\n \"yoke\",\n \"zerofrom\",\n \"zerotrie\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"ident_case\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39\"\n\n[[package]]\nname = \"idna\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de\"\ndependencies = [\n \"idna_adapter\",\n \"smallvec\",\n \"utf8_iter\",\n]\n\n[[package]]\nname = \"idna_adapter\"\nversion = \"1.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344\"\ndependencies = [\n \"icu_normalizer\",\n \"icu_properties\",\n]\n\n[[package]]\nname = \"ignore\"\nversion = \"0.4.23\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b\"\ndependencies = [\n \"crossbeam-deque\",\n \"globset\",\n \"log\",\n \"memchr\",\n \"regex-automata\",\n \"same-file\",\n \"walkdir\",\n \"winapi-util\",\n]\n\n[[package]]\nname = \"include_dir\"\nversion = \"0.7.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd\"\ndependencies = [\n \"include_dir_macros\",\n]\n\n[[package]]\nname = \"include_dir_macros\"\nversion = \"0.7.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n]\n\n[[package]]\nname = \"indenter\"\nversion = \"0.3.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5\"\n\n[[package]]\nname = \"indexmap\"\nversion = \"2.11.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5\"\ndependencies = [\n \"equivalent\",\n \"hashbrown 0.16.0\",\n \"serde\",\n \"serde_core\",\n]\n\n[[package]]\nname = \"indoc\"\nversion = \"2.0.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706\"\ndependencies = [\n \"rustversion\",\n]\n\n[[package]]\nname = \"inherent\"\nversion = \"1.0.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c727f80bfa4a6c6e2508d2f05b6f4bfce242030bd88ed15ae5331c5b5d30fba7\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"inotify\"\nversion = \"0.11.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"inotify-sys\",\n \"libc\",\n]\n\n[[package]]\nname = \"inotify-sys\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"insta\"\nversion = \"1.43.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"46fdb647ebde000f43b5b53f773c30cf9b0cb4300453208713fa38b2c70935a0\"\ndependencies = [\n \"console\",\n \"once_cell\",\n \"pest\",\n \"pest_derive\",\n \"regex\",\n \"serde\",\n \"similar\",\n]\n\n[[package]]\nname = \"io-uring\"\nversion = \"0.7.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"cfg-if\",\n \"libc\",\n]\n\n[[package]]\nname = \"ipnet\"\nversion = \"2.11.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130\"\n\n[[package]]\nname = \"ipnetwork\"\nversion = \"0.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"iri-string\"\nversion = \"0.7.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2\"\ndependencies = [\n \"memchr\",\n \"serde\",\n]\n\n[[package]]\nname = \"is_terminal_polyfill\"\nversion = \"1.70.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf\"\n\n[[package]]\nname = \"itertools\"\nversion = \"0.12.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569\"\ndependencies = [\n \"either\",\n]\n\n[[package]]\nname = \"itertools\"\nversion = \"0.14.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285\"\ndependencies = [\n \"either\",\n]\n\n[[package]]\nname = \"itoa\"\nversion = \"1.0.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c\"\n\n[[package]]\nname = \"jobserver\"\nversion = \"0.1.34\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33\"\ndependencies = [\n \"getrandom 0.3.3\",\n \"libc\",\n]\n\n[[package]]\nname = \"js-sys\"\nversion = \"0.3.81\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305\"\ndependencies = [\n \"once_cell\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"jsonwebtoken\"\nversion = \"9.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde\"\ndependencies = [\n \"base64\",\n \"js-sys\",\n \"pem\",\n \"ring\",\n \"serde\",\n \"serde_json\",\n \"simple_asn1\",\n]\n\n[[package]]\nname = \"kqueue\"\nversion = \"1.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a\"\ndependencies = [\n \"kqueue-sys\",\n \"libc\",\n]\n\n[[package]]\nname = \"kqueue-sys\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b\"\ndependencies = [\n \"bitflags 1.3.2\",\n \"libc\",\n]\n\n[[package]]\nname = \"lazy_static\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe\"\ndependencies = [\n \"spin\",\n]\n\n[[package]]\nname = \"lettre\"\nversion = \"0.11.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5cb54db6ff7a89efac87dba5baeac57bb9ccd726b49a9b6f21fb92b3966aaf56\"\ndependencies = [\n \"async-trait\",\n \"base64\",\n \"chumsky\",\n \"email-encoding\",\n \"email_address\",\n \"fastrand\",\n \"futures-io\",\n \"futures-util\",\n \"hostname\",\n \"httpdate\",\n \"idna\",\n \"mime\",\n \"nom 8.0.0\",\n \"percent-encoding\",\n \"quoted_printable\",\n \"rustls\",\n \"socket2 0.6.0\",\n \"tokio\",\n \"tokio-rustls\",\n \"url\",\n \"webpki-roots 1.0.2\",\n]\n\n[[package]]\nname = \"libc\"\nversion = \"0.2.176\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174\"\n\n[[package]]\nname = \"libm\"\nversion = \"0.2.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de\"\n\n[[package]]\nname = \"libredox\"\nversion = \"0.1.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"libc\",\n \"redox_syscall\",\n]\n\n[[package]]\nname = \"libsqlite3-sys\"\nversion = \"0.30.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149\"\ndependencies = [\n \"cc\",\n \"pkg-config\",\n \"vcpkg\",\n]\n\n[[package]]\nname = \"litemap\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956\"\n\n[[package]]\nname = \"lock_api\"\nversion = \"0.4.14\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965\"\ndependencies = [\n \"scopeguard\",\n]\n\n[[package]]\nname = \"loco-gen\"\nversion = \"0.16.3\"\nsource = \"git+https://github.com/SeaQL/loco?branch=master#0e2860b7885e6c00e013b3618896a78095809ede\"\ndependencies = [\n \"chrono\",\n \"clap\",\n \"colored 3.0.0\",\n \"cruet 0.14.0\",\n \"duct\",\n \"heck 0.4.1\",\n \"include_dir\",\n \"regex\",\n \"rrgen\",\n \"serde\",\n \"serde_json\",\n \"tera\",\n \"thiserror 1.0.69\",\n \"tracing\",\n]\n\n[[package]]\nname = \"loco-rs\"\nversion = \"0.16.3\"\nsource = \"git+https://github.com/SeaQL/loco?branch=master#0e2860b7885e6c00e013b3618896a78095809ede\"\ndependencies = [\n \"argon2\",\n \"async-trait\",\n \"axum\",\n \"axum-extra\",\n \"axum-test\",\n \"backtrace_printer\",\n \"byte-unit\",\n \"bytes\",\n \"chrono\",\n \"clap\",\n \"colored 3.0.0\",\n \"cruet 0.13.3\",\n \"dashmap 6.1.0\",\n \"duct\",\n \"duct_sh\",\n \"english-to-cron\",\n \"futures-util\",\n \"heck 0.4.1\",\n \"include_dir\",\n \"ipnetwork\",\n \"jsonwebtoken\",\n \"lettre\",\n \"loco-gen\",\n \"moka\",\n \"notify\",\n \"opendal\",\n \"rand 0.9.2\",\n \"redis\",\n \"regex\",\n \"scraper\",\n \"sea-orm\",\n \"sea-orm-migration\",\n \"semver\",\n \"serde\",\n \"serde_json\",\n \"serde_variant\",\n \"serde_yaml\",\n \"sqlx\",\n \"tera\",\n \"thiserror 1.0.69\",\n \"tokio\",\n \"tokio-cron-scheduler\",\n \"tokio-util\",\n \"toml\",\n \"tower 0.4.13\",\n \"tower-http\",\n \"tracing\",\n \"tracing-appender\",\n \"tracing-subscriber\",\n \"tree-fs\",\n \"ulid\",\n \"uuid\",\n \"validator\",\n]\n\n[[package]]\nname = \"loco_seaography\"\nversion = \"0.1.0\"\ndependencies = [\n \"async-graphql-axum\",\n \"async-trait\",\n \"axum\",\n \"chrono\",\n \"eyre\",\n \"include_dir\",\n \"insta\",\n \"lazy_static\",\n \"loco-rs\",\n \"migration\",\n \"rstest\",\n \"sea-orm\",\n \"seaography\",\n \"serde\",\n \"serde_json\",\n \"serial_test\",\n \"tokio\",\n \"tokio-util\",\n \"tower-service\",\n \"tracing\",\n \"tracing-subscriber\",\n \"uuid\",\n \"validator\",\n]\n\n[[package]]\nname = \"log\"\nversion = \"0.4.28\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432\"\n\n[[package]]\nname = \"lru\"\nversion = \"0.12.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38\"\ndependencies = [\n \"hashbrown 0.15.5\",\n]\n\n[[package]]\nname = \"mac\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4\"\n\n[[package]]\nname = \"markup5ever\"\nversion = \"0.14.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18\"\ndependencies = [\n \"log\",\n \"phf\",\n \"phf_codegen\",\n \"string_cache\",\n \"string_cache_codegen\",\n \"tendril\",\n]\n\n[[package]]\nname = \"match_token\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"matchers\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9\"\ndependencies = [\n \"regex-automata\",\n]\n\n[[package]]\nname = \"matchit\"\nversion = \"0.8.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3\"\n\n[[package]]\nname = \"md-5\"\nversion = \"0.10.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf\"\ndependencies = [\n \"cfg-if\",\n \"digest\",\n]\n\n[[package]]\nname = \"memchr\"\nversion = \"2.7.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273\"\n\n[[package]]\nname = \"migration\"\nversion = \"0.1.0\"\ndependencies = [\n \"loco-rs\",\n \"sea-orm-migration\",\n \"tokio\",\n]\n\n[[package]]\nname = \"mime\"\nversion = \"0.3.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a\"\n\n[[package]]\nname = \"mime_guess\"\nversion = \"2.0.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e\"\ndependencies = [\n \"mime\",\n \"unicase\",\n]\n\n[[package]]\nname = \"minimal-lexical\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a\"\n\n[[package]]\nname = \"miniz_oxide\"\nversion = \"0.8.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316\"\ndependencies = [\n \"adler2\",\n \"simd-adler32\",\n]\n\n[[package]]\nname = \"mio\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c\"\ndependencies = [\n \"libc\",\n \"log\",\n \"wasi 0.11.1+wasi-snapshot-preview1\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"moka\"\nversion = \"0.12.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8261cd88c312e0004c1d51baad2980c66528dfdb2bee62003e643a4d8f86b077\"\ndependencies = [\n \"crossbeam-channel\",\n \"crossbeam-epoch\",\n \"crossbeam-utils\",\n \"equivalent\",\n \"parking_lot\",\n \"portable-atomic\",\n \"rustc_version\",\n \"smallvec\",\n \"tagptr\",\n \"uuid\",\n]\n\n[[package]]\nname = \"multer\"\nversion = \"3.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b\"\ndependencies = [\n \"bytes\",\n \"encoding_rs\",\n \"futures-util\",\n \"http\",\n \"httparse\",\n \"memchr\",\n \"mime\",\n \"spin\",\n \"version_check\",\n]\n\n[[package]]\nname = \"new_debug_unreachable\"\nversion = \"1.0.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086\"\n\n[[package]]\nname = \"nom\"\nversion = \"7.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a\"\ndependencies = [\n \"memchr\",\n \"minimal-lexical\",\n]\n\n[[package]]\nname = \"nom\"\nversion = \"8.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"notify\"\nversion = \"8.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"fsevent-sys\",\n \"inotify\",\n \"kqueue\",\n \"libc\",\n \"log\",\n \"mio\",\n \"notify-types\",\n \"walkdir\",\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"notify-types\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d\"\n\n[[package]]\nname = \"nu-ansi-term\"\nversion = \"0.50.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399\"\ndependencies = [\n \"windows-sys 0.52.0\",\n]\n\n[[package]]\nname = \"num-bigint\"\nversion = \"0.4.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9\"\ndependencies = [\n \"num-integer\",\n \"num-traits\",\n]\n\n[[package]]\nname = \"num-bigint-dig\"\nversion = \"0.8.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151\"\ndependencies = [\n \"byteorder\",\n \"lazy_static\",\n \"libm\",\n \"num-integer\",\n \"num-iter\",\n \"num-traits\",\n \"rand 0.8.5\",\n \"smallvec\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"num-conv\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9\"\n\n[[package]]\nname = \"num-derive\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"num-integer\"\nversion = \"0.1.46\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f\"\ndependencies = [\n \"num-traits\",\n]\n\n[[package]]\nname = \"num-iter\"\nversion = \"0.1.45\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf\"\ndependencies = [\n \"autocfg\",\n \"num-integer\",\n \"num-traits\",\n]\n\n[[package]]\nname = \"num-traits\"\nversion = \"0.2.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841\"\ndependencies = [\n \"autocfg\",\n \"libm\",\n]\n\n[[package]]\nname = \"object\"\nversion = \"0.37.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"once_cell\"\nversion = \"1.21.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d\"\n\n[[package]]\nname = \"once_cell_polyfill\"\nversion = \"1.70.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad\"\n\n[[package]]\nname = \"opendal\"\nversion = \"0.54.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ffb9838d0575c6dbaf3fcec7255af8d5771996d4af900bbb6fa9a314dec00a1a\"\ndependencies = [\n \"anyhow\",\n \"backon\",\n \"base64\",\n \"bytes\",\n \"chrono\",\n \"futures\",\n \"getrandom 0.2.16\",\n \"http\",\n \"http-body\",\n \"log\",\n \"md-5\",\n \"percent-encoding\",\n \"quick-xml\",\n \"reqwest\",\n \"serde\",\n \"serde_json\",\n \"tokio\",\n \"uuid\",\n]\n\n[[package]]\nname = \"ordered-float\"\nversion = \"4.6.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951\"\ndependencies = [\n \"num-traits\",\n]\n\n[[package]]\nname = \"os_pipe\"\nversion = \"1.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"db335f4760b14ead6290116f2427bf33a14d4f0617d49f78a246de10c1831224\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"ouroboros\"\nversion = \"0.18.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59\"\ndependencies = [\n \"aliasable\",\n \"ouroboros_macro\",\n \"static_assertions\",\n]\n\n[[package]]\nname = \"ouroboros_macro\"\nversion = \"0.18.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0\"\ndependencies = [\n \"heck 0.4.1\",\n \"proc-macro2\",\n \"proc-macro2-diagnostics\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"parking\"\nversion = \"2.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba\"\n\n[[package]]\nname = \"parking_lot\"\nversion = \"0.12.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a\"\ndependencies = [\n \"lock_api\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"parking_lot_core\"\nversion = \"0.9.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"redox_syscall\",\n \"smallvec\",\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"parse-zoneinfo\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24\"\ndependencies = [\n \"regex\",\n]\n\n[[package]]\nname = \"password-hash\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166\"\ndependencies = [\n \"base64ct\",\n \"rand_core 0.6.4\",\n \"subtle\",\n]\n\n[[package]]\nname = \"pem\"\nversion = \"3.0.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3\"\ndependencies = [\n \"base64\",\n \"serde\",\n]\n\n[[package]]\nname = \"pem-rfc7468\"\nversion = \"0.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412\"\ndependencies = [\n \"base64ct\",\n]\n\n[[package]]\nname = \"percent-encoding\"\nversion = \"2.3.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220\"\n\n[[package]]\nname = \"pest\"\nversion = \"2.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4\"\ndependencies = [\n \"memchr\",\n \"ucd-trie\",\n]\n\n[[package]]\nname = \"pest_derive\"\nversion = \"2.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de\"\ndependencies = [\n \"pest\",\n \"pest_generator\",\n]\n\n[[package]]\nname = \"pest_generator\"\nversion = \"2.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843\"\ndependencies = [\n \"pest\",\n \"pest_meta\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"pest_meta\"\nversion = \"2.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a\"\ndependencies = [\n \"pest\",\n \"sha2\",\n]\n\n[[package]]\nname = \"pgvector\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fc58e2d255979a31caa7cabfa7aac654af0354220719ab7a68520ae7a91e8c0b\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"phf\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078\"\ndependencies = [\n \"phf_macros\",\n \"phf_shared\",\n]\n\n[[package]]\nname = \"phf_codegen\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a\"\ndependencies = [\n \"phf_generator\",\n \"phf_shared\",\n]\n\n[[package]]\nname = \"phf_generator\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d\"\ndependencies = [\n \"phf_shared\",\n \"rand 0.8.5\",\n]\n\n[[package]]\nname = \"phf_macros\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216\"\ndependencies = [\n \"phf_generator\",\n \"phf_shared\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"phf_shared\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5\"\ndependencies = [\n \"siphasher\",\n]\n\n[[package]]\nname = \"pin-project-lite\"\nversion = \"0.2.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b\"\n\n[[package]]\nname = \"pin-utils\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184\"\n\n[[package]]\nname = \"pkcs1\"\nversion = \"0.7.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f\"\ndependencies = [\n \"der\",\n \"pkcs8\",\n \"spki\",\n]\n\n[[package]]\nname = \"pkcs8\"\nversion = \"0.10.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7\"\ndependencies = [\n \"der\",\n \"spki\",\n]\n\n[[package]]\nname = \"pkg-config\"\nversion = \"0.3.32\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c\"\n\n[[package]]\nname = \"pluralizer\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4b3eba432a00a1f6c16f39147847a870e94e2e9b992759b503e330efec778cbe\"\ndependencies = [\n \"once_cell\",\n \"regex\",\n]\n\n[[package]]\nname = \"portable-atomic\"\nversion = \"1.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483\"\n\n[[package]]\nname = \"potential_utf\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a\"\ndependencies = [\n \"zerovec\",\n]\n\n[[package]]\nname = \"powerfmt\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391\"\n\n[[package]]\nname = \"ppv-lite86\"\nversion = \"0.2.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9\"\ndependencies = [\n \"zerocopy\",\n]\n\n[[package]]\nname = \"precomputed-hash\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c\"\n\n[[package]]\nname = \"pretty_assertions\"\nversion = \"1.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d\"\ndependencies = [\n \"diff\",\n \"yansi\",\n]\n\n[[package]]\nname = \"proc-macro-crate\"\nversion = \"3.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983\"\ndependencies = [\n \"toml_edit 0.23.6\",\n]\n\n[[package]]\nname = \"proc-macro-error-attr2\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n]\n\n[[package]]\nname = \"proc-macro-error2\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802\"\ndependencies = [\n \"proc-macro-error-attr2\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"proc-macro2\"\nversion = \"1.0.101\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de\"\ndependencies = [\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"proc-macro2-diagnostics\"\nversion = \"0.10.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"version_check\",\n \"yansi\",\n]\n\n[[package]]\nname = \"psm\"\nversion = \"0.1.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e66fcd288453b748497d8fb18bccc83a16b0518e3906d4b8df0a8d42d93dbb1c\"\ndependencies = [\n \"cc\",\n]\n\n[[package]]\nname = \"ptr_meta\"\nversion = \"0.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1\"\ndependencies = [\n \"ptr_meta_derive\",\n]\n\n[[package]]\nname = \"ptr_meta_derive\"\nversion = \"0.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"quick-xml\"\nversion = \"0.37.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb\"\ndependencies = [\n \"memchr\",\n \"serde\",\n]\n\n[[package]]\nname = \"quote\"\nversion = \"1.0.41\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1\"\ndependencies = [\n \"proc-macro2\",\n]\n\n[[package]]\nname = \"quoted_printable\"\nversion = \"0.5.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"640c9bd8497b02465aeef5375144c26062e0dcd5939dfcbb0f5db76cb8c17c73\"\n\n[[package]]\nname = \"r-efi\"\nversion = \"5.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f\"\n\n[[package]]\nname = \"radium\"\nversion = \"0.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09\"\n\n[[package]]\nname = \"rand\"\nversion = \"0.8.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404\"\ndependencies = [\n \"libc\",\n \"rand_chacha 0.3.1\",\n \"rand_core 0.6.4\",\n]\n\n[[package]]\nname = \"rand\"\nversion = \"0.9.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1\"\ndependencies = [\n \"rand_chacha 0.9.0\",\n \"rand_core 0.9.3\",\n]\n\n[[package]]\nname = \"rand_chacha\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88\"\ndependencies = [\n \"ppv-lite86\",\n \"rand_core 0.6.4\",\n]\n\n[[package]]\nname = \"rand_chacha\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb\"\ndependencies = [\n \"ppv-lite86\",\n \"rand_core 0.9.3\",\n]\n\n[[package]]\nname = \"rand_core\"\nversion = \"0.6.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c\"\ndependencies = [\n \"getrandom 0.2.16\",\n]\n\n[[package]]\nname = \"rand_core\"\nversion = \"0.9.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38\"\ndependencies = [\n \"getrandom 0.3.3\",\n]\n\n[[package]]\nname = \"redis\"\nversion = \"0.31.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0bc1ea653e0b2e097db3ebb5b7f678be339620b8041f66b30a308c1d45d36a7f\"\ndependencies = [\n \"bytes\",\n \"cfg-if\",\n \"combine\",\n \"futures-util\",\n \"itoa\",\n \"num-bigint\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"ryu\",\n \"sha1_smol\",\n \"socket2 0.5.10\",\n \"tokio\",\n \"tokio-util\",\n \"url\",\n]\n\n[[package]]\nname = \"redox_syscall\"\nversion = \"0.5.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d\"\ndependencies = [\n \"bitflags 2.9.4\",\n]\n\n[[package]]\nname = \"regex\"\nversion = \"1.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c\"\ndependencies = [\n \"aho-corasick\",\n \"memchr\",\n \"regex-automata\",\n \"regex-syntax\",\n]\n\n[[package]]\nname = \"regex-automata\"\nversion = \"0.4.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad\"\ndependencies = [\n \"aho-corasick\",\n \"memchr\",\n \"regex-syntax\",\n]\n\n[[package]]\nname = \"regex-syntax\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001\"\n\n[[package]]\nname = \"relative-path\"\nversion = \"1.9.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2\"\n\n[[package]]\nname = \"rend\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c\"\ndependencies = [\n \"bytecheck\",\n]\n\n[[package]]\nname = \"reqwest\"\nversion = \"0.12.23\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb\"\ndependencies = [\n \"base64\",\n \"bytes\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"hyper\",\n \"hyper-util\",\n \"js-sys\",\n \"log\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"serde\",\n \"serde_json\",\n \"serde_urlencoded\",\n \"sync_wrapper\",\n \"tokio\",\n \"tokio-util\",\n \"tower 0.5.2\",\n \"tower-http\",\n \"tower-service\",\n \"url\",\n \"wasm-bindgen\",\n \"wasm-bindgen-futures\",\n \"wasm-streams\",\n \"web-sys\",\n]\n\n[[package]]\nname = \"reserve-port\"\nversion = \"2.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"21918d6644020c6f6ef1993242989bf6d4952d2e025617744f184c02df51c356\"\ndependencies = [\n \"thiserror 2.0.17\",\n]\n\n[[package]]\nname = \"ring\"\nversion = \"0.17.14\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7\"\ndependencies = [\n \"cc\",\n \"cfg-if\",\n \"getrandom 0.2.16\",\n \"libc\",\n \"untrusted\",\n \"windows-sys 0.52.0\",\n]\n\n[[package]]\nname = \"rkyv\"\nversion = \"0.7.45\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b\"\ndependencies = [\n \"bitvec\",\n \"bytecheck\",\n \"bytes\",\n \"hashbrown 0.12.3\",\n \"ptr_meta\",\n \"rend\",\n \"rkyv_derive\",\n \"seahash\",\n \"tinyvec\",\n \"uuid\",\n]\n\n[[package]]\nname = \"rkyv_derive\"\nversion = \"0.7.45\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"rrgen\"\nversion = \"0.5.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ee7a7ede035354391a37e42aa4935b3d8921f0ded896d2ce44bb1a3b6dd76bab\"\ndependencies = [\n \"cruet 0.13.3\",\n \"fs-err\",\n \"glob\",\n \"heck 0.4.1\",\n \"regex\",\n \"serde\",\n \"serde_json\",\n \"serde_regex\",\n \"serde_yaml\",\n \"tera\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"rsa\"\nversion = \"0.9.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b\"\ndependencies = [\n \"const-oid\",\n \"digest\",\n \"num-bigint-dig\",\n \"num-integer\",\n \"num-traits\",\n \"pkcs1\",\n \"pkcs8\",\n \"rand_core 0.6.4\",\n \"signature\",\n \"spki\",\n \"subtle\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"rstest\"\nversion = \"0.18.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"97eeab2f3c0a199bc4be135c36c924b6590b88c377d416494288c14f2db30199\"\ndependencies = [\n \"futures\",\n \"futures-timer\",\n \"rstest_macros\",\n \"rustc_version\",\n]\n\n[[package]]\nname = \"rstest_macros\"\nversion = \"0.18.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d428f8247852f894ee1be110b375111b586d4fa431f6c46e64ba5a0dcccbe605\"\ndependencies = [\n \"cfg-if\",\n \"glob\",\n \"proc-macro2\",\n \"quote\",\n \"regex\",\n \"relative-path\",\n \"rustc_version\",\n \"syn 2.0.106\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"rust-multipart-rfc7578_2\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c839d037155ebc06a571e305af66ff9fd9063a6e662447051737e1ac75beea41\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"mime\",\n \"rand 0.9.2\",\n \"thiserror 2.0.17\",\n]\n\n[[package]]\nname = \"rust_decimal\"\nversion = \"1.38.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8975fc98059f365204d635119cf9c5a60ae67b841ed49b5422a9a7e56cdfac0\"\ndependencies = [\n \"arrayvec\",\n \"borsh\",\n \"bytes\",\n \"num-traits\",\n \"rand 0.8.5\",\n \"rkyv\",\n \"serde\",\n \"serde_json\",\n]\n\n[[package]]\nname = \"rustc-demangle\"\nversion = \"0.1.26\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace\"\n\n[[package]]\nname = \"rustc_version\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92\"\ndependencies = [\n \"semver\",\n]\n\n[[package]]\nname = \"rustls\"\nversion = \"0.23.32\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40\"\ndependencies = [\n \"log\",\n \"once_cell\",\n \"ring\",\n \"rustls-pki-types\",\n \"rustls-webpki\",\n \"subtle\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"rustls-pki-types\"\nversion = \"1.12.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79\"\ndependencies = [\n \"zeroize\",\n]\n\n[[package]]\nname = \"rustls-webpki\"\nversion = \"0.103.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf\"\ndependencies = [\n \"ring\",\n \"rustls-pki-types\",\n \"untrusted\",\n]\n\n[[package]]\nname = \"rustversion\"\nversion = \"1.0.22\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d\"\n\n[[package]]\nname = \"ryu\"\nversion = \"1.0.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f\"\n\n[[package]]\nname = \"same-file\"\nversion = \"1.0.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502\"\ndependencies = [\n \"winapi-util\",\n]\n\n[[package]]\nname = \"scopeguard\"\nversion = \"1.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49\"\n\n[[package]]\nname = \"scraper\"\nversion = \"0.21.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b0e749d29b2064585327af5038a5a8eb73aeebad4a3472e83531a436563f7208\"\ndependencies = [\n \"ahash 0.8.12\",\n \"cssparser\",\n \"ego-tree\",\n \"getopts\",\n \"html5ever\",\n \"indexmap\",\n \"precomputed-hash\",\n \"selectors\",\n \"tendril\",\n]\n\n[[package]]\nname = \"sea-bae\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f694a6ab48f14bc063cfadff30ab551d3c7e46d8f81836c51989d548f44a2a25\"\ndependencies = [\n \"heck 0.4.1\",\n \"proc-macro-error2\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"sea-orm\"\nversion = \"2.0.0-rc.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"25c0efc234bdf1f073cc9b448da21a22ed0ac7ff0958a0b3bc4994041dc059df\"\ndependencies = [\n \"async-stream\",\n \"async-trait\",\n \"bigdecimal\",\n \"chrono\",\n \"derive_more 2.0.1\",\n \"futures-util\",\n \"itertools 0.14.0\",\n \"log\",\n \"ouroboros\",\n \"pgvector\",\n \"rust_decimal\",\n \"sea-orm-macros\",\n \"sea-query\",\n \"sea-query-sqlx\",\n \"sea-schema\",\n \"serde\",\n \"serde_json\",\n \"sqlx\",\n \"strum 0.27.2\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tracing\",\n \"url\",\n \"uuid\",\n]\n\n[[package]]\nname = \"sea-orm-cli\"\nversion = \"2.0.0-rc.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f50ae78e4442db69930949a8bcf3b82b0e992c8ea389ae2b1d80504029adab5d\"\ndependencies = [\n \"chrono\",\n \"clap\",\n \"dotenvy\",\n \"glob\",\n \"indoc\",\n \"regex\",\n \"sea-schema\",\n \"sqlx\",\n \"tokio\",\n \"tracing\",\n \"tracing-subscriber\",\n \"url\",\n]\n\n[[package]]\nname = \"sea-orm-macros\"\nversion = \"2.0.0-rc.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"35b6ce0ae263925930d4e0f95e24a5a8b069dccc61a1ef68da26338470d94929\"\ndependencies = [\n \"heck 0.5.0\",\n \"pluralizer\",\n \"proc-macro-crate\",\n \"proc-macro2\",\n \"quote\",\n \"sea-bae\",\n \"syn 2.0.106\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"sea-orm-migration\"\nversion = \"2.0.0-rc.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"433fa69cd3f8dc754a2dc51106aee10262fec84ac5195ff7d9966dd1c0d467bd\"\ndependencies = [\n \"async-trait\",\n \"clap\",\n \"dotenvy\",\n \"sea-orm\",\n \"sea-orm-cli\",\n \"sea-schema\",\n \"tracing\",\n \"tracing-subscriber\",\n]\n\n[[package]]\nname = \"sea-query\"\nversion = \"1.0.0-rc.29\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93948054fb2d208555a96d03d2c887591deb42ffe3210eedbd8a3234c6fb6d34\"\ndependencies = [\n \"chrono\",\n \"inherent\",\n \"ordered-float\",\n \"rust_decimal\",\n \"sea-query-derive\",\n \"serde_json\",\n \"time\",\n \"uuid\",\n]\n\n[[package]]\nname = \"sea-query-derive\"\nversion = \"1.0.0-rc.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"217e9422de35f26c16c5f671fce3c075a65e10322068dbc66078428634af6195\"\ndependencies = [\n \"darling 0.20.11\",\n \"heck 0.4.1\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"thiserror 2.0.17\",\n]\n\n[[package]]\nname = \"sea-query-sqlx\"\nversion = \"0.8.0-rc.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"693f3ac3a10a228afaf3512b122cffc07c57b4269d233c7ff60571ebb4f0dd17\"\ndependencies = [\n \"chrono\",\n \"rust_decimal\",\n \"sea-query\",\n \"serde_json\",\n \"sqlx\",\n \"time\",\n \"uuid\",\n]\n\n[[package]]\nname = \"sea-schema\"\nversion = \"0.17.0-rc.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b363dd21c20fe4d1488819cb2bc7f8d4696c62dd9f39554f97639f54d57dd0ab\"\ndependencies = [\n \"async-trait\",\n \"sea-query\",\n \"sea-query-sqlx\",\n \"sea-schema-derive\",\n \"sqlx\",\n]\n\n[[package]]\nname = \"sea-schema-derive\"\nversion = \"0.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"debdc8729c37fdbf88472f97fd470393089f997a909e535ff67c544d18cfccf0\"\ndependencies = [\n \"heck 0.4.1\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"seahash\"\nversion = \"4.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b\"\n\n[[package]]\nname = \"seaography\"\nversion = \"2.0.0-rc.6\"\nsource = \"git+https://github.com/SeaQL/seaography.git?branch=main#ee380956016e74531015051a31f889e45337a335\"\ndependencies = [\n \"async-graphql\",\n \"fnv\",\n \"heck 0.4.1\",\n \"itertools 0.12.1\",\n \"lazy_static\",\n \"sea-orm\",\n \"seaography-macros\",\n \"serde\",\n \"serde_json\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"seaography-macros\"\nversion = \"2.0.0-rc.6\"\nsource = \"git+https://github.com/SeaQL/seaography.git?branch=main#ee380956016e74531015051a31f889e45337a335\"\ndependencies = [\n \"darling 0.21.3\",\n \"heck 0.5.0\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"selectors\"\nversion = \"0.26.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fd568a4c9bb598e291a08244a5c1f5a8a6650bee243b5b0f8dbb3d9cc1d87fe8\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"cssparser\",\n \"derive_more 0.99.20\",\n \"fxhash\",\n \"log\",\n \"new_debug_unreachable\",\n \"phf\",\n \"phf_codegen\",\n \"precomputed-hash\",\n \"servo_arc\",\n \"smallvec\",\n]\n\n[[package]]\nname = \"semver\"\nversion = \"1.0.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2\"\n\n[[package]]\nname = \"serde\"\nversion = \"1.0.228\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e\"\ndependencies = [\n \"serde_core\",\n \"serde_derive\",\n]\n\n[[package]]\nname = \"serde_core\"\nversion = \"1.0.228\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad\"\ndependencies = [\n \"serde_derive\",\n]\n\n[[package]]\nname = \"serde_derive\"\nversion = \"1.0.228\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"serde_json\"\nversion = \"1.0.145\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c\"\ndependencies = [\n \"itoa\",\n \"memchr\",\n \"ryu\",\n \"serde\",\n \"serde_core\",\n]\n\n[[package]]\nname = \"serde_path_to_error\"\nversion = \"0.1.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457\"\ndependencies = [\n \"itoa\",\n \"serde\",\n \"serde_core\",\n]\n\n[[package]]\nname = \"serde_regex\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf\"\ndependencies = [\n \"regex\",\n \"serde\",\n]\n\n[[package]]\nname = \"serde_spanned\"\nversion = \"0.6.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"serde_urlencoded\"\nversion = \"0.7.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd\"\ndependencies = [\n \"form_urlencoded\",\n \"itoa\",\n \"ryu\",\n \"serde\",\n]\n\n[[package]]\nname = \"serde_variant\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0a0068df419f9d9b6488fdded3f1c818522cdea328e02ce9d9f147380265a432\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"serde_yaml\"\nversion = \"0.9.34+deprecated\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47\"\ndependencies = [\n \"indexmap\",\n \"itoa\",\n \"ryu\",\n \"serde\",\n \"unsafe-libyaml\",\n]\n\n[[package]]\nname = \"serial_test\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d\"\ndependencies = [\n \"dashmap 5.5.3\",\n \"futures\",\n \"lazy_static\",\n \"log\",\n \"parking_lot\",\n \"serial_test_derive\",\n]\n\n[[package]]\nname = \"serial_test_derive\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"servo_arc\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"204ea332803bd95a0b60388590d59cf6468ec9becf626e2451f1d26a1d972de4\"\ndependencies = [\n \"stable_deref_trait\",\n]\n\n[[package]]\nname = \"sha1\"\nversion = \"0.10.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba\"\ndependencies = [\n \"cfg-if\",\n \"cpufeatures\",\n \"digest\",\n]\n\n[[package]]\nname = \"sha1_smol\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d\"\n\n[[package]]\nname = \"sha2\"\nversion = \"0.10.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283\"\ndependencies = [\n \"cfg-if\",\n \"cpufeatures\",\n \"digest\",\n]\n\n[[package]]\nname = \"sharded-slab\"\nversion = \"0.1.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6\"\ndependencies = [\n \"lazy_static\",\n]\n\n[[package]]\nname = \"shared_child\"\nversion = \"1.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e362d9935bc50f019969e2f9ecd66786612daae13e8f277be7bfb66e8bed3f7\"\ndependencies = [\n \"libc\",\n \"sigchld\",\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"shared_thread\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"52b86057fcb5423f5018e331ac04623e32d6b5ce85e33300f92c79a1973928b0\"\n\n[[package]]\nname = \"shlex\"\nversion = \"1.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64\"\n\n[[package]]\nname = \"sigchld\"\nversion = \"0.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47106eded3c154e70176fc83df9737335c94ce22f821c32d17ed1db1f83badb1\"\ndependencies = [\n \"libc\",\n \"os_pipe\",\n \"signal-hook\",\n]\n\n[[package]]\nname = \"signal-hook\"\nversion = \"0.3.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2\"\ndependencies = [\n \"libc\",\n \"signal-hook-registry\",\n]\n\n[[package]]\nname = \"signal-hook-registry\"\nversion = \"1.4.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"signature\"\nversion = \"2.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de\"\ndependencies = [\n \"digest\",\n \"rand_core 0.6.4\",\n]\n\n[[package]]\nname = \"simd-adler32\"\nversion = \"0.3.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe\"\n\n[[package]]\nname = \"simdutf8\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e\"\n\n[[package]]\nname = \"similar\"\nversion = \"2.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa\"\n\n[[package]]\nname = \"simple_asn1\"\nversion = \"0.6.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb\"\ndependencies = [\n \"num-bigint\",\n \"num-traits\",\n \"thiserror 2.0.17\",\n \"time\",\n]\n\n[[package]]\nname = \"siphasher\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d\"\n\n[[package]]\nname = \"slab\"\nversion = \"0.4.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589\"\n\n[[package]]\nname = \"slug\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724\"\ndependencies = [\n \"deunicode\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"smallvec\"\nversion = \"1.15.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"socket2\"\nversion = \"0.5.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.52.0\",\n]\n\n[[package]]\nname = \"socket2\"\nversion = \"0.6.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"spin\"\nversion = \"0.9.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67\"\ndependencies = [\n \"lock_api\",\n]\n\n[[package]]\nname = \"spki\"\nversion = \"0.7.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d\"\ndependencies = [\n \"base64ct\",\n \"der\",\n]\n\n[[package]]\nname = \"sqlx\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc\"\ndependencies = [\n \"sqlx-core\",\n \"sqlx-macros\",\n \"sqlx-mysql\",\n \"sqlx-postgres\",\n \"sqlx-sqlite\",\n]\n\n[[package]]\nname = \"sqlx-core\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6\"\ndependencies = [\n \"base64\",\n \"bytes\",\n \"chrono\",\n \"crc\",\n \"crossbeam-queue\",\n \"either\",\n \"event-listener\",\n \"futures-core\",\n \"futures-intrusive\",\n \"futures-io\",\n \"futures-util\",\n \"hashbrown 0.15.5\",\n \"hashlink\",\n \"indexmap\",\n \"log\",\n \"memchr\",\n \"once_cell\",\n \"percent-encoding\",\n \"rust_decimal\",\n \"rustls\",\n \"serde\",\n \"serde_json\",\n \"sha2\",\n \"smallvec\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tokio\",\n \"tokio-stream\",\n \"tracing\",\n \"url\",\n \"uuid\",\n \"webpki-roots 0.26.11\",\n]\n\n[[package]]\nname = \"sqlx-macros\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"sqlx-core\",\n \"sqlx-macros-core\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"sqlx-macros-core\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b\"\ndependencies = [\n \"dotenvy\",\n \"either\",\n \"heck 0.5.0\",\n \"hex\",\n \"once_cell\",\n \"proc-macro2\",\n \"quote\",\n \"serde\",\n \"serde_json\",\n \"sha2\",\n \"sqlx-core\",\n \"sqlx-mysql\",\n \"sqlx-postgres\",\n \"sqlx-sqlite\",\n \"syn 2.0.106\",\n \"tokio\",\n \"url\",\n]\n\n[[package]]\nname = \"sqlx-mysql\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526\"\ndependencies = [\n \"atoi\",\n \"base64\",\n \"bitflags 2.9.4\",\n \"byteorder\",\n \"bytes\",\n \"chrono\",\n \"crc\",\n \"digest\",\n \"dotenvy\",\n \"either\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-io\",\n \"futures-util\",\n \"generic-array\",\n \"hex\",\n \"hkdf\",\n \"hmac\",\n \"itoa\",\n \"log\",\n \"md-5\",\n \"memchr\",\n \"once_cell\",\n \"percent-encoding\",\n \"rand 0.8.5\",\n \"rsa\",\n \"rust_decimal\",\n \"serde\",\n \"sha1\",\n \"sha2\",\n \"smallvec\",\n \"sqlx-core\",\n \"stringprep\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tracing\",\n \"uuid\",\n \"whoami\",\n]\n\n[[package]]\nname = \"sqlx-postgres\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46\"\ndependencies = [\n \"atoi\",\n \"base64\",\n \"bitflags 2.9.4\",\n \"byteorder\",\n \"chrono\",\n \"crc\",\n \"dotenvy\",\n \"etcetera\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-util\",\n \"hex\",\n \"hkdf\",\n \"hmac\",\n \"home\",\n \"itoa\",\n \"log\",\n \"md-5\",\n \"memchr\",\n \"once_cell\",\n \"rand 0.8.5\",\n \"rust_decimal\",\n \"serde\",\n \"serde_json\",\n \"sha2\",\n \"smallvec\",\n \"sqlx-core\",\n \"stringprep\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tracing\",\n \"uuid\",\n \"whoami\",\n]\n\n[[package]]\nname = \"sqlx-sqlite\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea\"\ndependencies = [\n \"atoi\",\n \"chrono\",\n \"flume\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-executor\",\n \"futures-intrusive\",\n \"futures-util\",\n \"libsqlite3-sys\",\n \"log\",\n \"percent-encoding\",\n \"serde\",\n \"serde_urlencoded\",\n \"sqlx-core\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tracing\",\n \"url\",\n \"uuid\",\n]\n\n[[package]]\nname = \"stable_deref_trait\"\nversion = \"1.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3\"\n\n[[package]]\nname = \"stacker\"\nversion = \"0.1.22\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e1f8b29fb42aafcea4edeeb6b2f2d7ecd0d969c48b4cf0d2e64aafc471dd6e59\"\ndependencies = [\n \"cc\",\n \"cfg-if\",\n \"libc\",\n \"psm\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"static_assertions\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f\"\n\n[[package]]\nname = \"static_assertions_next\"\nversion = \"1.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d7beae5182595e9a8b683fa98c4317f956c9a2dec3b9716990d20023cc60c766\"\n\n[[package]]\nname = \"string_cache\"\nversion = \"0.8.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f\"\ndependencies = [\n \"new_debug_unreachable\",\n \"parking_lot\",\n \"phf_shared\",\n \"precomputed-hash\",\n \"serde\",\n]\n\n[[package]]\nname = \"string_cache_codegen\"\nversion = \"0.5.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0\"\ndependencies = [\n \"phf_generator\",\n \"phf_shared\",\n \"proc-macro2\",\n \"quote\",\n]\n\n[[package]]\nname = \"stringprep\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1\"\ndependencies = [\n \"unicode-bidi\",\n \"unicode-normalization\",\n \"unicode-properties\",\n]\n\n[[package]]\nname = \"strsim\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f\"\n\n[[package]]\nname = \"strum\"\nversion = \"0.26.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06\"\ndependencies = [\n \"strum_macros\",\n]\n\n[[package]]\nname = \"strum\"\nversion = \"0.27.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf\"\n\n[[package]]\nname = \"strum_macros\"\nversion = \"0.26.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be\"\ndependencies = [\n \"heck 0.5.0\",\n \"proc-macro2\",\n \"quote\",\n \"rustversion\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"subtle\"\nversion = \"2.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292\"\n\n[[package]]\nname = \"syn\"\nversion = \"1.0.109\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"syn\"\nversion = \"2.0.106\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"sync_wrapper\"\nversion = \"1.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263\"\ndependencies = [\n \"futures-core\",\n]\n\n[[package]]\nname = \"synstructure\"\nversion = \"0.13.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"tagptr\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417\"\n\n[[package]]\nname = \"tap\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369\"\n\n[[package]]\nname = \"tendril\"\nversion = \"0.4.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0\"\ndependencies = [\n \"futf\",\n \"mac\",\n \"utf-8\",\n]\n\n[[package]]\nname = \"tera\"\nversion = \"1.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ab9d851b45e865f178319da0abdbfe6acbc4328759ff18dafc3a41c16b4cd2ee\"\ndependencies = [\n \"chrono\",\n \"chrono-tz\",\n \"globwalk\",\n \"humansize\",\n \"lazy_static\",\n \"percent-encoding\",\n \"pest\",\n \"pest_derive\",\n \"rand 0.8.5\",\n \"regex\",\n \"serde\",\n \"serde_json\",\n \"slug\",\n \"unic-segment\",\n]\n\n[[package]]\nname = \"thiserror\"\nversion = \"1.0.69\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52\"\ndependencies = [\n \"thiserror-impl 1.0.69\",\n]\n\n[[package]]\nname = \"thiserror\"\nversion = \"2.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8\"\ndependencies = [\n \"thiserror-impl 2.0.17\",\n]\n\n[[package]]\nname = \"thiserror-impl\"\nversion = \"1.0.69\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"thiserror-impl\"\nversion = \"2.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"thread_local\"\nversion = \"1.1.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185\"\ndependencies = [\n \"cfg-if\",\n]\n\n[[package]]\nname = \"time\"\nversion = \"0.3.44\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d\"\ndependencies = [\n \"deranged\",\n \"itoa\",\n \"num-conv\",\n \"powerfmt\",\n \"serde\",\n \"time-core\",\n \"time-macros\",\n]\n\n[[package]]\nname = \"time-core\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b\"\n\n[[package]]\nname = \"time-macros\"\nversion = \"0.2.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3\"\ndependencies = [\n \"num-conv\",\n \"time-core\",\n]\n\n[[package]]\nname = \"tinystr\"\nversion = \"0.8.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b\"\ndependencies = [\n \"displaydoc\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"tinyvec\"\nversion = \"1.10.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa\"\ndependencies = [\n \"tinyvec_macros\",\n]\n\n[[package]]\nname = \"tinyvec_macros\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20\"\n\n[[package]]\nname = \"tokio\"\nversion = \"1.47.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038\"\ndependencies = [\n \"backtrace\",\n \"bytes\",\n \"io-uring\",\n \"libc\",\n \"mio\",\n \"pin-project-lite\",\n \"signal-hook-registry\",\n \"slab\",\n \"socket2 0.6.0\",\n \"tokio-macros\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"tokio-cron-scheduler\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f2594dd7c2abbbafbb1c78d167fd10860dc7bd75f814cb051a1e0d3e796b9702\"\ndependencies = [\n \"chrono\",\n \"cron\",\n \"num-derive\",\n \"num-traits\",\n \"tokio\",\n \"tracing\",\n \"uuid\",\n]\n\n[[package]]\nname = \"tokio-macros\"\nversion = \"2.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"tokio-rustls\"\nversion = \"0.26.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61\"\ndependencies = [\n \"rustls\",\n \"tokio\",\n]\n\n[[package]]\nname = \"tokio-stream\"\nversion = \"0.1.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047\"\ndependencies = [\n \"futures-core\",\n \"pin-project-lite\",\n \"tokio\",\n]\n\n[[package]]\nname = \"tokio-tungstenite\"\nversion = \"0.28.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857\"\ndependencies = [\n \"futures-util\",\n \"log\",\n \"tokio\",\n \"tungstenite\",\n]\n\n[[package]]\nname = \"tokio-util\"\nversion = \"0.7.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"futures-io\",\n \"futures-sink\",\n \"pin-project-lite\",\n \"tokio\",\n]\n\n[[package]]\nname = \"toml\"\nversion = \"0.8.23\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362\"\ndependencies = [\n \"serde\",\n \"serde_spanned\",\n \"toml_datetime 0.6.11\",\n \"toml_edit 0.22.27\",\n]\n\n[[package]]\nname = \"toml_datetime\"\nversion = \"0.6.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"toml_datetime\"\nversion = \"0.7.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1\"\ndependencies = [\n \"serde_core\",\n]\n\n[[package]]\nname = \"toml_edit\"\nversion = \"0.22.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a\"\ndependencies = [\n \"indexmap\",\n \"serde\",\n \"serde_spanned\",\n \"toml_datetime 0.6.11\",\n \"toml_write\",\n \"winnow\",\n]\n\n[[package]]\nname = \"toml_edit\"\nversion = \"0.23.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b\"\ndependencies = [\n \"indexmap\",\n \"toml_datetime 0.7.2\",\n \"toml_parser\",\n \"winnow\",\n]\n\n[[package]]\nname = \"toml_parser\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627\"\ndependencies = [\n \"winnow\",\n]\n\n[[package]]\nname = \"toml_write\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801\"\n\n[[package]]\nname = \"tower\"\nversion = \"0.4.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c\"\ndependencies = [\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"tower\"\nversion = \"0.5.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9\"\ndependencies = [\n \"futures-core\",\n \"futures-util\",\n \"pin-project-lite\",\n \"sync_wrapper\",\n \"tokio\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"tower-http\"\nversion = \"0.6.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2\"\ndependencies = [\n \"async-compression\",\n \"bitflags 2.9.4\",\n \"bytes\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"http-range-header\",\n \"httpdate\",\n \"iri-string\",\n \"mime\",\n \"mime_guess\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"tokio\",\n \"tokio-util\",\n \"tower 0.5.2\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"tower-layer\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e\"\n\n[[package]]\nname = \"tower-service\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3\"\n\n[[package]]\nname = \"tracing\"\nversion = \"0.1.41\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0\"\ndependencies = [\n \"log\",\n \"pin-project-lite\",\n \"tracing-attributes\",\n \"tracing-core\",\n]\n\n[[package]]\nname = \"tracing-appender\"\nversion = \"0.2.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf\"\ndependencies = [\n \"crossbeam-channel\",\n \"thiserror 1.0.69\",\n \"time\",\n \"tracing-subscriber\",\n]\n\n[[package]]\nname = \"tracing-attributes\"\nversion = \"0.1.30\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"tracing-core\"\nversion = \"0.1.34\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678\"\ndependencies = [\n \"once_cell\",\n \"valuable\",\n]\n\n[[package]]\nname = \"tracing-log\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3\"\ndependencies = [\n \"log\",\n \"once_cell\",\n \"tracing-core\",\n]\n\n[[package]]\nname = \"tracing-serde\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1\"\ndependencies = [\n \"serde\",\n \"tracing-core\",\n]\n\n[[package]]\nname = \"tracing-subscriber\"\nversion = \"0.3.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5\"\ndependencies = [\n \"matchers\",\n \"nu-ansi-term\",\n \"once_cell\",\n \"regex-automata\",\n \"serde\",\n \"serde_json\",\n \"sharded-slab\",\n \"smallvec\",\n \"thread_local\",\n \"tracing\",\n \"tracing-core\",\n \"tracing-log\",\n \"tracing-serde\",\n]\n\n[[package]]\nname = \"tree-fs\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5c6115680fa5fdb99b4ff19c9c3217e75116d2bb0eae82458c4e1818be6a10c7\"\ndependencies = [\n \"rand 0.9.2\",\n \"serde\",\n]\n\n[[package]]\nname = \"try-lock\"\nversion = \"0.2.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b\"\n\n[[package]]\nname = \"tungstenite\"\nversion = \"0.28.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442\"\ndependencies = [\n \"bytes\",\n \"data-encoding\",\n \"http\",\n \"httparse\",\n \"log\",\n \"rand 0.9.2\",\n \"sha1\",\n \"thiserror 2.0.17\",\n \"utf-8\",\n]\n\n[[package]]\nname = \"typenum\"\nversion = \"1.19.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb\"\n\n[[package]]\nname = \"ucd-trie\"\nversion = \"0.1.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971\"\n\n[[package]]\nname = \"ulid\"\nversion = \"1.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"470dbf6591da1b39d43c14523b2b469c86879a53e8b758c8e090a470fe7b1fbe\"\ndependencies = [\n \"rand 0.9.2\",\n \"web-time\",\n]\n\n[[package]]\nname = \"unic-char-property\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221\"\ndependencies = [\n \"unic-char-range\",\n]\n\n[[package]]\nname = \"unic-char-range\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc\"\n\n[[package]]\nname = \"unic-common\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc\"\n\n[[package]]\nname = \"unic-segment\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23\"\ndependencies = [\n \"unic-ucd-segment\",\n]\n\n[[package]]\nname = \"unic-ucd-segment\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700\"\ndependencies = [\n \"unic-char-property\",\n \"unic-char-range\",\n \"unic-ucd-version\",\n]\n\n[[package]]\nname = \"unic-ucd-version\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4\"\ndependencies = [\n \"unic-common\",\n]\n\n[[package]]\nname = \"unicase\"\nversion = \"2.8.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539\"\n\n[[package]]\nname = \"unicode-bidi\"\nversion = \"0.3.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5\"\n\n[[package]]\nname = \"unicode-ident\"\nversion = \"1.0.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d\"\n\n[[package]]\nname = \"unicode-normalization\"\nversion = \"0.1.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956\"\ndependencies = [\n \"tinyvec\",\n]\n\n[[package]]\nname = \"unicode-properties\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0\"\n\n[[package]]\nname = \"unicode-width\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254\"\n\n[[package]]\nname = \"unicode-xid\"\nversion = \"0.2.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853\"\n\n[[package]]\nname = \"unsafe-libyaml\"\nversion = \"0.2.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861\"\n\n[[package]]\nname = \"untrusted\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1\"\n\n[[package]]\nname = \"url\"\nversion = \"2.5.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b\"\ndependencies = [\n \"form_urlencoded\",\n \"idna\",\n \"percent-encoding\",\n \"serde\",\n]\n\n[[package]]\nname = \"utf-8\"\nversion = \"0.7.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9\"\n\n[[package]]\nname = \"utf8-width\"\nversion = \"0.1.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3\"\n\n[[package]]\nname = \"utf8_iter\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be\"\n\n[[package]]\nname = \"utf8parse\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821\"\n\n[[package]]\nname = \"uuid\"\nversion = \"1.18.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2\"\ndependencies = [\n \"getrandom 0.3.3\",\n \"js-sys\",\n \"rand 0.9.2\",\n \"serde\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"validator\"\nversion = \"0.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"43fb22e1a008ece370ce08a3e9e4447a910e92621bb49b85d6e48a45397e7cfa\"\ndependencies = [\n \"idna\",\n \"once_cell\",\n \"regex\",\n \"serde\",\n \"serde_derive\",\n \"serde_json\",\n \"url\",\n \"validator_derive\",\n]\n\n[[package]]\nname = \"validator_derive\"\nversion = \"0.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b7df16e474ef958526d1205f6dda359fdfab79d9aa6d54bafcb92dcd07673dca\"\ndependencies = [\n \"darling 0.20.11\",\n \"once_cell\",\n \"proc-macro-error2\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"valuable\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65\"\n\n[[package]]\nname = \"vcpkg\"\nversion = \"0.2.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426\"\n\n[[package]]\nname = \"version_check\"\nversion = \"0.9.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a\"\n\n[[package]]\nname = \"walkdir\"\nversion = \"2.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b\"\ndependencies = [\n \"same-file\",\n \"winapi-util\",\n]\n\n[[package]]\nname = \"want\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e\"\ndependencies = [\n \"try-lock\",\n]\n\n[[package]]\nname = \"wasi\"\nversion = \"0.11.1+wasi-snapshot-preview1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b\"\n\n[[package]]\nname = \"wasi\"\nversion = \"0.14.7+wasi-0.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c\"\ndependencies = [\n \"wasip2\",\n]\n\n[[package]]\nname = \"wasip2\"\nversion = \"1.0.1+wasi-0.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7\"\ndependencies = [\n \"wit-bindgen\",\n]\n\n[[package]]\nname = \"wasite\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b\"\n\n[[package]]\nname = \"wasm-bindgen\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d\"\ndependencies = [\n \"cfg-if\",\n \"once_cell\",\n \"rustversion\",\n \"wasm-bindgen-macro\",\n \"wasm-bindgen-shared\",\n]\n\n[[package]]\nname = \"wasm-bindgen-backend\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19\"\ndependencies = [\n \"bumpalo\",\n \"log\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"wasm-bindgen-shared\",\n]\n\n[[package]]\nname = \"wasm-bindgen-futures\"\nversion = \"0.4.54\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c\"\ndependencies = [\n \"cfg-if\",\n \"js-sys\",\n \"once_cell\",\n \"wasm-bindgen\",\n \"web-sys\",\n]\n\n[[package]]\nname = \"wasm-bindgen-macro\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119\"\ndependencies = [\n \"quote\",\n \"wasm-bindgen-macro-support\",\n]\n\n[[package]]\nname = \"wasm-bindgen-macro-support\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"wasm-bindgen-backend\",\n \"wasm-bindgen-shared\",\n]\n\n[[package]]\nname = \"wasm-bindgen-shared\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1\"\ndependencies = [\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"wasm-streams\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65\"\ndependencies = [\n \"futures-util\",\n \"js-sys\",\n \"wasm-bindgen\",\n \"wasm-bindgen-futures\",\n \"web-sys\",\n]\n\n[[package]]\nname = \"web-sys\"\nversion = \"0.3.81\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120\"\ndependencies = [\n \"js-sys\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"web-time\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb\"\ndependencies = [\n \"js-sys\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"webpki-roots\"\nversion = \"0.26.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9\"\ndependencies = [\n \"webpki-roots 1.0.2\",\n]\n\n[[package]]\nname = \"webpki-roots\"\nversion = \"1.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2\"\ndependencies = [\n \"rustls-pki-types\",\n]\n\n[[package]]\nname = \"whoami\"\nversion = \"1.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d\"\ndependencies = [\n \"libredox\",\n \"wasite\",\n]\n\n[[package]]\nname = \"winapi-util\"\nversion = \"0.1.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22\"\ndependencies = [\n \"windows-sys 0.61.2\",\n]\n\n[[package]]\nname = \"windows-core\"\nversion = \"0.62.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb\"\ndependencies = [\n \"windows-implement\",\n \"windows-interface\",\n \"windows-link 0.2.1\",\n \"windows-result\",\n \"windows-strings\",\n]\n\n[[package]]\nname = \"windows-implement\"\nversion = \"0.60.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"windows-interface\"\nversion = \"0.59.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"windows-link\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a\"\n\n[[package]]\nname = \"windows-link\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5\"\n\n[[package]]\nname = \"windows-result\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5\"\ndependencies = [\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"windows-strings\"\nversion = \"0.5.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091\"\ndependencies = [\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.48.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9\"\ndependencies = [\n \"windows-targets 0.48.5\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.52.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d\"\ndependencies = [\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.59.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b\"\ndependencies = [\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.60.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb\"\ndependencies = [\n \"windows-targets 0.53.5\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.61.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc\"\ndependencies = [\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c\"\ndependencies = [\n \"windows_aarch64_gnullvm 0.48.5\",\n \"windows_aarch64_msvc 0.48.5\",\n \"windows_i686_gnu 0.48.5\",\n \"windows_i686_msvc 0.48.5\",\n \"windows_x86_64_gnu 0.48.5\",\n \"windows_x86_64_gnullvm 0.48.5\",\n \"windows_x86_64_msvc 0.48.5\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973\"\ndependencies = [\n \"windows_aarch64_gnullvm 0.52.6\",\n \"windows_aarch64_msvc 0.52.6\",\n \"windows_i686_gnu 0.52.6\",\n \"windows_i686_gnullvm 0.52.6\",\n \"windows_i686_msvc 0.52.6\",\n \"windows_x86_64_gnu 0.52.6\",\n \"windows_x86_64_gnullvm 0.52.6\",\n \"windows_x86_64_msvc 0.52.6\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.53.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3\"\ndependencies = [\n \"windows-link 0.2.1\",\n \"windows_aarch64_gnullvm 0.53.1\",\n \"windows_aarch64_msvc 0.53.1\",\n \"windows_i686_gnu 0.53.1\",\n \"windows_i686_gnullvm 0.53.1\",\n \"windows_i686_msvc 0.53.1\",\n \"windows_x86_64_gnu 0.53.1\",\n \"windows_x86_64_gnullvm 0.53.1\",\n \"windows_x86_64_msvc 0.53.1\",\n]\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8\"\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3\"\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3\"\n\n[[package]]\nname = \"windows_i686_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66\"\n\n[[package]]\nname = \"windows_i686_gnullvm\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650\"\n\n[[package]]\nname = \"winnow\"\nversion = \"0.7.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"wit-bindgen\"\nversion = \"0.46.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59\"\n\n[[package]]\nname = \"writeable\"\nversion = \"0.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb\"\n\n[[package]]\nname = \"wyz\"\nversion = \"0.5.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed\"\ndependencies = [\n \"tap\",\n]\n\n[[package]]\nname = \"yansi\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049\"\n\n[[package]]\nname = \"yoke\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc\"\ndependencies = [\n \"serde\",\n \"stable_deref_trait\",\n \"yoke-derive\",\n \"zerofrom\",\n]\n\n[[package]]\nname = \"yoke-derive\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"synstructure\",\n]\n\n[[package]]\nname = \"zerocopy\"\nversion = \"0.8.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c\"\ndependencies = [\n \"zerocopy-derive\",\n]\n\n[[package]]\nname = \"zerocopy-derive\"\nversion = \"0.8.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"zerofrom\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5\"\ndependencies = [\n \"zerofrom-derive\",\n]\n\n[[package]]\nname = \"zerofrom-derive\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"synstructure\",\n]\n\n[[package]]\nname = \"zeroize\"\nversion = \"1.8.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0\"\n\n[[package]]\nname = \"zerotrie\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595\"\ndependencies = [\n \"displaydoc\",\n \"yoke\",\n \"zerofrom\",\n]\n\n[[package]]\nname = \"zerovec\"\nversion = \"0.11.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b\"\ndependencies = [\n \"yoke\",\n \"zerofrom\",\n \"zerovec-derive\",\n]\n\n[[package]]\nname = \"zerovec-derive\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"zstd\"\nversion = \"0.13.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a\"\ndependencies = [\n \"zstd-safe\",\n]\n\n[[package]]\nname = \"zstd-safe\"\nversion = \"7.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d\"\ndependencies = [\n \"zstd-sys\",\n]\n\n[[package]]\nname = \"zstd-sys\"\nversion = \"2.0.16+zstd.1.5.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748\"\ndependencies = [\n \"cc\",\n \"pkg-config\",\n]\n"
  },
  {
    "path": "examples/loco_seaography/Cargo.toml",
    "content": "[workspace]\n\n[package]\nedition      = \"2024\"\nname         = \"loco_seaography\"\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n\nloco-rs   = { version = \"0.16\" }\nmigration = { path = \"migration\" }\n\nasync-graphql-axum = { version = \"7.0\" }\nasync-trait        = \"0.1.74\"\naxum               = { version = \"0.8\", features = [\"multipart\"] }\nchrono             = \"0.4\"\neyre               = \"0.6\"\ninclude_dir        = \"0.7\"\nlazy_static        = { version = \"1.4\" }\nserde              = { version = \"1\", features = [\"derive\"] }\nserde_json         = \"1\"\ntokio              = { version = \"1.33.0\", default-features = false }\ntokio-util         = \"0.7.11\"\ntower-service      = { version = \"0.3\" }\ntracing            = \"0.1.40\"\ntracing-subscriber = { version = \"0.3.17\", features = [\"env-filter\", \"json\"] }\nuuid               = { version = \"1.6.0\", features = [\"v4\"] }\nvalidator          = { version = \"0.20\" }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"sqlx-sqlite\",\n    \"sqlx-postgres\",\n    \"runtime-tokio-rustls\",\n    \"macros\",\n]\nversion = \"~2.0.0-rc.37\" # sea-orm version\n\n[dependencies.seaography]\nbranch   = \"main\"\nfeatures = [\"graphql-playground\", \"with-decimal\", \"with-chrono\"]\ngit      = \"https://github.com/SeaQL/seaography.git\"\nversion  = \"~2.0.0-rc.1\"                                         # seaography version\n\n[[bin]]\nname              = \"loco_seaography-cli\"\npath              = \"src/bin/main.rs\"\nrequired-features = []\n\n[dev-dependencies]\ninsta       = { version = \"1.34.0\", features = [\"redactions\", \"yaml\", \"filters\"] }\nloco-rs     = { version = \"0.16\", features = [\"testing\"] }\nrstest      = \"0.18.2\"\nserial_test = \"2.0.0\"\n\n[patch.crates-io]\nloco-rs = { git = \"https://github.com/SeaQL/loco\", branch = \"master\" }\n"
  },
  {
    "path": "examples/loco_seaography/README.md",
    "content": "# Adding GraphQL Support to Loco with Seaography\n\nIn this tutorial, we would add a GraphQL endpoint with [Seaography](https://github.com/SeaQL/seaography) based on our Loco starter application.\n\nRead The full tutorial [here](https://www.sea-ql.org/blog/2024-07-01-graphql-support-with-loco-seaography/).\n\nRead our first tutorial of the series, [Getting Started with Loco & SeaORM](https://www.sea-ql.org/blog/2024-05-28-getting-started-with-loco-seaorm/), if you haven't.\n\n![Screenshot Query](Screenshot-Query.png)\n\n![Screenshot Create](Screenshot-Create.png)\n"
  },
  {
    "path": "examples/loco_seaography/config/development.yaml",
    "content": "# Loco configuration file documentation\n\n# Application logging configuration\nlogger:\n  # Enable or disable logging.\n  enable: true\n  # Enable pretty backtrace (sets RUST_BACKTRACE=1)\n  pretty_backtrace: true\n  # Log level, options: trace, debug, info, warn or error.\n  level: debug\n  # Define the logging format. options: compact, pretty or Json\n  format: compact\n  # By default the logger has filtering only logs that came from your code or logs that came from `loco` framework. to see all third party libraries\n  # Uncomment the line below to override to see all third party libraries you can enable this config and override the logger filters.\n  # override_filter: trace\n\n# Web server configuration\nserver:\n  # Port on which the server will listen. the server binding is 0.0.0.0:{PORT}\n  port: 3000\n  # The UI hostname or IP address that mailers will point to.\n  host: http://localhost\n  # Out of the box middleware configuration. to disable middleware you can changed the `enable` field to `false` of comment the middleware block\n  middlewares:\n    # Enable Etag cache header middleware\n    etag:\n      enable: true\n    # Allows to limit the payload size request. payload that bigger than this file will blocked the request.\n    limit_payload:\n      # Enable/Disable the middleware.\n      enable: true\n      # the limit size. can be b,kb,kib,mb,mib,gb,gib\n      body_limit: 5mb\n    # Generating a unique request ID and enhancing logging with additional information such as the start and completion of request processing, latency, status code, and other request details.\n    logger:\n      # Enable/Disable the middleware.\n      enable: true\n    # when your code is panicked, the request still returns 500 status code.\n    catch_panic:\n      # Enable/Disable the middleware.\n      enable: true\n    # Timeout for incoming requests middleware. requests that take more time from the configuration will cute and 408 status code will returned.\n    timeout_request:\n      # Enable/Disable the middleware.\n      enable: false\n      # Duration time in milliseconds.\n      timeout: 5000\n    cors:\n      enable: true\n      # Set the value of the [`Access-Control-Allow-Origin`][mdn] header\n      # allow_origins:\n      #   - https://loco.rs\n      # Set the value of the [`Access-Control-Allow-Headers`][mdn] header\n      # allow_headers:\n      # - Content-Type\n      # Set the value of the [`Access-Control-Allow-Methods`][mdn] header\n      # allow_methods:\n      #   - POST\n      # Set the value of the [`Access-Control-Max-Age`][mdn] header in seconds\n      # max_age: 3600\n\n# Worker Configuration\nworkers:\n  # specifies the worker mode. Options:\n  #   - BackgroundQueue - Workers operate asynchronously in the background, processing queued.\n  #   - ForegroundBlocking - Workers operate in the foreground and block until tasks are completed.\n  #   - BackgroundAsync - Workers operate asynchronously in the background, processing tasks with async capabilities.\n  mode: BackgroundQueue\n\n# Mailer Configuration.\nmailer:\n  # SMTP mailer configuration.\n  smtp:\n    # Enable/Disable smtp mailer.\n    enable: true\n    # SMTP server host. e.x localhost, smtp.gmail.com\n    host: {{ get_env(name=\"MAILER_HOST\", default=\"localhost\") }}\n    # SMTP server port\n    port: 1025\n    # Use secure connection (SSL/TLS).\n    secure: false\n    # auth:\n    #   user:\n    #   password:\n\n# Initializers Configuration\n# initializers:\n#  oauth2:\n#    authorization_code: # Authorization code grant type\n#      - client_identifier: google # Identifier for the OAuth2 provider. Replace 'google' with your provider's name if different, must be unique within the oauth2 config.\n#        ... other fields\n\n# Database Configuration\ndatabase:\n  # Database connection URI\n  uri: {{ get_env(name=\"DATABASE_URL\", default=\"sqlite://loco_seaography.db?mode=rwc\") }}\n  # When enabled, the sql query will be logged.\n  enable_logging: false\n  # Set the timeout duration when acquiring a connection.\n  connect_timeout: 500\n  # Set the idle duration before closing a connection.\n  idle_timeout: 500\n  # Minimum number of connections for a pool.\n  min_connections: 1\n  # Maximum number of connections for a pool.\n  max_connections: 1\n  # Run migration up when application loaded\n  auto_migrate: true\n  # Truncate database when application loaded. This is a dangerous operation, make sure that you using this flag only on dev environments or test mode\n  dangerously_truncate: false\n  # Recreating schema when application loaded.  This is a dangerous operation, make sure that you using this flag only on dev environments or test mode\n  dangerously_recreate: false\n\n# Redis Configuration\nredis:\n  # Redis connection URI\n  uri: {{ get_env(name=\"REDIS_URL\", default=\"redis://127.0.0.1\") }}\n  # Dangerously flush all data in Redis on startup. dangerous operation, make sure that you using this flag only on dev environments or test mode\n  dangerously_flush: false\n\n# Authentication Configuration\nauth:\n  # JWT authentication\n  jwt:\n    # Secret key for token generation and verification\n    secret: pByQUgg4GmXKAqQQvAGo\n    # Token expiration time in seconds\n    expiration: 604800 # 7 days\n\n"
  },
  {
    "path": "examples/loco_seaography/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nloco-rs = { version = \"0.16\" }\ntokio   = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.\n    # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.\n    # e.g.\n    \"runtime-tokio-rustls\", # `ASYNC_RUNTIME` feature\n]\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n\n[patch.crates-io]\nloco-rs = { git = \"https://github.com/SeaQL/loco\", branch = \"master\" }\n"
  },
  {
    "path": "examples/loco_seaography/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Generate a new migration file\n    ```sh\n    cargo run -- migrate generate MIGRATION_NAME\n    ```\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/loco_seaography/migration/src/lib.rs",
    "content": "#![allow(elided_lifetimes_in_paths)]\n#![allow(clippy::wildcard_imports)]\npub use sea_orm_migration::prelude::*;\n\nmod m20220101_000001_users;\nmod m20231103_114510_notes;\nmod m20240520_173001_files;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220101_000001_users::Migration),\n            Box::new(m20231103_114510_notes::Migration),\n            Box::new(m20240520_173001_files::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/migration/src/m20220101_000001_users.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let table = table_auto(\"users\")\n            .col(pk_auto(\"id\"))\n            .col(uuid(\"pid\"))\n            .col(string_uniq(\"email\"))\n            .col(string(\"password\"))\n            .col(string(\"api_key\").unique_key())\n            .col(string(\"name\"))\n            .col(string_null(\"reset_token\"))\n            .col(timestamp_null(\"reset_sent_at\"))\n            .col(string_null(\"email_verification_token\"))\n            .col(timestamp_null(\"email_verification_sent_at\"))\n            .col(timestamp_null(\"email_verified_at\"))\n            .to_owned();\n        manager.create_table(table).await?;\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"users\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/migration/src/m20231103_114510_notes.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                table_auto(\"notes\")\n                    .col(pk_auto(\"id\"))\n                    .col(string_null(\"title\"))\n                    .col(string_null(\"content\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"notes\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/migration/src/m20240520_173001_files.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                table_auto(\"files\")\n                    .col(pk_auto(\"id\"))\n                    .col(integer(\"notes_id\"))\n                    .col(string(\"file_path\"))\n                    .foreign_key(\n                        ForeignKey::create()\n                            .name(\"FK_files_notes_id\")\n                            .from(\"files\", \"notes_id\")\n                            .to(\"notes\", \"id\"),\n                    )\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"files\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/app.rs",
    "content": "use std::path::Path;\n\nuse async_trait::async_trait;\nuse loco_rs::{\n    Result,\n    app::{AppContext, Hooks, Initializer},\n    bgworker::{BackgroundWorker, Queue},\n    boot::{BootResult, StartMode, create_app},\n    config::Config,\n    controller::AppRoutes,\n    db::{self, truncate_table},\n    environment::Environment,\n    task::Tasks,\n};\nuse migration::Migrator;\n\nuse crate::{\n    controllers, initializers,\n    models::_entities::{notes, users},\n    tasks,\n    workers::downloader::DownloadWorker,\n};\n\npub struct App;\n#[async_trait]\nimpl Hooks for App {\n    fn app_name() -> &'static str {\n        env!(\"CARGO_CRATE_NAME\")\n    }\n\n    fn app_version() -> String {\n        format!(\n            \"{} ({})\",\n            env!(\"CARGO_PKG_VERSION\"),\n            option_env!(\"BUILD_SHA\")\n                .or(option_env!(\"GITHUB_SHA\"))\n                .unwrap_or(\"dev\")\n        )\n    }\n\n    async fn boot(\n        mode: StartMode,\n        environment: &Environment,\n        config: Config,\n    ) -> Result<BootResult> {\n        create_app::<Self, Migrator>(mode, environment, config).await\n    }\n\n    async fn initializers(_ctx: &AppContext) -> Result<Vec<Box<dyn Initializer>>> {\n        let initializers: Vec<Box<dyn Initializer>> =\n            vec![Box::new(initializers::graphql::GraphQLInitializer)];\n\n        Ok(initializers)\n    }\n\n    fn routes(_ctx: &AppContext) -> AppRoutes {\n        AppRoutes::with_default_routes()\n            .prefix(\"/api\")\n            .add_route(controllers::notes::routes())\n            .add_route(controllers::auth::routes())\n            .add_route(controllers::user::routes())\n            .add_route(controllers::files::routes())\n            .add_route(controllers::graphql::routes())\n    }\n\n    async fn connect_workers(ctx: &AppContext, queue: &Queue) -> Result<()> {\n        queue.register(DownloadWorker::build(ctx)).await?;\n        Ok(())\n    }\n\n    fn register_tasks(tasks: &mut Tasks) {\n        tasks.register(tasks::seed::SeedData);\n    }\n\n    async fn truncate(ctx: &AppContext) -> Result<()> {\n        let db = &ctx.db;\n        truncate_table(db, users::Entity).await?;\n        truncate_table(db, notes::Entity).await?;\n        Ok(())\n    }\n\n    async fn seed(ctx: &AppContext, base: &Path) -> Result<()> {\n        let db = &ctx.db;\n        db::seed::<users::ActiveModel>(db, &base.join(\"users.yaml\").display().to_string()).await?;\n        db::seed::<notes::ActiveModel>(db, &base.join(\"notes.yaml\").display().to_string()).await?;\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/bin/main.rs",
    "content": "use loco_rs::cli;\nuse loco_seaography::app::App;\nuse migration::Migrator;\n\n#[tokio::main]\nasync fn main() -> eyre::Result<()> {\n    cli::main::<App, Migrator>().await?;\n    Ok(())\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/controllers/auth.rs",
    "content": "use axum::debug_handler;\nuse loco_rs::prelude::*;\nuse serde::{Deserialize, Serialize};\n\nuse crate::{\n    mailers::auth::AuthMailer,\n    models::{\n        _entities::users,\n        users::{LoginParams, RegisterParams},\n    },\n    views::auth::LoginResponse,\n};\n#[derive(Debug, Deserialize, Serialize)]\npub struct VerifyParams {\n    pub token: String,\n}\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct ForgotParams {\n    pub email: String,\n}\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct ResetParams {\n    pub token: String,\n    pub password: String,\n}\n\n/// Register function creates a new user with the given parameters and sends a\n/// welcome email to the user\n#[debug_handler]\nasync fn register(\n    State(ctx): State<AppContext>,\n    Json(params): Json<RegisterParams>,\n) -> Result<Response> {\n    let res = users::Model::create_with_password(&ctx.db, &params).await;\n\n    let user = match res {\n        Ok(user) => user,\n        Err(err) => {\n            tracing::info!(\n                message = err.to_string(),\n                user_email = &params.email,\n                \"could not register user\",\n            );\n            return format::json(());\n        }\n    };\n\n    // Skip email verification, all new registrations are considered verified\n    let _user = user.into_active_model().verified(&ctx.db).await?;\n\n    // Skip sending verification email as we don't have a mail server\n    /*\n    let user = user\n        .into_active_model()\n        .set_email_verification_sent(&ctx.db)\n        .await?;\n\n    AuthMailer::send_welcome(&ctx, &user).await?;\n    */\n\n    format::json(())\n}\n\n/// Verify register user. if the user not verified his email, he can't login to\n/// the system.\n#[debug_handler]\nasync fn verify(\n    State(ctx): State<AppContext>,\n    Json(params): Json<VerifyParams>,\n) -> Result<Response> {\n    let user = users::Model::find_by_verification_token(&ctx.db, &params.token).await?;\n\n    if user.email_verified_at.is_some() {\n        tracing::info!(pid = user.pid.to_string(), \"user already verified\");\n    } else {\n        let active_model = user.into_active_model();\n        let user = active_model.verified(&ctx.db).await?;\n        tracing::info!(pid = user.pid.to_string(), \"user verified\");\n    }\n\n    format::json(())\n}\n\n/// In case the user forgot his password  this endpoints generate a forgot token\n/// and send email to the user. In case the email not found in our DB, we are\n/// returning a valid request for for security reasons (not exposing users DB\n/// list).\n#[debug_handler]\nasync fn forgot(\n    State(ctx): State<AppContext>,\n    Json(params): Json<ForgotParams>,\n) -> Result<Response> {\n    let Ok(user) = users::Model::find_by_email(&ctx.db, &params.email).await else {\n        // we don't want to expose our users email. if the email is invalid we still\n        // returning success to the caller\n        return format::json(());\n    };\n\n    let user = user\n        .into_active_model()\n        .set_forgot_password_sent(&ctx.db)\n        .await?;\n\n    AuthMailer::forgot_password(&ctx, &user).await?;\n\n    format::json(())\n}\n\n/// reset user password by the given parameters\n#[debug_handler]\nasync fn reset(State(ctx): State<AppContext>, Json(params): Json<ResetParams>) -> Result<Response> {\n    let Ok(user) = users::Model::find_by_reset_token(&ctx.db, &params.token).await else {\n        // we don't want to expose our users email. if the email is invalid we still\n        // returning success to the caller\n        tracing::info!(\"reset token not found\");\n\n        return format::json(());\n    };\n    user.into_active_model()\n        .reset_password(&ctx.db, &params.password)\n        .await?;\n\n    format::json(())\n}\n\n/// Creates a user login and returns a token\n#[debug_handler]\nasync fn login(State(ctx): State<AppContext>, Json(params): Json<LoginParams>) -> Result<Response> {\n    let user = users::Model::find_by_email(&ctx.db, &params.email).await?;\n\n    let valid = user.verify_password(&params.password);\n\n    if !valid {\n        return unauthorized(\"unauthorized!\");\n    }\n\n    let jwt_secret = ctx.config.get_jwt_config()?;\n\n    let token = user\n        .generate_jwt(&jwt_secret.secret, &jwt_secret.expiration)\n        .or_else(|_| unauthorized(\"unauthorized!\"))?;\n\n    format::json(LoginResponse::new(&user, &token))\n}\n\npub fn routes() -> Routes {\n    Routes::new()\n        .prefix(\"auth\")\n        .add(\"/register\", post(register))\n        .add(\"/verify\", post(verify))\n        .add(\"/login\", post(login))\n        .add(\"/forgot\", post(forgot))\n        .add(\"/reset\", post(reset))\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/controllers/files.rs",
    "content": "#![allow(clippy::missing_errors_doc)]\n#![allow(clippy::unnecessary_struct_initialization)]\n#![allow(clippy::unused_async)]\nuse std::path::PathBuf;\n\nuse axum::{body::Body, debug_handler, extract::Multipart};\nuse loco_rs::prelude::*;\nuse sea_orm::QueryOrder;\nuse tokio::{fs, io::AsyncWriteExt};\nuse tokio_util::io::ReaderStream;\n\nuse crate::models::_entities::files;\n\nconst UPLOAD_DIR: &str = \"./uploads\";\n\n#[debug_handler]\npub async fn upload(\n    _auth: auth::JWT,\n    Path(notes_id): Path<i32>,\n    State(ctx): State<AppContext>,\n    mut multipart: Multipart,\n) -> Result<Response> {\n    // Collect all uploaded files\n    let mut files = Vec::new();\n\n    // Iterate all files in the POST body\n    while let Some(field) = multipart.next_field().await.map_err(|err| {\n        tracing::error!(error = ?err,\"could not readd multipart\");\n        Error::BadRequest(\"could not readd multipart\".into())\n    })? {\n        // Get the file name\n        let file_name = match field.file_name() {\n            Some(file_name) => file_name.to_string(),\n            _ => return Err(Error::BadRequest(\"file name not found\".into())),\n        };\n\n        // Get the file content as bytes\n        let content = field.bytes().await.map_err(|err| {\n            tracing::error!(error = ?err,\"could not readd bytes\");\n            Error::BadRequest(\"could not readd bytes\".into())\n        })?;\n\n        // Create a folder to store the uploaded file\n        let now = chrono::offset::Local::now()\n            .format(\"%Y%m%d_%H%M%S\")\n            .to_string();\n        let uuid = uuid::Uuid::new_v4().to_string();\n        let folder = format!(\"{now}_{uuid}\");\n        let upload_folder = PathBuf::from(UPLOAD_DIR).join(&folder);\n        fs::create_dir_all(&upload_folder).await?;\n\n        // Write the file into the newly created folder\n        let path = upload_folder.join(file_name);\n        let mut f = fs::OpenOptions::new()\n            .create_new(true)\n            .write(true)\n            .open(&path)\n            .await?;\n        f.write_all(&content).await?;\n        f.flush().await?;\n\n        // Record the file upload in database\n        let file = files::ActiveModel {\n            notes_id: ActiveValue::Set(notes_id),\n            file_path: ActiveValue::Set(\n                path.strip_prefix(UPLOAD_DIR)\n                    .unwrap()\n                    .to_str()\n                    .unwrap()\n                    .to_string(),\n            ),\n            ..Default::default()\n        }\n        .insert(&ctx.db)\n        .await?;\n\n        files.push(file);\n    }\n\n    format::json(files)\n}\n\n#[debug_handler]\npub async fn list(\n    _auth: auth::JWT,\n    Path(notes_id): Path<i32>,\n    State(ctx): State<AppContext>,\n) -> Result<Response> {\n    // Fetch all files uploaded for a specific notes\n    let files = files::Entity::find()\n        .filter(files::Column::NotesId.eq(notes_id))\n        .order_by_asc(files::Column::Id)\n        .all(&ctx.db)\n        .await?;\n\n    format::json(files)\n}\n\n#[debug_handler]\npub async fn view(\n    _auth: auth::JWT,\n    Path(files_id): Path<i32>,\n    State(ctx): State<AppContext>,\n) -> Result<Response> {\n    // Fetch the file info from database\n    let file = files::Entity::find_by_id(files_id)\n        .one(&ctx.db)\n        .await?\n        .expect(\"File not found\");\n\n    // Stream the file\n    let file = fs::File::open(format!(\"{UPLOAD_DIR}/{}\", file.file_path)).await?;\n    let stream = ReaderStream::new(file);\n    let body = Body::from_stream(stream);\n\n    Ok(format::render().response().body(body)?)\n}\n\npub fn routes() -> Routes {\n    // Bind the routes\n    Routes::new()\n        .prefix(\"files\")\n        .add(\"/upload/{notes_id}\", post(upload))\n        .add(\"/list/{notes_id}\", get(list))\n        .add(\"/view/{files_id}\", get(view))\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/controllers/graphql.rs",
    "content": "use async_graphql::{\n    dynamic::Schema,\n    http::{GraphQLPlaygroundConfig, playground_source},\n};\nuse async_graphql_axum::GraphQLRequest;\nuse loco_rs::prelude::*;\nuse seaography::async_graphql;\n\n// GraphQL playground UI\nasync fn graphql_playground() -> Result<Response> {\n    // The `GraphQLPlaygroundConfig` take one parameter\n    // which is the URL of the GraphQL handler: `/api/graphql`\n    let res = playground_source(GraphQLPlaygroundConfig::new(\"/api/graphql\"));\n\n    Ok(Response::new(res.into()))\n}\n\nasync fn graphql_handler(\n    // _auth: auth::JWT,\n    State(ctx): State<AppContext>,\n    gql_req: GraphQLRequest,\n) -> Result<async_graphql_axum::GraphQLResponse, (axum::http::StatusCode, &'static str)> {\n    let gql_req = gql_req.into_inner();\n\n    let schema: Schema = ctx.shared_store.get().ok_or((\n        axum::http::StatusCode::INTERNAL_SERVER_ERROR,\n        \"GraphQL not setup\",\n    ))?;\n    let res = schema.execute(gql_req).await.into();\n\n    Ok(res)\n}\n\npub fn routes() -> Routes {\n    // Define route\n    Routes::new()\n        // We put all GraphQL route behind `graphql` prefix\n        .prefix(\"graphql\")\n        // GraphQL playground page is a GET request\n        .add(\"/\", get(graphql_playground))\n        // GraphQL handler is a POST request\n        .add(\"/\", post(graphql_handler))\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/controllers/mod.rs",
    "content": "pub mod auth;\npub mod files;\npub mod graphql;\npub mod notes;\npub mod user;\n"
  },
  {
    "path": "examples/loco_seaography/src/controllers/notes.rs",
    "content": "#![allow(clippy::missing_errors_doc)]\n#![allow(clippy::unnecessary_struct_initialization)]\n#![allow(clippy::unused_async)]\nuse axum::debug_handler;\nuse loco_rs::prelude::*;\nuse serde::{Deserialize, Serialize};\n\nuse crate::models::_entities::notes::{ActiveModel, Entity, Model};\n\n#[derive(Clone, Debug, Serialize, Deserialize)]\npub struct Params {\n    pub title: Option<String>,\n    pub content: Option<String>,\n}\n\nimpl Params {\n    fn update(&self, item: &mut ActiveModel) {\n        item.title = Set(self.title.clone());\n        item.content = Set(self.content.clone());\n    }\n}\n\nasync fn load_item(ctx: &AppContext, id: i32) -> Result<Model> {\n    let item = Entity::find_by_id(id).one(&ctx.db).await?;\n    item.ok_or_else(|| Error::NotFound)\n}\n\n#[debug_handler]\npub async fn list(State(ctx): State<AppContext>) -> Result<Response> {\n    format::json(Entity::find().all(&ctx.db).await?)\n}\n\n#[debug_handler]\npub async fn add(State(ctx): State<AppContext>, Json(params): Json<Params>) -> Result<Response> {\n    let mut item = ActiveModel {\n        ..Default::default()\n    };\n    params.update(&mut item);\n    let item = item.insert(&ctx.db).await?;\n    format::json(item)\n}\n\n#[debug_handler]\npub async fn update(\n    Path(id): Path<i32>,\n    State(ctx): State<AppContext>,\n    Json(params): Json<Params>,\n) -> Result<Response> {\n    let item = load_item(&ctx, id).await?;\n    let mut item = item.into_active_model();\n    params.update(&mut item);\n    let item = item.update(&ctx.db).await?;\n    format::json(item)\n}\n\n#[debug_handler]\npub async fn remove(Path(id): Path<i32>, State(ctx): State<AppContext>) -> Result<Response> {\n    load_item(&ctx, id).await?.delete(&ctx.db).await?;\n    format::empty()\n}\n\n#[debug_handler]\npub async fn get_one(Path(id): Path<i32>, State(ctx): State<AppContext>) -> Result<Response> {\n    format::json(load_item(&ctx, id).await?)\n}\n\npub fn routes() -> Routes {\n    Routes::new()\n        .prefix(\"notes\")\n        .add(\"/\", get(list))\n        .add(\"/\", post(add))\n        .add(\"/{id}\", get(get_one))\n        .add(\"/{id}\", delete(remove))\n        .add(\"/{id}\", post(update))\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/controllers/user.rs",
    "content": "use axum::debug_handler;\nuse loco_rs::prelude::*;\n\nuse crate::{models::_entities::users, views::user::CurrentResponse};\n\n#[debug_handler]\nasync fn current(auth: auth::JWT, State(ctx): State<AppContext>) -> Result<Response> {\n    let user = users::Model::find_by_pid(&ctx.db, &auth.claims.pid).await?;\n    format::json(CurrentResponse::new(&user))\n}\n\npub fn routes() -> Routes {\n    Routes::new().prefix(\"user\").add(\"/current\", get(current))\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/fixtures/notes.yaml",
    "content": "---\n- id: 1\n  title: Loco note 1\n  content: Loco note 1 content\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n- id: 2\n  title: Loco note 2\n  content: Loco note 2 content\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n"
  },
  {
    "path": "examples/loco_seaography/src/fixtures/users.yaml",
    "content": "---\n- id: 1\n  pid: 11111111-1111-1111-1111-111111111111\n  email: user1@example.com\n  password: \"$argon2id$v=19$m=19456,t=2,p=1$ETQBx4rTgNAZhSaeYZKOZg$eYTdH26CRT6nUJtacLDEboP0li6xUwUF/q5nSlQ8uuc\"\n  api_key: lo-95ec80d7-cb60-4b70-9b4b-9ef74cb88758\n  name: user1\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n- id: 2\n  pid: 22222222-2222-2222-2222-222222222222\n  email: user2@example.com\n  password: \"$argon2id$v=19$m=19456,t=2,p=1$ETQBx4rTgNAZhSaeYZKOZg$eYTdH26CRT6nUJtacLDEboP0li6xUwUF/q5nSlQ8uuc\"\n  api_key: lo-153561ca-fa84-4e1b-813a-c62526d0a77e\n  name: user2\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n"
  },
  {
    "path": "examples/loco_seaography/src/graphql/mod.rs",
    "content": "pub mod query_root;\n"
  },
  {
    "path": "examples/loco_seaography/src/graphql/query_root.rs",
    "content": "use async_graphql::dynamic::*;\nuse sea_orm::DatabaseConnection;\nuse seaography::{Builder, BuilderContext, async_graphql};\n\nlazy_static::lazy_static! { static ref CONTEXT: BuilderContext = BuilderContext::default(); }\n\npub fn schema(\n    database: DatabaseConnection,\n    depth: Option<usize>,\n    complexity: Option<usize>,\n) -> Result<Schema, SchemaError> {\n    // Construct GraphQL schema\n    let builder = Builder::new(&CONTEXT, database.clone());\n    // Register SeaORM Entities\n    let builder = crate::models::_entities::register_entity_modules(builder);\n    builder\n        // Maximum depth of the constructed query\n        .set_depth_limit(depth)\n        // Maximum complexity of the constructed query\n        .set_complexity_limit(complexity)\n        .schema_builder()\n        // GraphQL schema with database connection\n        .data(database)\n        .finish()\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/initializers/graphql.rs",
    "content": "use crate::graphql::query_root;\nuse async_trait::async_trait;\nuse axum::Router as AxumRouter;\nuse loco_rs::prelude::*;\n\n// Maximum depth of the constructed query\nconst DEPTH: Option<usize> = None;\n// Maximum complexity of the constructed query\nconst COMPLEXITY: Option<usize> = None;\n\npub struct GraphQLInitializer;\n\n#[async_trait]\nimpl Initializer for GraphQLInitializer {\n    fn name(&self) -> String {\n        \"graphql\".to_string()\n    }\n\n    async fn after_routes(&self, router: AxumRouter, ctx: &AppContext) -> Result<AxumRouter> {\n        let schema = query_root::schema(ctx.db.clone(), DEPTH, COMPLEXITY)\n            .expect(\"Failed to build GraphQL schema\");\n        ctx.shared_store.insert(schema);\n\n        Ok(router)\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/initializers/mod.rs",
    "content": "pub mod graphql;\n"
  },
  {
    "path": "examples/loco_seaography/src/lib.rs",
    "content": "pub mod app;\npub mod controllers;\npub mod graphql;\npub mod initializers;\npub mod mailers;\npub mod models;\npub mod tasks;\npub mod views;\npub mod workers;\n"
  },
  {
    "path": "examples/loco_seaography/src/mailers/auth/forgot/html.t",
    "content": ";<html>\n\n<body>\n  Hey {{name}},\n  Forgot your password? No worries! You can reset it by clicking the link below:\n  <a href=\"http://{{domain}}/reset#{{resetToken}}\">Reset Your Password</a>\n  If you didn't request a password reset, please ignore this email.\n  Best regards,<br>The Loco Team</br>\n</body>\n\n</html>\n"
  },
  {
    "path": "examples/loco_seaography/src/mailers/auth/forgot/subject.t",
    "content": "Your reset password link\n"
  },
  {
    "path": "examples/loco_seaography/src/mailers/auth/forgot/text.t",
    "content": "Reset your password with this link:\n\nhttp://localhost/reset#{{resetToken}}\n"
  },
  {
    "path": "examples/loco_seaography/src/mailers/auth/welcome/html.t",
    "content": ";<html>\n\n<body>\n  Dear {{name}},\n  Welcome to Loco! You can now log in to your account.\n  Before you get started, please verify your account by clicking the link below:\n  <a href=\"http://{{domain}}/verify#{{verifyToken}}\">\n    Verify Your Account\n  </a>\n  <p>Best regards,<br>The Loco Team</p>\n</body>\n\n</html>\n"
  },
  {
    "path": "examples/loco_seaography/src/mailers/auth/welcome/subject.t",
    "content": "Welcome {{name}}\n"
  },
  {
    "path": "examples/loco_seaography/src/mailers/auth/welcome/text.t",
    "content": "Welcome {{name}}, you can now log in.\n  Verify your account with the link below:\n\n  http://localhost/verify#{{verifyToken}}\n"
  },
  {
    "path": "examples/loco_seaography/src/mailers/auth.rs",
    "content": "// auth mailer\n#![allow(non_upper_case_globals)]\n\nuse loco_rs::prelude::*;\nuse serde_json::json;\n\nuse crate::models::users;\n\nstatic welcome: Dir<'_> = include_dir!(\"src/mailers/auth/welcome\");\nstatic forgot: Dir<'_> = include_dir!(\"src/mailers/auth/forgot\");\n// #[derive(Mailer)] // -- disabled for faster build speed. it works. but lets\n// move on for now.\n\n#[allow(clippy::module_name_repetitions)]\npub struct AuthMailer {}\nimpl Mailer for AuthMailer {}\nimpl AuthMailer {\n    /// Sending welcome email the the given user\n    ///\n    /// # Errors\n    ///\n    /// When email sending is failed\n    pub async fn send_welcome(ctx: &AppContext, user: &users::Model) -> Result<()> {\n        Self::mail_template(\n            ctx,\n            &welcome,\n            mailer::Args {\n                to: user.email.to_string(),\n                locals: json!({\n                  \"name\": user.name,\n                  \"verifyToken\": user.email_verification_token,\n                  \"domain\": ctx.config.server.full_url()\n                }),\n                ..Default::default()\n            },\n        )\n        .await?;\n\n        Ok(())\n    }\n\n    /// Sending forgot password email\n    ///\n    /// # Errors\n    ///\n    /// When email sending is failed\n    pub async fn forgot_password(ctx: &AppContext, user: &users::Model) -> Result<()> {\n        Self::mail_template(\n            ctx,\n            &forgot,\n            mailer::Args {\n                to: user.email.to_string(),\n                locals: json!({\n                  \"name\": user.name,\n                  \"resetToken\": user.reset_token,\n                  \"domain\": ctx.config.server.full_url()\n                }),\n                ..Default::default()\n            },\n        )\n        .await?;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/mailers/mod.rs",
    "content": "pub mod auth;\n"
  },
  {
    "path": "examples/loco_seaography/src/models/_entities/files.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.10\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"files\")]\npub struct Model {\n    pub created_at: DateTime,\n    pub updated_at: DateTime,\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub notes_id: i32,\n    pub file_path: String,\n    #[sea_orm(belongs_to, from = \"notes_id\", to = \"id\")]\n    pub notes: HasOne<super::notes::Entity>,\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/models/_entities/mod.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.0-rc.5\n\npub mod prelude;\n\npub mod files;\npub mod notes;\npub mod users;\n\nseaography::register_entity_modules!([files, notes, users]);\n"
  },
  {
    "path": "examples/loco_seaography/src/models/_entities/notes.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.10\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"notes\")]\npub struct Model {\n    pub created_at: DateTime,\n    pub updated_at: DateTime,\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub title: Option<String>,\n    pub content: Option<String>,\n    #[sea_orm(has_many)]\n    pub files: HasMany<super::files::Entity>,\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/models/_entities/prelude.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.0-rc.5\n\npub use super::{files::Entity as Files, notes::Entity as Notes, users::Entity as Users};\n"
  },
  {
    "path": "examples/loco_seaography/src/models/_entities/users.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.0-rc.5\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"users\")]\npub struct Model {\n    pub created_at: DateTime,\n    pub updated_at: DateTime,\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub pid: Uuid,\n    #[sea_orm(unique)]\n    pub email: String,\n    pub password: String,\n    #[sea_orm(unique)]\n    pub api_key: String,\n    pub name: String,\n    pub reset_token: Option<String>,\n    pub reset_sent_at: Option<DateTime>,\n    pub email_verification_token: Option<String>,\n    pub email_verification_sent_at: Option<DateTime>,\n    pub email_verified_at: Option<DateTime>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]\npub enum RelatedEntity {}\n"
  },
  {
    "path": "examples/loco_seaography/src/models/files.rs",
    "content": "use sea_orm::entity::prelude::*;\n\nuse super::_entities::files::ActiveModel;\n\nimpl ActiveModelBehavior for ActiveModel {\n    // extend activemodel below (keep comment for generators)\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/models/mod.rs",
    "content": "pub mod _entities;\npub mod files;\npub mod notes;\npub mod users;\n"
  },
  {
    "path": "examples/loco_seaography/src/models/notes.rs",
    "content": "use sea_orm::entity::prelude::*;\n\nuse super::_entities::notes::ActiveModel;\n\nimpl ActiveModelBehavior for ActiveModel {\n    // extend activemodel below (keep comment for generators)\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/models/users.rs",
    "content": "use async_trait::async_trait;\nuse chrono::offset::Local;\nuse loco_rs::{auth::jwt, hash, prelude::*};\nuse serde::{Deserialize, Serialize};\nuse uuid::Uuid;\n\npub use super::_entities::users::{self, ActiveModel, Entity, Model};\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct LoginParams {\n    pub email: String,\n    pub password: String,\n}\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct RegisterParams {\n    pub email: String,\n    pub password: String,\n    pub name: String,\n}\n\n#[derive(Debug, Validate, Deserialize)]\npub struct Validator {\n    #[validate(length(min = 2, message = \"Name must be at least 2 characters long.\"))]\n    pub name: String,\n    #[validate(email(message = \"invalid email\"))]\n    pub email: String,\n}\n\nimpl Validatable for super::_entities::users::ActiveModel {\n    fn validator(&self) -> Box<dyn Validate> {\n        Box::new(Validator {\n            name: self.name.as_ref().to_owned(),\n            email: self.email.as_ref().to_owned(),\n        })\n    }\n}\n\n#[async_trait::async_trait]\nimpl ActiveModelBehavior for super::_entities::users::ActiveModel {\n    async fn before_save<C>(self, _db: &C, insert: bool) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.validate()?;\n        if insert {\n            let mut this = self;\n            this.pid = ActiveValue::Set(Uuid::new_v4());\n            this.api_key = ActiveValue::Set(format!(\"lo-{}\", Uuid::new_v4()));\n            Ok(this)\n        } else {\n            Ok(self)\n        }\n    }\n}\n\n#[async_trait]\nimpl Authenticable for super::_entities::users::Model {\n    async fn find_by_api_key(db: &DatabaseConnection, api_key: &str) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::ApiKey.eq(api_key))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    async fn find_by_claims_key(db: &DatabaseConnection, claims_key: &str) -> ModelResult<Self> {\n        Self::find_by_pid(db, claims_key).await\n    }\n}\n\nimpl super::_entities::users::Model {\n    /// finds a user by the provided email\n    ///\n    /// # Errors\n    ///\n    /// When could not find user by the given token or DB query error\n    pub async fn find_by_email(db: &DatabaseConnection, email: &str) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::Email.eq(email))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// finds a user by the provided verification token\n    ///\n    /// # Errors\n    ///\n    /// When could not find user by the given token or DB query error\n    pub async fn find_by_verification_token(\n        db: &DatabaseConnection,\n        token: &str,\n    ) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::EmailVerificationToken.eq(token))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// /// finds a user by the provided reset token\n    ///\n    /// # Errors\n    ///\n    /// When could not find user by the given token or DB query error\n    pub async fn find_by_reset_token(db: &DatabaseConnection, token: &str) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::ResetToken.eq(token))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// finds a user by the provided pid\n    ///\n    /// # Errors\n    ///\n    /// When could not find user  or DB query error\n    pub async fn find_by_pid(db: &DatabaseConnection, pid: &str) -> ModelResult<Self> {\n        let parse_uuid = Uuid::parse_str(pid).map_err(|e| ModelError::Any(e.into()))?;\n        let user = users::Entity::find()\n            .filter(users::Column::Pid.eq(parse_uuid))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// finds a user by the provided api key\n    ///\n    /// # Errors\n    ///\n    /// When could not find user by the given token or DB query error\n    pub async fn find_by_api_key(db: &DatabaseConnection, api_key: &str) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::ApiKey.eq(api_key))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// Verifies whether the provided plain password matches the hashed password\n    ///\n    /// # Errors\n    ///\n    /// when could not verify password\n    #[must_use]\n    pub fn verify_password(&self, password: &str) -> bool {\n        hash::verify_password(password, &self.password)\n    }\n\n    /// Asynchronously creates a user with a password and saves it to the\n    /// database.\n    ///\n    /// # Errors\n    ///\n    /// When could not save the user into the DB\n    pub async fn create_with_password(\n        db: &DatabaseConnection,\n        params: &RegisterParams,\n    ) -> ModelResult<Self> {\n        let txn = db.begin().await?;\n\n        if users::Entity::find()\n            .filter(users::Column::Email.eq(&params.email))\n            .one(&txn)\n            .await?\n            .is_some()\n        {\n            return Err(ModelError::EntityAlreadyExists {});\n        }\n\n        let password_hash =\n            hash::hash_password(&params.password).map_err(|e| ModelError::Any(e.into()))?;\n        let user = users::ActiveModel {\n            email: ActiveValue::set(params.email.to_string()),\n            password: ActiveValue::set(password_hash),\n            name: ActiveValue::set(params.name.to_string()),\n            ..Default::default()\n        }\n        .insert(&txn)\n        .await?;\n\n        txn.commit().await?;\n\n        Ok(user)\n    }\n\n    /// Creates a JWT\n    ///\n    /// # Errors\n    ///\n    /// when could not convert user claims to jwt token\n    pub fn generate_jwt(&self, secret: &str, expiration: &u64) -> ModelResult<String> {\n        Ok(jwt::JWT::new(secret).generate_token(\n            *expiration,\n            self.pid.to_string(),\n            Default::default(),\n        )?)\n    }\n}\n\nimpl super::_entities::users::ActiveModel {\n    /// Sets the email verification information for the user and\n    /// updates it in the database.\n    ///\n    /// This method is used to record the timestamp when the email verification\n    /// was sent and generate a unique verification token for the user.\n    ///\n    /// # Errors\n    ///\n    /// when has DB query error\n    pub async fn set_email_verification_sent(\n        mut self,\n        db: &DatabaseConnection,\n    ) -> ModelResult<Model> {\n        self.email_verification_sent_at = ActiveValue::set(Some(Local::now().naive_local()));\n        self.email_verification_token = ActiveValue::Set(Some(Uuid::new_v4().to_string()));\n        Ok(self.update(db).await?)\n    }\n\n    /// Sets the information for a reset password request,\n    /// generates a unique reset password token, and updates it in the\n    /// database.\n    ///\n    /// This method records the timestamp when the reset password token is sent\n    /// and generates a unique token for the user.\n    ///\n    /// # Arguments\n    ///\n    /// # Errors\n    ///\n    /// when has DB query error\n    pub async fn set_forgot_password_sent(mut self, db: &DatabaseConnection) -> ModelResult<Model> {\n        self.reset_sent_at = ActiveValue::set(Some(Local::now().naive_local()));\n        self.reset_token = ActiveValue::Set(Some(Uuid::new_v4().to_string()));\n        Ok(self.update(db).await?)\n    }\n\n    /// Records the verification time when a user verifies their\n    /// email and updates it in the database.\n    ///\n    /// This method sets the timestamp when the user successfully verifies their\n    /// email.\n    ///\n    /// # Errors\n    ///\n    /// when has DB query error\n    pub async fn verified(mut self, db: &DatabaseConnection) -> ModelResult<Model> {\n        self.email_verified_at = ActiveValue::set(Some(Local::now().naive_local()));\n        Ok(self.update(db).await?)\n    }\n\n    /// Resets the current user password with a new password and\n    /// updates it in the database.\n    ///\n    /// This method hashes the provided password and sets it as the new password\n    /// for the user.    \n    /// # Errors\n    ///\n    /// when has DB query error or could not hashed the given password\n    pub async fn reset_password(\n        mut self,\n        db: &DatabaseConnection,\n        password: &str,\n    ) -> ModelResult<Model> {\n        self.password =\n            ActiveValue::set(hash::hash_password(password).map_err(|e| ModelError::Any(e.into()))?);\n        Ok(self.update(db).await?)\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/tasks/mod.rs",
    "content": "pub mod seed;\n"
  },
  {
    "path": "examples/loco_seaography/src/tasks/seed.rs",
    "content": "//! This task implements data seeding functionality for initializing new\n//! development/demo environments.\n//!\n//! # Example\n//!\n//! Run the task with the following command:\n//! ```sh\n//! cargo run task\n//! ```\n//!\n//! To override existing data and reset the data structure, use the following\n//! command with the `refresh:true` argument:\n//! ```sh\n//! cargo run task seed_data refresh:true\n//! ```\n\nuse loco_rs::{db, prelude::*};\nuse migration::Migrator;\n\nuse crate::app::App;\n\n#[allow(clippy::module_name_repetitions)]\npub struct SeedData;\n#[async_trait]\nimpl Task for SeedData {\n    fn task(&self) -> TaskInfo {\n        TaskInfo {\n            name: \"seed_data\".to_string(),\n            detail: \"Task for seeding data\".to_string(),\n        }\n    }\n\n    async fn run(&self, app_context: &AppContext, vars: &task::Vars) -> Result<()> {\n        let refresh = vars\n            .cli_arg(\"refresh\")\n            .is_ok_and(|refresh| refresh == \"true\");\n\n        if refresh {\n            db::reset::<Migrator>(&app_context.db).await?;\n        }\n        let path = std::path::Path::new(\"src/fixtures\");\n        db::run_app_seed::<App>(app_context, path).await?;\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/views/auth.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::models::_entities::users;\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct LoginResponse {\n    pub token: String,\n    pub pid: String,\n    pub name: String,\n    pub is_verified: bool,\n}\n\nimpl LoginResponse {\n    #[must_use]\n    pub fn new(user: &users::Model, token: &String) -> Self {\n        Self {\n            token: token.to_string(),\n            pid: user.pid.to_string(),\n            name: user.name.clone(),\n            is_verified: user.email_verified_at.is_some(),\n        }\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/views/mod.rs",
    "content": "pub mod auth;\npub mod user;\n"
  },
  {
    "path": "examples/loco_seaography/src/views/user.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::models::_entities::users;\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct CurrentResponse {\n    pub pid: String,\n    pub name: String,\n    pub email: String,\n}\n\nimpl CurrentResponse {\n    #[must_use]\n    pub fn new(user: &users::Model) -> Self {\n        Self {\n            pid: user.pid.to_string(),\n            name: user.name.clone(),\n            email: user.email.clone(),\n        }\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/workers/downloader.rs",
    "content": "use std::time::Duration;\n\nuse loco_rs::prelude::*;\nuse serde::{Deserialize, Serialize};\nuse tokio::time::sleep;\n\nuse crate::models::users;\n\npub struct DownloadWorker {\n    pub ctx: AppContext,\n}\n\n#[derive(Deserialize, Debug, Serialize)]\npub struct DownloadWorkerArgs {\n    pub user_guid: String,\n}\n\n#[async_trait]\nimpl BackgroundWorker<DownloadWorkerArgs> for DownloadWorker {\n    fn build(ctx: &AppContext) -> Self {\n        Self { ctx: ctx.clone() }\n    }\n\n    async fn perform(&self, args: DownloadWorkerArgs) -> Result<()> {\n        // TODO: Some actual work goes here...\n        println!(\"================================================\");\n        println!(\"Sending payment report to user {}\", args.user_guid);\n\n        sleep(Duration::from_millis(2000)).await;\n\n        let all = users::Entity::find()\n            .all(&self.ctx.db)\n            .await\n            .map_err(Box::from)?;\n        for user in &all {\n            println!(\"user: {}\", user.id);\n        }\n        println!(\"================================================\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/loco_seaography/src/workers/mod.rs",
    "content": "pub mod downloader;\n"
  },
  {
    "path": "examples/loco_starter/.cargo/config.toml",
    "content": "[alias]\nloco       = \"run --\"\nplayground = \"run --example playground\"\n"
  },
  {
    "path": "examples/loco_starter/.devcontainer/Dockerfile",
    "content": "FROM mcr.microsoft.com/devcontainers/rust:1\n\nRUN apt-get update && export DEBIAN_FRONTEND=noninteractive \\\n     && apt-get -y install --no-install-recommends postgresql-client \\\n     && cargo install sea-orm-cli cargo-insta \\\n     && chown -R vscode /usr/local/cargo\n\nCOPY .env /.env\n"
  },
  {
    "path": "examples/loco_starter/.devcontainer/devcontainer.json",
    "content": "{\n    \"name\": \"Loco\",\n    \"dockerComposeFile\": \"docker-compose.yml\",\n    \"service\": \"app\",\n    \"workspaceFolder\": \"/workspaces/${localWorkspaceFolderBasename}\",\n    \"forwardPorts\": [\n        3000\n    ]\n}"
  },
  {
    "path": "examples/loco_starter/.devcontainer/docker-compose.yml",
    "content": "version: \"3\"\n\nservices:\n  app:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    command: sleep infinity\n    networks:\n      - db\n      - redis\n      - mailer\n    volumes:\n      - ../..:/workspaces:cached\n    env_file:\n      - .env\n  db:\n    image: postgres:15.3-alpine\n    restart: unless-stopped\n    ports:\n      - 5432:5432\n    networks:\n      - db\n    volumes:\n      - postgres-data:/var/lib/postgresql/data\n    env_file:\n      - .env\n  redis:\n    image: redis:latest\n    restart: unless-stopped\n    ports:\n      - 6379:6379\n    networks:\n      - redis\n  mailer:\n    image: mailtutan/mailtutan:latest\n    restart: unless-stopped\n    ports:\n      - 1080:1080\n      - 1025:1025\n    networks:\n      - mailer\n\nvolumes:\n  postgres-data:\n\nnetworks:\n  db:\n  redis:\n  mailer:\n"
  },
  {
    "path": "examples/loco_starter/.github/workflows/ci.yaml",
    "content": "name: CI\non:\n  push:\n    branches:\n      - master\n      - main\n  pull_request:\n\nenv:\n  RUST_TOOLCHAIN: stable\n  TOOLCHAIN_PROFILE: minimal\n\njobs:\n  rustfmt:\n    name: Check Style\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: read\n\n    steps:\n      - name: Checkout the code\n        uses: actions/checkout@v4\n      - uses: actions-rs/toolchain@v1\n        with:\n          profile: ${{ env.TOOLCHAIN_PROFILE }}\n          toolchain: ${{ env.RUST_TOOLCHAIN }}\n          override: true\n          components: rustfmt\n      - name: Run cargo fmt\n        uses: actions-rs/cargo@v1\n        with:\n          command: fmt\n          args: --all -- --check\n\n  clippy:\n    name: Run Clippy\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: read\n\n    steps:\n      - name: Checkout the code\n        uses: actions/checkout@v4\n      - uses: actions-rs/toolchain@v1\n        with:\n          profile: ${{ env.TOOLCHAIN_PROFILE }}\n          toolchain: ${{ env.RUST_TOOLCHAIN }}\n          override: true\n      - name: Setup Rust cache\n        uses: Swatinem/rust-cache@v2\n      - name: Run cargo clippy\n        uses: actions-rs/cargo@v1\n        with:\n          command: clippy\n          args: --all-features -- -D warnings -W clippy::pedantic -W clippy::nursery -W rust-2018-idioms\n\n  test:\n    name: Run Tests\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: read\n\n    services:\n      redis:\n        image: redis\n        options: >-\n          --health-cmd \"redis-cli ping\"\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n        ports:\n          - \"6379:6379\"\n      postgres:\n        image: postgres\n        env:\n          POSTGRES_DB: postgres_test\n          POSTGRES_USER: postgres\n          POSTGRES_PASSWORD: postgres\n        ports:\n          - \"5432:5432\"\n        # Set health checks to wait until postgres has started\n        options: --health-cmd pg_isready\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n\n    steps:\n      - name: Checkout the code\n        uses: actions/checkout@v4\n      - uses: actions-rs/toolchain@v1\n        with:\n          profile: ${{ env.TOOLCHAIN_PROFILE }}\n          toolchain: ${{ env.RUST_TOOLCHAIN }}\n          override: true\n      - name: Setup Rust cache\n        uses: Swatinem/rust-cache@v2\n      - name: Run cargo test\n        uses: actions-rs/cargo@v1\n        with:\n          command: test\n          args: --all-features --all\n        env:\n          REDIS_URL: redis://localhost:${{job.services.redis.ports[6379]}}\n          DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres_test\n"
  },
  {
    "path": "examples/loco_starter/.gitignore",
    "content": "**/config/local.yaml\n**/config/*.local.yaml\n**/config/production.yaml\n\n# Generated by Cargo\n# will have compiled files and executables\ndebug/\ntarget/\n\n# include cargo lock\n!Cargo.lock\n\n# These are backup files generated by rustfmt\n**/*.rs.bk\n\n# MSVC Windows builds of rustc generate these, which store debugging information\n*.pdb\n\nuploads\n"
  },
  {
    "path": "examples/loco_starter/.rustfmt.toml",
    "content": "comment_width        = 80\nformat_strings       = true\ngroup_imports        = \"StdExternalCrate\"\nimports_granularity  = \"Crate\"\nmax_width            = 100\nuse_small_heuristics = \"Default\"\nwrap_comments        = true\n"
  },
  {
    "path": "examples/loco_starter/Cargo.lock",
    "content": "# This file is automatically @generated by Cargo.\n# It is not intended for manual editing.\nversion = 4\n\n[[package]]\nname = \"addr2line\"\nversion = \"0.25.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b\"\ndependencies = [\n \"gimli\",\n]\n\n[[package]]\nname = \"adler2\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa\"\n\n[[package]]\nname = \"ahash\"\nversion = \"0.7.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9\"\ndependencies = [\n \"getrandom 0.2.16\",\n \"once_cell\",\n \"version_check\",\n]\n\n[[package]]\nname = \"ahash\"\nversion = \"0.8.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75\"\ndependencies = [\n \"cfg-if\",\n \"getrandom 0.3.3\",\n \"once_cell\",\n \"version_check\",\n \"zerocopy\",\n]\n\n[[package]]\nname = \"aho-corasick\"\nversion = \"1.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"aliasable\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd\"\n\n[[package]]\nname = \"alloc-no-stdlib\"\nversion = \"2.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3\"\n\n[[package]]\nname = \"alloc-stdlib\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece\"\ndependencies = [\n \"alloc-no-stdlib\",\n]\n\n[[package]]\nname = \"allocator-api2\"\nversion = \"0.2.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923\"\n\n[[package]]\nname = \"android_system_properties\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"anstream\"\nversion = \"0.6.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a\"\ndependencies = [\n \"anstyle\",\n \"anstyle-parse\",\n \"anstyle-query\",\n \"anstyle-wincon\",\n \"colorchoice\",\n \"is_terminal_polyfill\",\n \"utf8parse\",\n]\n\n[[package]]\nname = \"anstyle\"\nversion = \"1.0.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78\"\n\n[[package]]\nname = \"anstyle-parse\"\nversion = \"0.2.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2\"\ndependencies = [\n \"utf8parse\",\n]\n\n[[package]]\nname = \"anstyle-query\"\nversion = \"1.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2\"\ndependencies = [\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"anstyle-wincon\"\nversion = \"3.0.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a\"\ndependencies = [\n \"anstyle\",\n \"once_cell_polyfill\",\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"anyhow\"\nversion = \"1.0.100\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61\"\n\n[[package]]\nname = \"argon2\"\nversion = \"0.5.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072\"\ndependencies = [\n \"base64ct\",\n \"blake2\",\n \"cpufeatures\",\n \"password-hash\",\n]\n\n[[package]]\nname = \"arrayvec\"\nversion = \"0.7.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50\"\n\n[[package]]\nname = \"assert-json-diff\"\nversion = \"2.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12\"\ndependencies = [\n \"serde\",\n \"serde_json\",\n]\n\n[[package]]\nname = \"async-compression\"\nversion = \"0.4.32\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0\"\ndependencies = [\n \"compression-codecs\",\n \"compression-core\",\n \"futures-core\",\n \"pin-project-lite\",\n \"tokio\",\n]\n\n[[package]]\nname = \"async-stream\"\nversion = \"0.3.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476\"\ndependencies = [\n \"async-stream-impl\",\n \"futures-core\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"async-stream-impl\"\nversion = \"0.3.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"async-trait\"\nversion = \"0.1.89\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"atoi\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528\"\ndependencies = [\n \"num-traits\",\n]\n\n[[package]]\nname = \"atomic-waker\"\nversion = \"1.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0\"\n\n[[package]]\nname = \"auto-future\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373\"\n\n[[package]]\nname = \"autocfg\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8\"\n\n[[package]]\nname = \"axum\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871\"\ndependencies = [\n \"axum-core\",\n \"axum-macros\",\n \"bytes\",\n \"form_urlencoded\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"hyper\",\n \"hyper-util\",\n \"itoa\",\n \"matchit\",\n \"memchr\",\n \"mime\",\n \"multer\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"serde_core\",\n \"serde_json\",\n \"serde_path_to_error\",\n \"serde_urlencoded\",\n \"sync_wrapper\",\n \"tokio\",\n \"tower 0.5.2\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"axum-core\"\nversion = \"0.5.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"mime\",\n \"pin-project-lite\",\n \"sync_wrapper\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"axum-extra\"\nversion = \"0.10.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9963ff19f40c6102c76756ef0a46004c0d58957d87259fc9208ff8441c12ab96\"\ndependencies = [\n \"axum\",\n \"axum-core\",\n \"bytes\",\n \"cookie\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"mime\",\n \"pin-project-lite\",\n \"rustversion\",\n \"serde_core\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"axum-macros\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"axum-test\"\nversion = \"17.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0eb1dfb84bd48bad8e4aa1acb82ed24c2bb5e855b659959b4e03b4dca118fcac\"\ndependencies = [\n \"anyhow\",\n \"assert-json-diff\",\n \"auto-future\",\n \"axum\",\n \"bytes\",\n \"bytesize\",\n \"cookie\",\n \"http\",\n \"http-body-util\",\n \"hyper\",\n \"hyper-util\",\n \"mime\",\n \"pretty_assertions\",\n \"reserve-port\",\n \"rust-multipart-rfc7578_2\",\n \"serde\",\n \"serde_json\",\n \"serde_urlencoded\",\n \"smallvec\",\n \"tokio\",\n \"tower 0.5.2\",\n \"url\",\n]\n\n[[package]]\nname = \"backon\"\nversion = \"1.5.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"592277618714fbcecda9a02ba7a8781f319d26532a88553bbacc77ba5d2b3a8d\"\ndependencies = [\n \"fastrand\",\n \"gloo-timers\",\n \"tokio\",\n]\n\n[[package]]\nname = \"backtrace\"\nversion = \"0.3.76\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6\"\ndependencies = [\n \"addr2line\",\n \"cfg-if\",\n \"libc\",\n \"miniz_oxide\",\n \"object\",\n \"rustc-demangle\",\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"backtrace_printer\"\nversion = \"1.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e8d28de81c708c843640982b66573df0f0168d87e42854b563971f326745aab7\"\ndependencies = [\n \"btparse-stable\",\n \"colored 2.2.0\",\n \"regex\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"base64\"\nversion = \"0.22.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6\"\n\n[[package]]\nname = \"base64ct\"\nversion = \"1.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba\"\n\n[[package]]\nname = \"bigdecimal\"\nversion = \"0.4.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1a22f228ab7a1b23027ccc6c350b72868017af7ea8356fbdf19f8d991c690013\"\ndependencies = [\n \"autocfg\",\n \"libm\",\n \"num-bigint\",\n \"num-integer\",\n \"num-traits\",\n \"serde\",\n]\n\n[[package]]\nname = \"bitflags\"\nversion = \"1.3.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a\"\n\n[[package]]\nname = \"bitflags\"\nversion = \"2.9.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"bitvec\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c\"\ndependencies = [\n \"funty\",\n \"radium\",\n \"tap\",\n \"wyz\",\n]\n\n[[package]]\nname = \"blake2\"\nversion = \"0.10.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe\"\ndependencies = [\n \"digest\",\n]\n\n[[package]]\nname = \"block-buffer\"\nversion = \"0.10.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71\"\ndependencies = [\n \"generic-array\",\n]\n\n[[package]]\nname = \"borsh\"\nversion = \"1.5.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce\"\ndependencies = [\n \"borsh-derive\",\n \"cfg_aliases\",\n]\n\n[[package]]\nname = \"borsh-derive\"\nversion = \"1.5.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3\"\ndependencies = [\n \"once_cell\",\n \"proc-macro-crate\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"brotli\"\nversion = \"8.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560\"\ndependencies = [\n \"alloc-no-stdlib\",\n \"alloc-stdlib\",\n \"brotli-decompressor\",\n]\n\n[[package]]\nname = \"brotli-decompressor\"\nversion = \"5.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03\"\ndependencies = [\n \"alloc-no-stdlib\",\n \"alloc-stdlib\",\n]\n\n[[package]]\nname = \"bstr\"\nversion = \"1.12.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4\"\ndependencies = [\n \"memchr\",\n \"serde\",\n]\n\n[[package]]\nname = \"btparse-stable\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0d75b8252ed252f881d1dc4482ae3c3854df6ee8183c1906bac50ff358f4f89f\"\n\n[[package]]\nname = \"bumpalo\"\nversion = \"3.19.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43\"\n\n[[package]]\nname = \"byte-unit\"\nversion = \"4.0.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c\"\ndependencies = [\n \"serde\",\n \"utf8-width\",\n]\n\n[[package]]\nname = \"bytecheck\"\nversion = \"0.6.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2\"\ndependencies = [\n \"bytecheck_derive\",\n \"ptr_meta\",\n \"simdutf8\",\n]\n\n[[package]]\nname = \"bytecheck_derive\"\nversion = \"0.6.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"byteorder\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b\"\n\n[[package]]\nname = \"bytes\"\nversion = \"1.10.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a\"\n\n[[package]]\nname = \"bytesize\"\nversion = \"2.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f5c434ae3cf0089ca203e9019ebe529c47ff45cefe8af7c85ecb734ef541822f\"\n\n[[package]]\nname = \"cc\"\nversion = \"1.2.40\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb\"\ndependencies = [\n \"find-msvc-tools\",\n \"jobserver\",\n \"libc\",\n \"shlex\",\n]\n\n[[package]]\nname = \"cfg-if\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9\"\n\n[[package]]\nname = \"cfg_aliases\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724\"\n\n[[package]]\nname = \"chrono\"\nversion = \"0.4.42\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2\"\ndependencies = [\n \"iana-time-zone\",\n \"js-sys\",\n \"num-traits\",\n \"serde\",\n \"wasm-bindgen\",\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"chrono-tz\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb\"\ndependencies = [\n \"chrono\",\n \"chrono-tz-build\",\n \"phf\",\n]\n\n[[package]]\nname = \"chrono-tz-build\"\nversion = \"0.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1\"\ndependencies = [\n \"parse-zoneinfo\",\n \"phf\",\n \"phf_codegen\",\n]\n\n[[package]]\nname = \"chumsky\"\nversion = \"0.9.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9\"\ndependencies = [\n \"hashbrown 0.14.5\",\n \"stacker\",\n]\n\n[[package]]\nname = \"clap\"\nversion = \"4.5.48\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae\"\ndependencies = [\n \"clap_builder\",\n \"clap_derive\",\n]\n\n[[package]]\nname = \"clap_builder\"\nversion = \"4.5.48\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9\"\ndependencies = [\n \"anstream\",\n \"anstyle\",\n \"clap_lex\",\n \"strsim\",\n]\n\n[[package]]\nname = \"clap_derive\"\nversion = \"4.5.47\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c\"\ndependencies = [\n \"heck 0.5.0\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"clap_lex\"\nversion = \"0.7.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675\"\n\n[[package]]\nname = \"colorchoice\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75\"\n\n[[package]]\nname = \"colored\"\nversion = \"2.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c\"\ndependencies = [\n \"lazy_static\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"colored\"\nversion = \"3.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e\"\ndependencies = [\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"combine\"\nversion = \"4.6.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"memchr\",\n \"pin-project-lite\",\n \"tokio\",\n \"tokio-util\",\n]\n\n[[package]]\nname = \"compression-codecs\"\nversion = \"0.4.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23\"\ndependencies = [\n \"brotli\",\n \"compression-core\",\n \"flate2\",\n \"memchr\",\n \"zstd\",\n \"zstd-safe\",\n]\n\n[[package]]\nname = \"compression-core\"\nversion = \"0.4.29\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb\"\n\n[[package]]\nname = \"concurrent-queue\"\nversion = \"2.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"console\"\nversion = \"0.15.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8\"\ndependencies = [\n \"encode_unicode\",\n \"libc\",\n \"once_cell\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"const-oid\"\nversion = \"0.9.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8\"\n\n[[package]]\nname = \"cookie\"\nversion = \"0.18.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747\"\ndependencies = [\n \"percent-encoding\",\n \"time\",\n \"version_check\",\n]\n\n[[package]]\nname = \"core-foundation-sys\"\nversion = \"0.8.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b\"\n\n[[package]]\nname = \"cpufeatures\"\nversion = \"0.2.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"crc\"\nversion = \"3.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675\"\ndependencies = [\n \"crc-catalog\",\n]\n\n[[package]]\nname = \"crc-catalog\"\nversion = \"2.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5\"\n\n[[package]]\nname = \"crc32fast\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511\"\ndependencies = [\n \"cfg-if\",\n]\n\n[[package]]\nname = \"cron\"\nversion = \"0.12.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6f8c3e73077b4b4a6ab1ea5047c37c57aee77657bc8ecd6f29b0af082d0b0c07\"\ndependencies = [\n \"chrono\",\n \"nom 7.1.3\",\n \"once_cell\",\n]\n\n[[package]]\nname = \"crossbeam-channel\"\nversion = \"0.5.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-deque\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51\"\ndependencies = [\n \"crossbeam-epoch\",\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-epoch\"\nversion = \"0.9.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-queue\"\nversion = \"0.3.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-utils\"\nversion = \"0.8.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28\"\n\n[[package]]\nname = \"cruet\"\nversion = \"0.13.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"113a9e83d8f614be76de8df1f25bf9d0ea6e85ea573710a3d3f3abe1438ae49c\"\ndependencies = [\n \"once_cell\",\n \"regex\",\n]\n\n[[package]]\nname = \"cruet\"\nversion = \"0.14.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6132609543972496bc97b1e01f1ce6586768870aeb4cabeb3385f4e05b5caead\"\ndependencies = [\n \"once_cell\",\n \"regex\",\n]\n\n[[package]]\nname = \"crypto-common\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3\"\ndependencies = [\n \"generic-array\",\n \"typenum\",\n]\n\n[[package]]\nname = \"cssparser\"\nversion = \"0.34.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b7c66d1cd8ed61bf80b38432613a7a2f09401ab8d0501110655f8b341484a3e3\"\ndependencies = [\n \"cssparser-macros\",\n \"dtoa-short\",\n \"itoa\",\n \"phf\",\n \"smallvec\",\n]\n\n[[package]]\nname = \"cssparser-macros\"\nversion = \"0.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331\"\ndependencies = [\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"darling\"\nversion = \"0.20.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee\"\ndependencies = [\n \"darling_core\",\n \"darling_macro\",\n]\n\n[[package]]\nname = \"darling_core\"\nversion = \"0.20.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e\"\ndependencies = [\n \"fnv\",\n \"ident_case\",\n \"proc-macro2\",\n \"quote\",\n \"strsim\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"darling_macro\"\nversion = \"0.20.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead\"\ndependencies = [\n \"darling_core\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"dashmap\"\nversion = \"5.5.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856\"\ndependencies = [\n \"cfg-if\",\n \"hashbrown 0.14.5\",\n \"lock_api\",\n \"once_cell\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"dashmap\"\nversion = \"6.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf\"\ndependencies = [\n \"cfg-if\",\n \"crossbeam-utils\",\n \"hashbrown 0.14.5\",\n \"lock_api\",\n \"once_cell\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"der\"\nversion = \"0.7.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb\"\ndependencies = [\n \"const-oid\",\n \"pem-rfc7468\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"deranged\"\nversion = \"0.5.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071\"\ndependencies = [\n \"powerfmt\",\n \"serde_core\",\n]\n\n[[package]]\nname = \"derive_more\"\nversion = \"0.99.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"derive_more\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678\"\ndependencies = [\n \"derive_more-impl\",\n]\n\n[[package]]\nname = \"derive_more-impl\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"unicode-xid\",\n]\n\n[[package]]\nname = \"deunicode\"\nversion = \"1.6.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04\"\n\n[[package]]\nname = \"diff\"\nversion = \"0.1.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8\"\n\n[[package]]\nname = \"digest\"\nversion = \"0.10.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292\"\ndependencies = [\n \"block-buffer\",\n \"const-oid\",\n \"crypto-common\",\n \"subtle\",\n]\n\n[[package]]\nname = \"displaydoc\"\nversion = \"0.2.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"dotenvy\"\nversion = \"0.15.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b\"\n\n[[package]]\nname = \"dtoa\"\nversion = \"1.0.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04\"\n\n[[package]]\nname = \"dtoa-short\"\nversion = \"0.3.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87\"\ndependencies = [\n \"dtoa\",\n]\n\n[[package]]\nname = \"duct\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d7478638a31d1f1f3d6c9f5e57c76b906a04ac4879d6fd0fb6245bc88f73fd0b\"\ndependencies = [\n \"libc\",\n \"os_pipe\",\n \"shared_child\",\n \"shared_thread\",\n]\n\n[[package]]\nname = \"duct_sh\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8139179d1d133ab7153920ba3812915b17c61e2514a6f98b1fd03f2c07668d1\"\ndependencies = [\n \"duct\",\n]\n\n[[package]]\nname = \"ego-tree\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7c6ba7d4eec39eaa9ab24d44a0e73a7949a1095a8b3f3abb11eddf27dbb56a53\"\n\n[[package]]\nname = \"either\"\nversion = \"1.15.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"email-encoding\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9298e6504d9b9e780ed3f7dfd43a61be8cd0e09eb07f7706a945b0072b6670b6\"\ndependencies = [\n \"base64\",\n \"memchr\",\n]\n\n[[package]]\nname = \"email_address\"\nversion = \"0.2.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449\"\n\n[[package]]\nname = \"encode_unicode\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0\"\n\n[[package]]\nname = \"encoding_rs\"\nversion = \"0.8.35\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3\"\ndependencies = [\n \"cfg-if\",\n]\n\n[[package]]\nname = \"english-to-cron\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e26fb7377cbec9a94f60428e6e6afbe10c699a14639b4d3d4b67b25c0bbe0806\"\ndependencies = [\n \"regex\",\n]\n\n[[package]]\nname = \"equivalent\"\nversion = \"1.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f\"\n\n[[package]]\nname = \"etcetera\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943\"\ndependencies = [\n \"cfg-if\",\n \"home\",\n \"windows-sys 0.48.0\",\n]\n\n[[package]]\nname = \"event-listener\"\nversion = \"5.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab\"\ndependencies = [\n \"concurrent-queue\",\n \"parking\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"eyre\"\nversion = \"0.6.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec\"\ndependencies = [\n \"indenter\",\n \"once_cell\",\n]\n\n[[package]]\nname = \"fastrand\"\nversion = \"2.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be\"\n\n[[package]]\nname = \"find-msvc-tools\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3\"\n\n[[package]]\nname = \"flate2\"\nversion = \"1.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9\"\ndependencies = [\n \"crc32fast\",\n \"miniz_oxide\",\n]\n\n[[package]]\nname = \"flume\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095\"\ndependencies = [\n \"futures-core\",\n \"futures-sink\",\n \"spin\",\n]\n\n[[package]]\nname = \"fnv\"\nversion = \"1.0.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1\"\n\n[[package]]\nname = \"foldhash\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2\"\n\n[[package]]\nname = \"form_urlencoded\"\nversion = \"1.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf\"\ndependencies = [\n \"percent-encoding\",\n]\n\n[[package]]\nname = \"fs-err\"\nversion = \"2.11.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41\"\ndependencies = [\n \"autocfg\",\n]\n\n[[package]]\nname = \"fsevent-sys\"\nversion = \"4.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"funty\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c\"\n\n[[package]]\nname = \"futf\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843\"\ndependencies = [\n \"mac\",\n \"new_debug_unreachable\",\n]\n\n[[package]]\nname = \"futures\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"futures-executor\",\n \"futures-io\",\n \"futures-sink\",\n \"futures-task\",\n \"futures-util\",\n]\n\n[[package]]\nname = \"futures-channel\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10\"\ndependencies = [\n \"futures-core\",\n \"futures-sink\",\n]\n\n[[package]]\nname = \"futures-core\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e\"\n\n[[package]]\nname = \"futures-executor\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f\"\ndependencies = [\n \"futures-core\",\n \"futures-task\",\n \"futures-util\",\n]\n\n[[package]]\nname = \"futures-intrusive\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f\"\ndependencies = [\n \"futures-core\",\n \"lock_api\",\n \"parking_lot\",\n]\n\n[[package]]\nname = \"futures-io\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6\"\n\n[[package]]\nname = \"futures-macro\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"futures-sink\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7\"\n\n[[package]]\nname = \"futures-task\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988\"\n\n[[package]]\nname = \"futures-timer\"\nversion = \"3.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24\"\n\n[[package]]\nname = \"futures-util\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"futures-io\",\n \"futures-macro\",\n \"futures-sink\",\n \"futures-task\",\n \"memchr\",\n \"pin-project-lite\",\n \"pin-utils\",\n \"slab\",\n]\n\n[[package]]\nname = \"fxhash\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c\"\ndependencies = [\n \"byteorder\",\n]\n\n[[package]]\nname = \"generic-array\"\nversion = \"0.14.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a\"\ndependencies = [\n \"typenum\",\n \"version_check\",\n]\n\n[[package]]\nname = \"getopts\"\nversion = \"0.2.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df\"\ndependencies = [\n \"unicode-width\",\n]\n\n[[package]]\nname = \"getrandom\"\nversion = \"0.2.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592\"\ndependencies = [\n \"cfg-if\",\n \"js-sys\",\n \"libc\",\n \"wasi 0.11.1+wasi-snapshot-preview1\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"getrandom\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"r-efi\",\n \"wasi 0.14.7+wasi-0.2.4\",\n]\n\n[[package]]\nname = \"gimli\"\nversion = \"0.32.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7\"\n\n[[package]]\nname = \"glob\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280\"\n\n[[package]]\nname = \"globset\"\nversion = \"0.4.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5\"\ndependencies = [\n \"aho-corasick\",\n \"bstr\",\n \"log\",\n \"regex-automata\",\n \"regex-syntax\",\n]\n\n[[package]]\nname = \"globwalk\"\nversion = \"0.9.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"ignore\",\n \"walkdir\",\n]\n\n[[package]]\nname = \"gloo-timers\"\nversion = \"0.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"js-sys\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.12.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888\"\ndependencies = [\n \"ahash 0.7.8\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.14.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1\"\ndependencies = [\n \"ahash 0.8.12\",\n \"allocator-api2\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.15.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1\"\ndependencies = [\n \"allocator-api2\",\n \"equivalent\",\n \"foldhash\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.16.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d\"\n\n[[package]]\nname = \"hashlink\"\nversion = \"0.10.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1\"\ndependencies = [\n \"hashbrown 0.15.5\",\n]\n\n[[package]]\nname = \"heck\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8\"\n\n[[package]]\nname = \"heck\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea\"\n\n[[package]]\nname = \"hex\"\nversion = \"0.4.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70\"\n\n[[package]]\nname = \"hkdf\"\nversion = \"0.12.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7\"\ndependencies = [\n \"hmac\",\n]\n\n[[package]]\nname = \"hmac\"\nversion = \"0.12.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e\"\ndependencies = [\n \"digest\",\n]\n\n[[package]]\nname = \"home\"\nversion = \"0.5.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf\"\ndependencies = [\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"hostname\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"windows-link 0.1.3\",\n]\n\n[[package]]\nname = \"html5ever\"\nversion = \"0.29.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c\"\ndependencies = [\n \"log\",\n \"mac\",\n \"markup5ever\",\n \"match_token\",\n]\n\n[[package]]\nname = \"http\"\nversion = \"1.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565\"\ndependencies = [\n \"bytes\",\n \"fnv\",\n \"itoa\",\n]\n\n[[package]]\nname = \"http-body\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184\"\ndependencies = [\n \"bytes\",\n \"http\",\n]\n\n[[package]]\nname = \"http-body-util\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"http\",\n \"http-body\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"http-range-header\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c\"\n\n[[package]]\nname = \"httparse\"\nversion = \"1.10.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87\"\n\n[[package]]\nname = \"httpdate\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9\"\n\n[[package]]\nname = \"humansize\"\nversion = \"2.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7\"\ndependencies = [\n \"libm\",\n]\n\n[[package]]\nname = \"hyper\"\nversion = \"1.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e\"\ndependencies = [\n \"atomic-waker\",\n \"bytes\",\n \"futures-channel\",\n \"futures-core\",\n \"http\",\n \"http-body\",\n \"httparse\",\n \"httpdate\",\n \"itoa\",\n \"pin-project-lite\",\n \"pin-utils\",\n \"smallvec\",\n \"tokio\",\n \"want\",\n]\n\n[[package]]\nname = \"hyper-util\"\nversion = \"0.1.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8\"\ndependencies = [\n \"base64\",\n \"bytes\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"hyper\",\n \"ipnet\",\n \"libc\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"socket2 0.6.0\",\n \"tokio\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"iana-time-zone\"\nversion = \"0.1.64\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb\"\ndependencies = [\n \"android_system_properties\",\n \"core-foundation-sys\",\n \"iana-time-zone-haiku\",\n \"js-sys\",\n \"log\",\n \"wasm-bindgen\",\n \"windows-core\",\n]\n\n[[package]]\nname = \"iana-time-zone-haiku\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f\"\ndependencies = [\n \"cc\",\n]\n\n[[package]]\nname = \"icu_collections\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47\"\ndependencies = [\n \"displaydoc\",\n \"potential_utf\",\n \"yoke\",\n \"zerofrom\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_locale_core\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a\"\ndependencies = [\n \"displaydoc\",\n \"litemap\",\n \"tinystr\",\n \"writeable\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_normalizer\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979\"\ndependencies = [\n \"displaydoc\",\n \"icu_collections\",\n \"icu_normalizer_data\",\n \"icu_properties\",\n \"icu_provider\",\n \"smallvec\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_normalizer_data\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3\"\n\n[[package]]\nname = \"icu_properties\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b\"\ndependencies = [\n \"displaydoc\",\n \"icu_collections\",\n \"icu_locale_core\",\n \"icu_properties_data\",\n \"icu_provider\",\n \"potential_utf\",\n \"zerotrie\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_properties_data\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632\"\n\n[[package]]\nname = \"icu_provider\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af\"\ndependencies = [\n \"displaydoc\",\n \"icu_locale_core\",\n \"stable_deref_trait\",\n \"tinystr\",\n \"writeable\",\n \"yoke\",\n \"zerofrom\",\n \"zerotrie\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"ident_case\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39\"\n\n[[package]]\nname = \"idna\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de\"\ndependencies = [\n \"idna_adapter\",\n \"smallvec\",\n \"utf8_iter\",\n]\n\n[[package]]\nname = \"idna_adapter\"\nversion = \"1.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344\"\ndependencies = [\n \"icu_normalizer\",\n \"icu_properties\",\n]\n\n[[package]]\nname = \"ignore\"\nversion = \"0.4.23\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b\"\ndependencies = [\n \"crossbeam-deque\",\n \"globset\",\n \"log\",\n \"memchr\",\n \"regex-automata\",\n \"same-file\",\n \"walkdir\",\n \"winapi-util\",\n]\n\n[[package]]\nname = \"include_dir\"\nversion = \"0.7.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd\"\ndependencies = [\n \"include_dir_macros\",\n]\n\n[[package]]\nname = \"include_dir_macros\"\nversion = \"0.7.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n]\n\n[[package]]\nname = \"indenter\"\nversion = \"0.3.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5\"\n\n[[package]]\nname = \"indexmap\"\nversion = \"2.11.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5\"\ndependencies = [\n \"equivalent\",\n \"hashbrown 0.16.0\",\n]\n\n[[package]]\nname = \"indoc\"\nversion = \"2.0.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706\"\ndependencies = [\n \"rustversion\",\n]\n\n[[package]]\nname = \"inherent\"\nversion = \"1.0.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c727f80bfa4a6c6e2508d2f05b6f4bfce242030bd88ed15ae5331c5b5d30fba7\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"inotify\"\nversion = \"0.11.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"inotify-sys\",\n \"libc\",\n]\n\n[[package]]\nname = \"inotify-sys\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"insta\"\nversion = \"1.43.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"46fdb647ebde000f43b5b53f773c30cf9b0cb4300453208713fa38b2c70935a0\"\ndependencies = [\n \"console\",\n \"once_cell\",\n \"pest\",\n \"pest_derive\",\n \"regex\",\n \"serde\",\n \"similar\",\n]\n\n[[package]]\nname = \"io-uring\"\nversion = \"0.7.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"cfg-if\",\n \"libc\",\n]\n\n[[package]]\nname = \"ipnet\"\nversion = \"2.11.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130\"\n\n[[package]]\nname = \"ipnetwork\"\nversion = \"0.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"iri-string\"\nversion = \"0.7.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2\"\ndependencies = [\n \"memchr\",\n \"serde\",\n]\n\n[[package]]\nname = \"is_terminal_polyfill\"\nversion = \"1.70.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf\"\n\n[[package]]\nname = \"itertools\"\nversion = \"0.14.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285\"\ndependencies = [\n \"either\",\n]\n\n[[package]]\nname = \"itoa\"\nversion = \"1.0.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c\"\n\n[[package]]\nname = \"jobserver\"\nversion = \"0.1.34\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33\"\ndependencies = [\n \"getrandom 0.3.3\",\n \"libc\",\n]\n\n[[package]]\nname = \"js-sys\"\nversion = \"0.3.81\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305\"\ndependencies = [\n \"once_cell\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"jsonwebtoken\"\nversion = \"9.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde\"\ndependencies = [\n \"base64\",\n \"js-sys\",\n \"pem\",\n \"ring\",\n \"serde\",\n \"serde_json\",\n \"simple_asn1\",\n]\n\n[[package]]\nname = \"kqueue\"\nversion = \"1.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a\"\ndependencies = [\n \"kqueue-sys\",\n \"libc\",\n]\n\n[[package]]\nname = \"kqueue-sys\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b\"\ndependencies = [\n \"bitflags 1.3.2\",\n \"libc\",\n]\n\n[[package]]\nname = \"lazy_static\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe\"\ndependencies = [\n \"spin\",\n]\n\n[[package]]\nname = \"lettre\"\nversion = \"0.11.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5cb54db6ff7a89efac87dba5baeac57bb9ccd726b49a9b6f21fb92b3966aaf56\"\ndependencies = [\n \"async-trait\",\n \"base64\",\n \"chumsky\",\n \"email-encoding\",\n \"email_address\",\n \"fastrand\",\n \"futures-io\",\n \"futures-util\",\n \"hostname\",\n \"httpdate\",\n \"idna\",\n \"mime\",\n \"nom 8.0.0\",\n \"percent-encoding\",\n \"quoted_printable\",\n \"rustls\",\n \"socket2 0.6.0\",\n \"tokio\",\n \"tokio-rustls\",\n \"url\",\n \"webpki-roots 1.0.2\",\n]\n\n[[package]]\nname = \"libc\"\nversion = \"0.2.176\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174\"\n\n[[package]]\nname = \"libm\"\nversion = \"0.2.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de\"\n\n[[package]]\nname = \"libredox\"\nversion = \"0.1.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"libc\",\n \"redox_syscall\",\n]\n\n[[package]]\nname = \"libsqlite3-sys\"\nversion = \"0.30.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149\"\ndependencies = [\n \"cc\",\n \"pkg-config\",\n \"vcpkg\",\n]\n\n[[package]]\nname = \"litemap\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956\"\n\n[[package]]\nname = \"lock_api\"\nversion = \"0.4.14\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965\"\ndependencies = [\n \"scopeguard\",\n]\n\n[[package]]\nname = \"loco-gen\"\nversion = \"0.16.3\"\nsource = \"git+https://github.com/SeaQL/loco?branch=master#0e2860b7885e6c00e013b3618896a78095809ede\"\ndependencies = [\n \"chrono\",\n \"clap\",\n \"colored 3.0.0\",\n \"cruet 0.14.0\",\n \"duct\",\n \"heck 0.4.1\",\n \"include_dir\",\n \"regex\",\n \"rrgen\",\n \"serde\",\n \"serde_json\",\n \"tera\",\n \"thiserror 1.0.69\",\n \"tracing\",\n]\n\n[[package]]\nname = \"loco-rs\"\nversion = \"0.16.3\"\nsource = \"git+https://github.com/SeaQL/loco?branch=master#0e2860b7885e6c00e013b3618896a78095809ede\"\ndependencies = [\n \"argon2\",\n \"async-trait\",\n \"axum\",\n \"axum-extra\",\n \"axum-test\",\n \"backtrace_printer\",\n \"byte-unit\",\n \"bytes\",\n \"chrono\",\n \"clap\",\n \"colored 3.0.0\",\n \"cruet 0.13.3\",\n \"dashmap 6.1.0\",\n \"duct\",\n \"duct_sh\",\n \"english-to-cron\",\n \"futures-util\",\n \"heck 0.4.1\",\n \"include_dir\",\n \"ipnetwork\",\n \"jsonwebtoken\",\n \"lettre\",\n \"loco-gen\",\n \"moka\",\n \"notify\",\n \"opendal\",\n \"rand 0.9.2\",\n \"redis\",\n \"regex\",\n \"scraper\",\n \"sea-orm\",\n \"sea-orm-migration\",\n \"semver\",\n \"serde\",\n \"serde_json\",\n \"serde_variant\",\n \"serde_yaml\",\n \"sqlx\",\n \"tera\",\n \"thiserror 1.0.69\",\n \"tokio\",\n \"tokio-cron-scheduler\",\n \"tokio-util\",\n \"toml\",\n \"tower 0.4.13\",\n \"tower-http\",\n \"tracing\",\n \"tracing-appender\",\n \"tracing-subscriber\",\n \"tree-fs\",\n \"ulid\",\n \"uuid\",\n \"validator\",\n]\n\n[[package]]\nname = \"loco_starter\"\nversion = \"0.1.0\"\ndependencies = [\n \"async-trait\",\n \"axum\",\n \"chrono\",\n \"eyre\",\n \"include_dir\",\n \"insta\",\n \"loco-rs\",\n \"migration\",\n \"rstest\",\n \"sea-orm\",\n \"serde\",\n \"serde_json\",\n \"serial_test\",\n \"tokio\",\n \"tokio-util\",\n \"tracing\",\n \"tracing-subscriber\",\n \"uuid\",\n \"validator\",\n]\n\n[[package]]\nname = \"log\"\nversion = \"0.4.28\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432\"\n\n[[package]]\nname = \"mac\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4\"\n\n[[package]]\nname = \"markup5ever\"\nversion = \"0.14.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18\"\ndependencies = [\n \"log\",\n \"phf\",\n \"phf_codegen\",\n \"string_cache\",\n \"string_cache_codegen\",\n \"tendril\",\n]\n\n[[package]]\nname = \"match_token\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"matchers\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9\"\ndependencies = [\n \"regex-automata\",\n]\n\n[[package]]\nname = \"matchit\"\nversion = \"0.8.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3\"\n\n[[package]]\nname = \"md-5\"\nversion = \"0.10.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf\"\ndependencies = [\n \"cfg-if\",\n \"digest\",\n]\n\n[[package]]\nname = \"memchr\"\nversion = \"2.7.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273\"\n\n[[package]]\nname = \"migration\"\nversion = \"0.1.0\"\ndependencies = [\n \"loco-rs\",\n \"sea-orm-migration\",\n \"tokio\",\n]\n\n[[package]]\nname = \"mime\"\nversion = \"0.3.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a\"\n\n[[package]]\nname = \"mime_guess\"\nversion = \"2.0.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e\"\ndependencies = [\n \"mime\",\n \"unicase\",\n]\n\n[[package]]\nname = \"minimal-lexical\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a\"\n\n[[package]]\nname = \"miniz_oxide\"\nversion = \"0.8.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316\"\ndependencies = [\n \"adler2\",\n \"simd-adler32\",\n]\n\n[[package]]\nname = \"mio\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c\"\ndependencies = [\n \"libc\",\n \"log\",\n \"wasi 0.11.1+wasi-snapshot-preview1\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"moka\"\nversion = \"0.12.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8261cd88c312e0004c1d51baad2980c66528dfdb2bee62003e643a4d8f86b077\"\ndependencies = [\n \"crossbeam-channel\",\n \"crossbeam-epoch\",\n \"crossbeam-utils\",\n \"equivalent\",\n \"parking_lot\",\n \"portable-atomic\",\n \"rustc_version\",\n \"smallvec\",\n \"tagptr\",\n \"uuid\",\n]\n\n[[package]]\nname = \"multer\"\nversion = \"3.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b\"\ndependencies = [\n \"bytes\",\n \"encoding_rs\",\n \"futures-util\",\n \"http\",\n \"httparse\",\n \"memchr\",\n \"mime\",\n \"spin\",\n \"version_check\",\n]\n\n[[package]]\nname = \"new_debug_unreachable\"\nversion = \"1.0.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086\"\n\n[[package]]\nname = \"nom\"\nversion = \"7.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a\"\ndependencies = [\n \"memchr\",\n \"minimal-lexical\",\n]\n\n[[package]]\nname = \"nom\"\nversion = \"8.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"notify\"\nversion = \"8.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"fsevent-sys\",\n \"inotify\",\n \"kqueue\",\n \"libc\",\n \"log\",\n \"mio\",\n \"notify-types\",\n \"walkdir\",\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"notify-types\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d\"\n\n[[package]]\nname = \"nu-ansi-term\"\nversion = \"0.50.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399\"\ndependencies = [\n \"windows-sys 0.52.0\",\n]\n\n[[package]]\nname = \"num-bigint\"\nversion = \"0.4.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9\"\ndependencies = [\n \"num-integer\",\n \"num-traits\",\n]\n\n[[package]]\nname = \"num-bigint-dig\"\nversion = \"0.8.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151\"\ndependencies = [\n \"byteorder\",\n \"lazy_static\",\n \"libm\",\n \"num-integer\",\n \"num-iter\",\n \"num-traits\",\n \"rand 0.8.5\",\n \"smallvec\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"num-conv\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9\"\n\n[[package]]\nname = \"num-derive\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"num-integer\"\nversion = \"0.1.46\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f\"\ndependencies = [\n \"num-traits\",\n]\n\n[[package]]\nname = \"num-iter\"\nversion = \"0.1.45\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf\"\ndependencies = [\n \"autocfg\",\n \"num-integer\",\n \"num-traits\",\n]\n\n[[package]]\nname = \"num-traits\"\nversion = \"0.2.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841\"\ndependencies = [\n \"autocfg\",\n \"libm\",\n]\n\n[[package]]\nname = \"object\"\nversion = \"0.37.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"once_cell\"\nversion = \"1.21.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d\"\n\n[[package]]\nname = \"once_cell_polyfill\"\nversion = \"1.70.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad\"\n\n[[package]]\nname = \"opendal\"\nversion = \"0.54.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ffb9838d0575c6dbaf3fcec7255af8d5771996d4af900bbb6fa9a314dec00a1a\"\ndependencies = [\n \"anyhow\",\n \"backon\",\n \"base64\",\n \"bytes\",\n \"chrono\",\n \"futures\",\n \"getrandom 0.2.16\",\n \"http\",\n \"http-body\",\n \"log\",\n \"md-5\",\n \"percent-encoding\",\n \"quick-xml\",\n \"reqwest\",\n \"serde\",\n \"serde_json\",\n \"tokio\",\n \"uuid\",\n]\n\n[[package]]\nname = \"ordered-float\"\nversion = \"4.6.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951\"\ndependencies = [\n \"num-traits\",\n]\n\n[[package]]\nname = \"os_pipe\"\nversion = \"1.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"db335f4760b14ead6290116f2427bf33a14d4f0617d49f78a246de10c1831224\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"ouroboros\"\nversion = \"0.18.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59\"\ndependencies = [\n \"aliasable\",\n \"ouroboros_macro\",\n \"static_assertions\",\n]\n\n[[package]]\nname = \"ouroboros_macro\"\nversion = \"0.18.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0\"\ndependencies = [\n \"heck 0.4.1\",\n \"proc-macro2\",\n \"proc-macro2-diagnostics\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"parking\"\nversion = \"2.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba\"\n\n[[package]]\nname = \"parking_lot\"\nversion = \"0.12.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a\"\ndependencies = [\n \"lock_api\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"parking_lot_core\"\nversion = \"0.9.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"redox_syscall\",\n \"smallvec\",\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"parse-zoneinfo\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24\"\ndependencies = [\n \"regex\",\n]\n\n[[package]]\nname = \"password-hash\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166\"\ndependencies = [\n \"base64ct\",\n \"rand_core 0.6.4\",\n \"subtle\",\n]\n\n[[package]]\nname = \"pem\"\nversion = \"3.0.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3\"\ndependencies = [\n \"base64\",\n \"serde\",\n]\n\n[[package]]\nname = \"pem-rfc7468\"\nversion = \"0.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412\"\ndependencies = [\n \"base64ct\",\n]\n\n[[package]]\nname = \"percent-encoding\"\nversion = \"2.3.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220\"\n\n[[package]]\nname = \"pest\"\nversion = \"2.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4\"\ndependencies = [\n \"memchr\",\n \"ucd-trie\",\n]\n\n[[package]]\nname = \"pest_derive\"\nversion = \"2.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de\"\ndependencies = [\n \"pest\",\n \"pest_generator\",\n]\n\n[[package]]\nname = \"pest_generator\"\nversion = \"2.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843\"\ndependencies = [\n \"pest\",\n \"pest_meta\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"pest_meta\"\nversion = \"2.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a\"\ndependencies = [\n \"pest\",\n \"sha2\",\n]\n\n[[package]]\nname = \"pgvector\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fc58e2d255979a31caa7cabfa7aac654af0354220719ab7a68520ae7a91e8c0b\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"phf\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078\"\ndependencies = [\n \"phf_macros\",\n \"phf_shared\",\n]\n\n[[package]]\nname = \"phf_codegen\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a\"\ndependencies = [\n \"phf_generator\",\n \"phf_shared\",\n]\n\n[[package]]\nname = \"phf_generator\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d\"\ndependencies = [\n \"phf_shared\",\n \"rand 0.8.5\",\n]\n\n[[package]]\nname = \"phf_macros\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216\"\ndependencies = [\n \"phf_generator\",\n \"phf_shared\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"phf_shared\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5\"\ndependencies = [\n \"siphasher\",\n]\n\n[[package]]\nname = \"pin-project-lite\"\nversion = \"0.2.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b\"\n\n[[package]]\nname = \"pin-utils\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184\"\n\n[[package]]\nname = \"pkcs1\"\nversion = \"0.7.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f\"\ndependencies = [\n \"der\",\n \"pkcs8\",\n \"spki\",\n]\n\n[[package]]\nname = \"pkcs8\"\nversion = \"0.10.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7\"\ndependencies = [\n \"der\",\n \"spki\",\n]\n\n[[package]]\nname = \"pkg-config\"\nversion = \"0.3.32\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c\"\n\n[[package]]\nname = \"portable-atomic\"\nversion = \"1.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483\"\n\n[[package]]\nname = \"potential_utf\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a\"\ndependencies = [\n \"zerovec\",\n]\n\n[[package]]\nname = \"powerfmt\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391\"\n\n[[package]]\nname = \"ppv-lite86\"\nversion = \"0.2.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9\"\ndependencies = [\n \"zerocopy\",\n]\n\n[[package]]\nname = \"precomputed-hash\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c\"\n\n[[package]]\nname = \"pretty_assertions\"\nversion = \"1.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d\"\ndependencies = [\n \"diff\",\n \"yansi\",\n]\n\n[[package]]\nname = \"proc-macro-crate\"\nversion = \"3.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983\"\ndependencies = [\n \"toml_edit 0.23.6\",\n]\n\n[[package]]\nname = \"proc-macro-error-attr2\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n]\n\n[[package]]\nname = \"proc-macro-error2\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802\"\ndependencies = [\n \"proc-macro-error-attr2\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"proc-macro2\"\nversion = \"1.0.101\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de\"\ndependencies = [\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"proc-macro2-diagnostics\"\nversion = \"0.10.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"version_check\",\n \"yansi\",\n]\n\n[[package]]\nname = \"psm\"\nversion = \"0.1.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e66fcd288453b748497d8fb18bccc83a16b0518e3906d4b8df0a8d42d93dbb1c\"\ndependencies = [\n \"cc\",\n]\n\n[[package]]\nname = \"ptr_meta\"\nversion = \"0.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1\"\ndependencies = [\n \"ptr_meta_derive\",\n]\n\n[[package]]\nname = \"ptr_meta_derive\"\nversion = \"0.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"quick-xml\"\nversion = \"0.37.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb\"\ndependencies = [\n \"memchr\",\n \"serde\",\n]\n\n[[package]]\nname = \"quote\"\nversion = \"1.0.41\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1\"\ndependencies = [\n \"proc-macro2\",\n]\n\n[[package]]\nname = \"quoted_printable\"\nversion = \"0.5.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"640c9bd8497b02465aeef5375144c26062e0dcd5939dfcbb0f5db76cb8c17c73\"\n\n[[package]]\nname = \"r-efi\"\nversion = \"5.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f\"\n\n[[package]]\nname = \"radium\"\nversion = \"0.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09\"\n\n[[package]]\nname = \"rand\"\nversion = \"0.8.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404\"\ndependencies = [\n \"libc\",\n \"rand_chacha 0.3.1\",\n \"rand_core 0.6.4\",\n]\n\n[[package]]\nname = \"rand\"\nversion = \"0.9.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1\"\ndependencies = [\n \"rand_chacha 0.9.0\",\n \"rand_core 0.9.3\",\n]\n\n[[package]]\nname = \"rand_chacha\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88\"\ndependencies = [\n \"ppv-lite86\",\n \"rand_core 0.6.4\",\n]\n\n[[package]]\nname = \"rand_chacha\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb\"\ndependencies = [\n \"ppv-lite86\",\n \"rand_core 0.9.3\",\n]\n\n[[package]]\nname = \"rand_core\"\nversion = \"0.6.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c\"\ndependencies = [\n \"getrandom 0.2.16\",\n]\n\n[[package]]\nname = \"rand_core\"\nversion = \"0.9.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38\"\ndependencies = [\n \"getrandom 0.3.3\",\n]\n\n[[package]]\nname = \"redis\"\nversion = \"0.31.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0bc1ea653e0b2e097db3ebb5b7f678be339620b8041f66b30a308c1d45d36a7f\"\ndependencies = [\n \"bytes\",\n \"cfg-if\",\n \"combine\",\n \"futures-util\",\n \"itoa\",\n \"num-bigint\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"ryu\",\n \"sha1_smol\",\n \"socket2 0.5.10\",\n \"tokio\",\n \"tokio-util\",\n \"url\",\n]\n\n[[package]]\nname = \"redox_syscall\"\nversion = \"0.5.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d\"\ndependencies = [\n \"bitflags 2.9.4\",\n]\n\n[[package]]\nname = \"regex\"\nversion = \"1.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c\"\ndependencies = [\n \"aho-corasick\",\n \"memchr\",\n \"regex-automata\",\n \"regex-syntax\",\n]\n\n[[package]]\nname = \"regex-automata\"\nversion = \"0.4.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad\"\ndependencies = [\n \"aho-corasick\",\n \"memchr\",\n \"regex-syntax\",\n]\n\n[[package]]\nname = \"regex-syntax\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001\"\n\n[[package]]\nname = \"relative-path\"\nversion = \"1.9.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2\"\n\n[[package]]\nname = \"rend\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c\"\ndependencies = [\n \"bytecheck\",\n]\n\n[[package]]\nname = \"reqwest\"\nversion = \"0.12.23\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb\"\ndependencies = [\n \"base64\",\n \"bytes\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"hyper\",\n \"hyper-util\",\n \"js-sys\",\n \"log\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"serde\",\n \"serde_json\",\n \"serde_urlencoded\",\n \"sync_wrapper\",\n \"tokio\",\n \"tokio-util\",\n \"tower 0.5.2\",\n \"tower-http\",\n \"tower-service\",\n \"url\",\n \"wasm-bindgen\",\n \"wasm-bindgen-futures\",\n \"wasm-streams\",\n \"web-sys\",\n]\n\n[[package]]\nname = \"reserve-port\"\nversion = \"2.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"21918d6644020c6f6ef1993242989bf6d4952d2e025617744f184c02df51c356\"\ndependencies = [\n \"thiserror 2.0.17\",\n]\n\n[[package]]\nname = \"ring\"\nversion = \"0.17.14\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7\"\ndependencies = [\n \"cc\",\n \"cfg-if\",\n \"getrandom 0.2.16\",\n \"libc\",\n \"untrusted\",\n \"windows-sys 0.52.0\",\n]\n\n[[package]]\nname = \"rkyv\"\nversion = \"0.7.45\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b\"\ndependencies = [\n \"bitvec\",\n \"bytecheck\",\n \"bytes\",\n \"hashbrown 0.12.3\",\n \"ptr_meta\",\n \"rend\",\n \"rkyv_derive\",\n \"seahash\",\n \"tinyvec\",\n \"uuid\",\n]\n\n[[package]]\nname = \"rkyv_derive\"\nversion = \"0.7.45\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"rrgen\"\nversion = \"0.5.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ee7a7ede035354391a37e42aa4935b3d8921f0ded896d2ce44bb1a3b6dd76bab\"\ndependencies = [\n \"cruet 0.13.3\",\n \"fs-err\",\n \"glob\",\n \"heck 0.4.1\",\n \"regex\",\n \"serde\",\n \"serde_json\",\n \"serde_regex\",\n \"serde_yaml\",\n \"tera\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"rsa\"\nversion = \"0.9.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b\"\ndependencies = [\n \"const-oid\",\n \"digest\",\n \"num-bigint-dig\",\n \"num-integer\",\n \"num-traits\",\n \"pkcs1\",\n \"pkcs8\",\n \"rand_core 0.6.4\",\n \"signature\",\n \"spki\",\n \"subtle\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"rstest\"\nversion = \"0.18.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"97eeab2f3c0a199bc4be135c36c924b6590b88c377d416494288c14f2db30199\"\ndependencies = [\n \"futures\",\n \"futures-timer\",\n \"rstest_macros\",\n \"rustc_version\",\n]\n\n[[package]]\nname = \"rstest_macros\"\nversion = \"0.18.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d428f8247852f894ee1be110b375111b586d4fa431f6c46e64ba5a0dcccbe605\"\ndependencies = [\n \"cfg-if\",\n \"glob\",\n \"proc-macro2\",\n \"quote\",\n \"regex\",\n \"relative-path\",\n \"rustc_version\",\n \"syn 2.0.106\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"rust-multipart-rfc7578_2\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c839d037155ebc06a571e305af66ff9fd9063a6e662447051737e1ac75beea41\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"mime\",\n \"rand 0.9.2\",\n \"thiserror 2.0.17\",\n]\n\n[[package]]\nname = \"rust_decimal\"\nversion = \"1.38.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8975fc98059f365204d635119cf9c5a60ae67b841ed49b5422a9a7e56cdfac0\"\ndependencies = [\n \"arrayvec\",\n \"borsh\",\n \"bytes\",\n \"num-traits\",\n \"rand 0.8.5\",\n \"rkyv\",\n \"serde\",\n \"serde_json\",\n]\n\n[[package]]\nname = \"rustc-demangle\"\nversion = \"0.1.26\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace\"\n\n[[package]]\nname = \"rustc_version\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92\"\ndependencies = [\n \"semver\",\n]\n\n[[package]]\nname = \"rustls\"\nversion = \"0.23.32\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40\"\ndependencies = [\n \"log\",\n \"once_cell\",\n \"ring\",\n \"rustls-pki-types\",\n \"rustls-webpki\",\n \"subtle\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"rustls-pki-types\"\nversion = \"1.12.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79\"\ndependencies = [\n \"zeroize\",\n]\n\n[[package]]\nname = \"rustls-webpki\"\nversion = \"0.103.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf\"\ndependencies = [\n \"ring\",\n \"rustls-pki-types\",\n \"untrusted\",\n]\n\n[[package]]\nname = \"rustversion\"\nversion = \"1.0.22\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d\"\n\n[[package]]\nname = \"ryu\"\nversion = \"1.0.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f\"\n\n[[package]]\nname = \"same-file\"\nversion = \"1.0.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502\"\ndependencies = [\n \"winapi-util\",\n]\n\n[[package]]\nname = \"scopeguard\"\nversion = \"1.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49\"\n\n[[package]]\nname = \"scraper\"\nversion = \"0.21.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b0e749d29b2064585327af5038a5a8eb73aeebad4a3472e83531a436563f7208\"\ndependencies = [\n \"ahash 0.8.12\",\n \"cssparser\",\n \"ego-tree\",\n \"getopts\",\n \"html5ever\",\n \"indexmap\",\n \"precomputed-hash\",\n \"selectors\",\n \"tendril\",\n]\n\n[[package]]\nname = \"sea-bae\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f694a6ab48f14bc063cfadff30ab551d3c7e46d8f81836c51989d548f44a2a25\"\ndependencies = [\n \"heck 0.4.1\",\n \"proc-macro-error2\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"sea-orm\"\nversion = \"2.0.0-rc.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"296a092e16fbbcc3a9969eae3915ef11024b98a43f3b77ff5199bc626c462d7a\"\ndependencies = [\n \"async-stream\",\n \"async-trait\",\n \"bigdecimal\",\n \"chrono\",\n \"derive_more 2.0.1\",\n \"futures-util\",\n \"itertools\",\n \"log\",\n \"ouroboros\",\n \"pgvector\",\n \"rust_decimal\",\n \"sea-orm-macros\",\n \"sea-query\",\n \"sea-query-sqlx\",\n \"sea-schema\",\n \"serde\",\n \"serde_json\",\n \"sqlx\",\n \"strum\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tracing\",\n \"url\",\n \"uuid\",\n]\n\n[[package]]\nname = \"sea-orm-cli\"\nversion = \"2.0.0-rc.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"301f7ace977d940474b47a154a5fc453714d13e5d53bdb077330c6fc6212a31b\"\ndependencies = [\n \"chrono\",\n \"clap\",\n \"dotenvy\",\n \"glob\",\n \"indoc\",\n \"regex\",\n \"sea-schema\",\n \"sqlx\",\n \"tokio\",\n \"tracing\",\n \"tracing-subscriber\",\n \"url\",\n]\n\n[[package]]\nname = \"sea-orm-macros\"\nversion = \"2.0.0-rc.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e56ee8be52d15a801dc62a5a30d83dc718762401f7c7945b7f2730ef385b8b3d\"\ndependencies = [\n \"heck 0.5.0\",\n \"proc-macro2\",\n \"quote\",\n \"sea-bae\",\n \"syn 2.0.106\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"sea-orm-migration\"\nversion = \"2.0.0-rc.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b7444940e5b7db32f55dea6d04cfb312480e45ae07753b1391311eccd5753475\"\ndependencies = [\n \"async-trait\",\n \"clap\",\n \"dotenvy\",\n \"sea-orm\",\n \"sea-orm-cli\",\n \"sea-schema\",\n \"tracing\",\n \"tracing-subscriber\",\n]\n\n[[package]]\nname = \"sea-query\"\nversion = \"1.0.0-rc.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"30d190945ff6b2914ef0631c1933ef67ee142b15f00b72d40bf241147d24b522\"\ndependencies = [\n \"bigdecimal\",\n \"chrono\",\n \"inherent\",\n \"ordered-float\",\n \"rust_decimal\",\n \"sea-query-derive\",\n \"serde_json\",\n \"time\",\n \"uuid\",\n]\n\n[[package]]\nname = \"sea-query-derive\"\nversion = \"1.0.0-rc.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"217e9422de35f26c16c5f671fce3c075a65e10322068dbc66078428634af6195\"\ndependencies = [\n \"darling\",\n \"heck 0.4.1\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"thiserror 2.0.17\",\n]\n\n[[package]]\nname = \"sea-query-sqlx\"\nversion = \"0.8.0-rc.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"68873fa1776b4c25a26e7679f8ee22332978c721168ec1b0b32b6583d5a9381d\"\ndependencies = [\n \"bigdecimal\",\n \"chrono\",\n \"rust_decimal\",\n \"sea-query\",\n \"serde_json\",\n \"sqlx\",\n \"time\",\n \"uuid\",\n]\n\n[[package]]\nname = \"sea-schema\"\nversion = \"0.17.0-rc.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9d00bab58be7fcc3a2dbc279099fcd5952d49e45d51444ebe8d5b7e7c4343df3\"\ndependencies = [\n \"async-trait\",\n \"sea-query\",\n \"sea-query-sqlx\",\n \"sea-schema-derive\",\n \"sqlx\",\n]\n\n[[package]]\nname = \"sea-schema-derive\"\nversion = \"0.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"debdc8729c37fdbf88472f97fd470393089f997a909e535ff67c544d18cfccf0\"\ndependencies = [\n \"heck 0.4.1\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"seahash\"\nversion = \"4.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b\"\n\n[[package]]\nname = \"selectors\"\nversion = \"0.26.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fd568a4c9bb598e291a08244a5c1f5a8a6650bee243b5b0f8dbb3d9cc1d87fe8\"\ndependencies = [\n \"bitflags 2.9.4\",\n \"cssparser\",\n \"derive_more 0.99.20\",\n \"fxhash\",\n \"log\",\n \"new_debug_unreachable\",\n \"phf\",\n \"phf_codegen\",\n \"precomputed-hash\",\n \"servo_arc\",\n \"smallvec\",\n]\n\n[[package]]\nname = \"semver\"\nversion = \"1.0.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2\"\n\n[[package]]\nname = \"serde\"\nversion = \"1.0.228\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e\"\ndependencies = [\n \"serde_core\",\n \"serde_derive\",\n]\n\n[[package]]\nname = \"serde_core\"\nversion = \"1.0.228\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad\"\ndependencies = [\n \"serde_derive\",\n]\n\n[[package]]\nname = \"serde_derive\"\nversion = \"1.0.228\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"serde_json\"\nversion = \"1.0.145\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c\"\ndependencies = [\n \"itoa\",\n \"memchr\",\n \"ryu\",\n \"serde\",\n \"serde_core\",\n]\n\n[[package]]\nname = \"serde_path_to_error\"\nversion = \"0.1.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457\"\ndependencies = [\n \"itoa\",\n \"serde\",\n \"serde_core\",\n]\n\n[[package]]\nname = \"serde_regex\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf\"\ndependencies = [\n \"regex\",\n \"serde\",\n]\n\n[[package]]\nname = \"serde_spanned\"\nversion = \"0.6.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"serde_urlencoded\"\nversion = \"0.7.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd\"\ndependencies = [\n \"form_urlencoded\",\n \"itoa\",\n \"ryu\",\n \"serde\",\n]\n\n[[package]]\nname = \"serde_variant\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0a0068df419f9d9b6488fdded3f1c818522cdea328e02ce9d9f147380265a432\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"serde_yaml\"\nversion = \"0.9.34+deprecated\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47\"\ndependencies = [\n \"indexmap\",\n \"itoa\",\n \"ryu\",\n \"serde\",\n \"unsafe-libyaml\",\n]\n\n[[package]]\nname = \"serial_test\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d\"\ndependencies = [\n \"dashmap 5.5.3\",\n \"futures\",\n \"lazy_static\",\n \"log\",\n \"parking_lot\",\n \"serial_test_derive\",\n]\n\n[[package]]\nname = \"serial_test_derive\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"servo_arc\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"204ea332803bd95a0b60388590d59cf6468ec9becf626e2451f1d26a1d972de4\"\ndependencies = [\n \"stable_deref_trait\",\n]\n\n[[package]]\nname = \"sha1\"\nversion = \"0.10.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba\"\ndependencies = [\n \"cfg-if\",\n \"cpufeatures\",\n \"digest\",\n]\n\n[[package]]\nname = \"sha1_smol\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d\"\n\n[[package]]\nname = \"sha2\"\nversion = \"0.10.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283\"\ndependencies = [\n \"cfg-if\",\n \"cpufeatures\",\n \"digest\",\n]\n\n[[package]]\nname = \"sharded-slab\"\nversion = \"0.1.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6\"\ndependencies = [\n \"lazy_static\",\n]\n\n[[package]]\nname = \"shared_child\"\nversion = \"1.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e362d9935bc50f019969e2f9ecd66786612daae13e8f277be7bfb66e8bed3f7\"\ndependencies = [\n \"libc\",\n \"sigchld\",\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"shared_thread\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"52b86057fcb5423f5018e331ac04623e32d6b5ce85e33300f92c79a1973928b0\"\n\n[[package]]\nname = \"shlex\"\nversion = \"1.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64\"\n\n[[package]]\nname = \"sigchld\"\nversion = \"0.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47106eded3c154e70176fc83df9737335c94ce22f821c32d17ed1db1f83badb1\"\ndependencies = [\n \"libc\",\n \"os_pipe\",\n \"signal-hook\",\n]\n\n[[package]]\nname = \"signal-hook\"\nversion = \"0.3.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2\"\ndependencies = [\n \"libc\",\n \"signal-hook-registry\",\n]\n\n[[package]]\nname = \"signal-hook-registry\"\nversion = \"1.4.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"signature\"\nversion = \"2.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de\"\ndependencies = [\n \"digest\",\n \"rand_core 0.6.4\",\n]\n\n[[package]]\nname = \"simd-adler32\"\nversion = \"0.3.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe\"\n\n[[package]]\nname = \"simdutf8\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e\"\n\n[[package]]\nname = \"similar\"\nversion = \"2.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa\"\n\n[[package]]\nname = \"simple_asn1\"\nversion = \"0.6.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb\"\ndependencies = [\n \"num-bigint\",\n \"num-traits\",\n \"thiserror 2.0.17\",\n \"time\",\n]\n\n[[package]]\nname = \"siphasher\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d\"\n\n[[package]]\nname = \"slab\"\nversion = \"0.4.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589\"\n\n[[package]]\nname = \"slug\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724\"\ndependencies = [\n \"deunicode\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"smallvec\"\nversion = \"1.15.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"socket2\"\nversion = \"0.5.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.52.0\",\n]\n\n[[package]]\nname = \"socket2\"\nversion = \"0.6.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"spin\"\nversion = \"0.9.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67\"\ndependencies = [\n \"lock_api\",\n]\n\n[[package]]\nname = \"spki\"\nversion = \"0.7.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d\"\ndependencies = [\n \"base64ct\",\n \"der\",\n]\n\n[[package]]\nname = \"sqlx\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc\"\ndependencies = [\n \"sqlx-core\",\n \"sqlx-macros\",\n \"sqlx-mysql\",\n \"sqlx-postgres\",\n \"sqlx-sqlite\",\n]\n\n[[package]]\nname = \"sqlx-core\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6\"\ndependencies = [\n \"base64\",\n \"bigdecimal\",\n \"bytes\",\n \"chrono\",\n \"crc\",\n \"crossbeam-queue\",\n \"either\",\n \"event-listener\",\n \"futures-core\",\n \"futures-intrusive\",\n \"futures-io\",\n \"futures-util\",\n \"hashbrown 0.15.5\",\n \"hashlink\",\n \"indexmap\",\n \"log\",\n \"memchr\",\n \"once_cell\",\n \"percent-encoding\",\n \"rust_decimal\",\n \"rustls\",\n \"serde\",\n \"serde_json\",\n \"sha2\",\n \"smallvec\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tokio\",\n \"tokio-stream\",\n \"tracing\",\n \"url\",\n \"uuid\",\n \"webpki-roots 0.26.11\",\n]\n\n[[package]]\nname = \"sqlx-macros\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"sqlx-core\",\n \"sqlx-macros-core\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"sqlx-macros-core\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b\"\ndependencies = [\n \"dotenvy\",\n \"either\",\n \"heck 0.5.0\",\n \"hex\",\n \"once_cell\",\n \"proc-macro2\",\n \"quote\",\n \"serde\",\n \"serde_json\",\n \"sha2\",\n \"sqlx-core\",\n \"sqlx-mysql\",\n \"sqlx-postgres\",\n \"sqlx-sqlite\",\n \"syn 2.0.106\",\n \"tokio\",\n \"url\",\n]\n\n[[package]]\nname = \"sqlx-mysql\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526\"\ndependencies = [\n \"atoi\",\n \"base64\",\n \"bigdecimal\",\n \"bitflags 2.9.4\",\n \"byteorder\",\n \"bytes\",\n \"chrono\",\n \"crc\",\n \"digest\",\n \"dotenvy\",\n \"either\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-io\",\n \"futures-util\",\n \"generic-array\",\n \"hex\",\n \"hkdf\",\n \"hmac\",\n \"itoa\",\n \"log\",\n \"md-5\",\n \"memchr\",\n \"once_cell\",\n \"percent-encoding\",\n \"rand 0.8.5\",\n \"rsa\",\n \"rust_decimal\",\n \"serde\",\n \"sha1\",\n \"sha2\",\n \"smallvec\",\n \"sqlx-core\",\n \"stringprep\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tracing\",\n \"uuid\",\n \"whoami\",\n]\n\n[[package]]\nname = \"sqlx-postgres\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46\"\ndependencies = [\n \"atoi\",\n \"base64\",\n \"bigdecimal\",\n \"bitflags 2.9.4\",\n \"byteorder\",\n \"chrono\",\n \"crc\",\n \"dotenvy\",\n \"etcetera\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-util\",\n \"hex\",\n \"hkdf\",\n \"hmac\",\n \"home\",\n \"itoa\",\n \"log\",\n \"md-5\",\n \"memchr\",\n \"num-bigint\",\n \"once_cell\",\n \"rand 0.8.5\",\n \"rust_decimal\",\n \"serde\",\n \"serde_json\",\n \"sha2\",\n \"smallvec\",\n \"sqlx-core\",\n \"stringprep\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tracing\",\n \"uuid\",\n \"whoami\",\n]\n\n[[package]]\nname = \"sqlx-sqlite\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea\"\ndependencies = [\n \"atoi\",\n \"chrono\",\n \"flume\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-executor\",\n \"futures-intrusive\",\n \"futures-util\",\n \"libsqlite3-sys\",\n \"log\",\n \"percent-encoding\",\n \"serde\",\n \"serde_urlencoded\",\n \"sqlx-core\",\n \"thiserror 2.0.17\",\n \"time\",\n \"tracing\",\n \"url\",\n \"uuid\",\n]\n\n[[package]]\nname = \"stable_deref_trait\"\nversion = \"1.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3\"\n\n[[package]]\nname = \"stacker\"\nversion = \"0.1.22\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e1f8b29fb42aafcea4edeeb6b2f2d7ecd0d969c48b4cf0d2e64aafc471dd6e59\"\ndependencies = [\n \"cc\",\n \"cfg-if\",\n \"libc\",\n \"psm\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"static_assertions\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f\"\n\n[[package]]\nname = \"string_cache\"\nversion = \"0.8.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f\"\ndependencies = [\n \"new_debug_unreachable\",\n \"parking_lot\",\n \"phf_shared\",\n \"precomputed-hash\",\n \"serde\",\n]\n\n[[package]]\nname = \"string_cache_codegen\"\nversion = \"0.5.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0\"\ndependencies = [\n \"phf_generator\",\n \"phf_shared\",\n \"proc-macro2\",\n \"quote\",\n]\n\n[[package]]\nname = \"stringprep\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1\"\ndependencies = [\n \"unicode-bidi\",\n \"unicode-normalization\",\n \"unicode-properties\",\n]\n\n[[package]]\nname = \"strsim\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f\"\n\n[[package]]\nname = \"strum\"\nversion = \"0.27.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf\"\n\n[[package]]\nname = \"subtle\"\nversion = \"2.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292\"\n\n[[package]]\nname = \"syn\"\nversion = \"1.0.109\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"syn\"\nversion = \"2.0.106\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"sync_wrapper\"\nversion = \"1.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263\"\ndependencies = [\n \"futures-core\",\n]\n\n[[package]]\nname = \"synstructure\"\nversion = \"0.13.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"tagptr\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417\"\n\n[[package]]\nname = \"tap\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369\"\n\n[[package]]\nname = \"tendril\"\nversion = \"0.4.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0\"\ndependencies = [\n \"futf\",\n \"mac\",\n \"utf-8\",\n]\n\n[[package]]\nname = \"tera\"\nversion = \"1.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ab9d851b45e865f178319da0abdbfe6acbc4328759ff18dafc3a41c16b4cd2ee\"\ndependencies = [\n \"chrono\",\n \"chrono-tz\",\n \"globwalk\",\n \"humansize\",\n \"lazy_static\",\n \"percent-encoding\",\n \"pest\",\n \"pest_derive\",\n \"rand 0.8.5\",\n \"regex\",\n \"serde\",\n \"serde_json\",\n \"slug\",\n \"unic-segment\",\n]\n\n[[package]]\nname = \"thiserror\"\nversion = \"1.0.69\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52\"\ndependencies = [\n \"thiserror-impl 1.0.69\",\n]\n\n[[package]]\nname = \"thiserror\"\nversion = \"2.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8\"\ndependencies = [\n \"thiserror-impl 2.0.17\",\n]\n\n[[package]]\nname = \"thiserror-impl\"\nversion = \"1.0.69\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"thiserror-impl\"\nversion = \"2.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"thread_local\"\nversion = \"1.1.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185\"\ndependencies = [\n \"cfg-if\",\n]\n\n[[package]]\nname = \"time\"\nversion = \"0.3.44\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d\"\ndependencies = [\n \"deranged\",\n \"itoa\",\n \"num-conv\",\n \"powerfmt\",\n \"serde\",\n \"time-core\",\n \"time-macros\",\n]\n\n[[package]]\nname = \"time-core\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b\"\n\n[[package]]\nname = \"time-macros\"\nversion = \"0.2.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3\"\ndependencies = [\n \"num-conv\",\n \"time-core\",\n]\n\n[[package]]\nname = \"tinystr\"\nversion = \"0.8.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b\"\ndependencies = [\n \"displaydoc\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"tinyvec\"\nversion = \"1.10.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa\"\ndependencies = [\n \"tinyvec_macros\",\n]\n\n[[package]]\nname = \"tinyvec_macros\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20\"\n\n[[package]]\nname = \"tokio\"\nversion = \"1.47.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038\"\ndependencies = [\n \"backtrace\",\n \"bytes\",\n \"io-uring\",\n \"libc\",\n \"mio\",\n \"pin-project-lite\",\n \"signal-hook-registry\",\n \"slab\",\n \"socket2 0.6.0\",\n \"tokio-macros\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"tokio-cron-scheduler\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f2594dd7c2abbbafbb1c78d167fd10860dc7bd75f814cb051a1e0d3e796b9702\"\ndependencies = [\n \"chrono\",\n \"cron\",\n \"num-derive\",\n \"num-traits\",\n \"tokio\",\n \"tracing\",\n \"uuid\",\n]\n\n[[package]]\nname = \"tokio-macros\"\nversion = \"2.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"tokio-rustls\"\nversion = \"0.26.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61\"\ndependencies = [\n \"rustls\",\n \"tokio\",\n]\n\n[[package]]\nname = \"tokio-stream\"\nversion = \"0.1.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047\"\ndependencies = [\n \"futures-core\",\n \"pin-project-lite\",\n \"tokio\",\n]\n\n[[package]]\nname = \"tokio-util\"\nversion = \"0.7.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"futures-sink\",\n \"pin-project-lite\",\n \"tokio\",\n]\n\n[[package]]\nname = \"toml\"\nversion = \"0.8.23\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362\"\ndependencies = [\n \"serde\",\n \"serde_spanned\",\n \"toml_datetime 0.6.11\",\n \"toml_edit 0.22.27\",\n]\n\n[[package]]\nname = \"toml_datetime\"\nversion = \"0.6.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"toml_datetime\"\nversion = \"0.7.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1\"\ndependencies = [\n \"serde_core\",\n]\n\n[[package]]\nname = \"toml_edit\"\nversion = \"0.22.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a\"\ndependencies = [\n \"indexmap\",\n \"serde\",\n \"serde_spanned\",\n \"toml_datetime 0.6.11\",\n \"toml_write\",\n \"winnow\",\n]\n\n[[package]]\nname = \"toml_edit\"\nversion = \"0.23.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b\"\ndependencies = [\n \"indexmap\",\n \"toml_datetime 0.7.2\",\n \"toml_parser\",\n \"winnow\",\n]\n\n[[package]]\nname = \"toml_parser\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627\"\ndependencies = [\n \"winnow\",\n]\n\n[[package]]\nname = \"toml_write\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801\"\n\n[[package]]\nname = \"tower\"\nversion = \"0.4.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c\"\ndependencies = [\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"tower\"\nversion = \"0.5.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9\"\ndependencies = [\n \"futures-core\",\n \"futures-util\",\n \"pin-project-lite\",\n \"sync_wrapper\",\n \"tokio\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"tower-http\"\nversion = \"0.6.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2\"\ndependencies = [\n \"async-compression\",\n \"bitflags 2.9.4\",\n \"bytes\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"http-range-header\",\n \"httpdate\",\n \"iri-string\",\n \"mime\",\n \"mime_guess\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"tokio\",\n \"tokio-util\",\n \"tower 0.5.2\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"tower-layer\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e\"\n\n[[package]]\nname = \"tower-service\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3\"\n\n[[package]]\nname = \"tracing\"\nversion = \"0.1.41\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0\"\ndependencies = [\n \"log\",\n \"pin-project-lite\",\n \"tracing-attributes\",\n \"tracing-core\",\n]\n\n[[package]]\nname = \"tracing-appender\"\nversion = \"0.2.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf\"\ndependencies = [\n \"crossbeam-channel\",\n \"thiserror 1.0.69\",\n \"time\",\n \"tracing-subscriber\",\n]\n\n[[package]]\nname = \"tracing-attributes\"\nversion = \"0.1.30\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"tracing-core\"\nversion = \"0.1.34\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678\"\ndependencies = [\n \"once_cell\",\n \"valuable\",\n]\n\n[[package]]\nname = \"tracing-log\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3\"\ndependencies = [\n \"log\",\n \"once_cell\",\n \"tracing-core\",\n]\n\n[[package]]\nname = \"tracing-serde\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1\"\ndependencies = [\n \"serde\",\n \"tracing-core\",\n]\n\n[[package]]\nname = \"tracing-subscriber\"\nversion = \"0.3.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5\"\ndependencies = [\n \"matchers\",\n \"nu-ansi-term\",\n \"once_cell\",\n \"regex-automata\",\n \"serde\",\n \"serde_json\",\n \"sharded-slab\",\n \"smallvec\",\n \"thread_local\",\n \"tracing\",\n \"tracing-core\",\n \"tracing-log\",\n \"tracing-serde\",\n]\n\n[[package]]\nname = \"tree-fs\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5c6115680fa5fdb99b4ff19c9c3217e75116d2bb0eae82458c4e1818be6a10c7\"\ndependencies = [\n \"rand 0.9.2\",\n \"serde\",\n]\n\n[[package]]\nname = \"try-lock\"\nversion = \"0.2.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b\"\n\n[[package]]\nname = \"typenum\"\nversion = \"1.19.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb\"\n\n[[package]]\nname = \"ucd-trie\"\nversion = \"0.1.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971\"\n\n[[package]]\nname = \"ulid\"\nversion = \"1.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"470dbf6591da1b39d43c14523b2b469c86879a53e8b758c8e090a470fe7b1fbe\"\ndependencies = [\n \"rand 0.9.2\",\n \"web-time\",\n]\n\n[[package]]\nname = \"unic-char-property\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221\"\ndependencies = [\n \"unic-char-range\",\n]\n\n[[package]]\nname = \"unic-char-range\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc\"\n\n[[package]]\nname = \"unic-common\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc\"\n\n[[package]]\nname = \"unic-segment\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23\"\ndependencies = [\n \"unic-ucd-segment\",\n]\n\n[[package]]\nname = \"unic-ucd-segment\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700\"\ndependencies = [\n \"unic-char-property\",\n \"unic-char-range\",\n \"unic-ucd-version\",\n]\n\n[[package]]\nname = \"unic-ucd-version\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4\"\ndependencies = [\n \"unic-common\",\n]\n\n[[package]]\nname = \"unicase\"\nversion = \"2.8.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539\"\n\n[[package]]\nname = \"unicode-bidi\"\nversion = \"0.3.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5\"\n\n[[package]]\nname = \"unicode-ident\"\nversion = \"1.0.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d\"\n\n[[package]]\nname = \"unicode-normalization\"\nversion = \"0.1.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956\"\ndependencies = [\n \"tinyvec\",\n]\n\n[[package]]\nname = \"unicode-properties\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0\"\n\n[[package]]\nname = \"unicode-width\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254\"\n\n[[package]]\nname = \"unicode-xid\"\nversion = \"0.2.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853\"\n\n[[package]]\nname = \"unsafe-libyaml\"\nversion = \"0.2.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861\"\n\n[[package]]\nname = \"untrusted\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1\"\n\n[[package]]\nname = \"url\"\nversion = \"2.5.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b\"\ndependencies = [\n \"form_urlencoded\",\n \"idna\",\n \"percent-encoding\",\n \"serde\",\n]\n\n[[package]]\nname = \"utf-8\"\nversion = \"0.7.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9\"\n\n[[package]]\nname = \"utf8-width\"\nversion = \"0.1.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3\"\n\n[[package]]\nname = \"utf8_iter\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be\"\n\n[[package]]\nname = \"utf8parse\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821\"\n\n[[package]]\nname = \"uuid\"\nversion = \"1.18.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2\"\ndependencies = [\n \"getrandom 0.3.3\",\n \"js-sys\",\n \"rand 0.9.2\",\n \"serde\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"validator\"\nversion = \"0.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"43fb22e1a008ece370ce08a3e9e4447a910e92621bb49b85d6e48a45397e7cfa\"\ndependencies = [\n \"idna\",\n \"once_cell\",\n \"regex\",\n \"serde\",\n \"serde_derive\",\n \"serde_json\",\n \"url\",\n \"validator_derive\",\n]\n\n[[package]]\nname = \"validator_derive\"\nversion = \"0.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b7df16e474ef958526d1205f6dda359fdfab79d9aa6d54bafcb92dcd07673dca\"\ndependencies = [\n \"darling\",\n \"once_cell\",\n \"proc-macro-error2\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"valuable\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65\"\n\n[[package]]\nname = \"vcpkg\"\nversion = \"0.2.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426\"\n\n[[package]]\nname = \"version_check\"\nversion = \"0.9.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a\"\n\n[[package]]\nname = \"walkdir\"\nversion = \"2.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b\"\ndependencies = [\n \"same-file\",\n \"winapi-util\",\n]\n\n[[package]]\nname = \"want\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e\"\ndependencies = [\n \"try-lock\",\n]\n\n[[package]]\nname = \"wasi\"\nversion = \"0.11.1+wasi-snapshot-preview1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b\"\n\n[[package]]\nname = \"wasi\"\nversion = \"0.14.7+wasi-0.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c\"\ndependencies = [\n \"wasip2\",\n]\n\n[[package]]\nname = \"wasip2\"\nversion = \"1.0.1+wasi-0.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7\"\ndependencies = [\n \"wit-bindgen\",\n]\n\n[[package]]\nname = \"wasite\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b\"\n\n[[package]]\nname = \"wasm-bindgen\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d\"\ndependencies = [\n \"cfg-if\",\n \"once_cell\",\n \"rustversion\",\n \"wasm-bindgen-macro\",\n \"wasm-bindgen-shared\",\n]\n\n[[package]]\nname = \"wasm-bindgen-backend\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19\"\ndependencies = [\n \"bumpalo\",\n \"log\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"wasm-bindgen-shared\",\n]\n\n[[package]]\nname = \"wasm-bindgen-futures\"\nversion = \"0.4.54\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c\"\ndependencies = [\n \"cfg-if\",\n \"js-sys\",\n \"once_cell\",\n \"wasm-bindgen\",\n \"web-sys\",\n]\n\n[[package]]\nname = \"wasm-bindgen-macro\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119\"\ndependencies = [\n \"quote\",\n \"wasm-bindgen-macro-support\",\n]\n\n[[package]]\nname = \"wasm-bindgen-macro-support\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"wasm-bindgen-backend\",\n \"wasm-bindgen-shared\",\n]\n\n[[package]]\nname = \"wasm-bindgen-shared\"\nversion = \"0.2.104\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1\"\ndependencies = [\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"wasm-streams\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65\"\ndependencies = [\n \"futures-util\",\n \"js-sys\",\n \"wasm-bindgen\",\n \"wasm-bindgen-futures\",\n \"web-sys\",\n]\n\n[[package]]\nname = \"web-sys\"\nversion = \"0.3.81\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120\"\ndependencies = [\n \"js-sys\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"web-time\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb\"\ndependencies = [\n \"js-sys\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"webpki-roots\"\nversion = \"0.26.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9\"\ndependencies = [\n \"webpki-roots 1.0.2\",\n]\n\n[[package]]\nname = \"webpki-roots\"\nversion = \"1.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2\"\ndependencies = [\n \"rustls-pki-types\",\n]\n\n[[package]]\nname = \"whoami\"\nversion = \"1.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d\"\ndependencies = [\n \"libredox\",\n \"wasite\",\n]\n\n[[package]]\nname = \"winapi-util\"\nversion = \"0.1.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22\"\ndependencies = [\n \"windows-sys 0.61.2\",\n]\n\n[[package]]\nname = \"windows-core\"\nversion = \"0.62.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb\"\ndependencies = [\n \"windows-implement\",\n \"windows-interface\",\n \"windows-link 0.2.1\",\n \"windows-result\",\n \"windows-strings\",\n]\n\n[[package]]\nname = \"windows-implement\"\nversion = \"0.60.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"windows-interface\"\nversion = \"0.59.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"windows-link\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a\"\n\n[[package]]\nname = \"windows-link\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5\"\n\n[[package]]\nname = \"windows-result\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5\"\ndependencies = [\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"windows-strings\"\nversion = \"0.5.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091\"\ndependencies = [\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.48.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9\"\ndependencies = [\n \"windows-targets 0.48.5\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.52.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d\"\ndependencies = [\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.59.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b\"\ndependencies = [\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.60.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb\"\ndependencies = [\n \"windows-targets 0.53.5\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.61.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc\"\ndependencies = [\n \"windows-link 0.2.1\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c\"\ndependencies = [\n \"windows_aarch64_gnullvm 0.48.5\",\n \"windows_aarch64_msvc 0.48.5\",\n \"windows_i686_gnu 0.48.5\",\n \"windows_i686_msvc 0.48.5\",\n \"windows_x86_64_gnu 0.48.5\",\n \"windows_x86_64_gnullvm 0.48.5\",\n \"windows_x86_64_msvc 0.48.5\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973\"\ndependencies = [\n \"windows_aarch64_gnullvm 0.52.6\",\n \"windows_aarch64_msvc 0.52.6\",\n \"windows_i686_gnu 0.52.6\",\n \"windows_i686_gnullvm 0.52.6\",\n \"windows_i686_msvc 0.52.6\",\n \"windows_x86_64_gnu 0.52.6\",\n \"windows_x86_64_gnullvm 0.52.6\",\n \"windows_x86_64_msvc 0.52.6\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.53.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3\"\ndependencies = [\n \"windows-link 0.2.1\",\n \"windows_aarch64_gnullvm 0.53.1\",\n \"windows_aarch64_msvc 0.53.1\",\n \"windows_i686_gnu 0.53.1\",\n \"windows_i686_gnullvm 0.53.1\",\n \"windows_i686_msvc 0.53.1\",\n \"windows_x86_64_gnu 0.53.1\",\n \"windows_x86_64_gnullvm 0.53.1\",\n \"windows_x86_64_msvc 0.53.1\",\n]\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8\"\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3\"\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3\"\n\n[[package]]\nname = \"windows_i686_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66\"\n\n[[package]]\nname = \"windows_i686_gnullvm\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.53.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650\"\n\n[[package]]\nname = \"winnow\"\nversion = \"0.7.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"wit-bindgen\"\nversion = \"0.46.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59\"\n\n[[package]]\nname = \"writeable\"\nversion = \"0.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb\"\n\n[[package]]\nname = \"wyz\"\nversion = \"0.5.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed\"\ndependencies = [\n \"tap\",\n]\n\n[[package]]\nname = \"yansi\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049\"\n\n[[package]]\nname = \"yoke\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc\"\ndependencies = [\n \"serde\",\n \"stable_deref_trait\",\n \"yoke-derive\",\n \"zerofrom\",\n]\n\n[[package]]\nname = \"yoke-derive\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"synstructure\",\n]\n\n[[package]]\nname = \"zerocopy\"\nversion = \"0.8.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c\"\ndependencies = [\n \"zerocopy-derive\",\n]\n\n[[package]]\nname = \"zerocopy-derive\"\nversion = \"0.8.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"zerofrom\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5\"\ndependencies = [\n \"zerofrom-derive\",\n]\n\n[[package]]\nname = \"zerofrom-derive\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n \"synstructure\",\n]\n\n[[package]]\nname = \"zeroize\"\nversion = \"1.8.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0\"\n\n[[package]]\nname = \"zerotrie\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595\"\ndependencies = [\n \"displaydoc\",\n \"yoke\",\n \"zerofrom\",\n]\n\n[[package]]\nname = \"zerovec\"\nversion = \"0.11.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b\"\ndependencies = [\n \"yoke\",\n \"zerofrom\",\n \"zerovec-derive\",\n]\n\n[[package]]\nname = \"zerovec-derive\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.106\",\n]\n\n[[package]]\nname = \"zstd\"\nversion = \"0.13.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a\"\ndependencies = [\n \"zstd-safe\",\n]\n\n[[package]]\nname = \"zstd-safe\"\nversion = \"7.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d\"\ndependencies = [\n \"zstd-sys\",\n]\n\n[[package]]\nname = \"zstd-sys\"\nversion = \"2.0.16+zstd.1.5.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748\"\ndependencies = [\n \"cc\",\n \"pkg-config\",\n]\n"
  },
  {
    "path": "examples/loco_starter/Cargo.toml",
    "content": "[workspace]\n\n[package]\nedition      = \"2024\"\nname         = \"loco_starter\"\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n\nloco-rs   = { version = \"0.16\" }\nmigration = { path = \"migration\" }\n\nasync-trait        = \"0.1.74\"\naxum               = { version = \"0.8\", features = [\"multipart\"] }\nchrono             = \"0.4\"\neyre               = \"0.6\"\ninclude_dir        = \"0.7\"\nserde              = { version = \"1\", features = [\"derive\"] }\nserde_json         = \"1\"\ntokio              = { version = \"1.33.0\", default-features = false }\ntokio-util         = \"0.7.11\"\ntracing            = \"0.1.40\"\ntracing-subscriber = { version = \"0.3.17\", features = [\"env-filter\", \"json\"] }\nuuid               = { version = \"1.6.0\", features = [\"v4\"] }\nvalidator          = { version = \"0.20\" }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"sqlx-sqlite\",\n    \"sqlx-postgres\",\n    \"runtime-tokio-rustls\",\n    \"macros\",\n]\nversion = \"~2.0.0-rc.37\" # sea-orm version\n\n[[bin]]\nname              = \"loco_starter-cli\"\npath              = \"src/bin/main.rs\"\nrequired-features = []\n\n[dev-dependencies]\ninsta       = { version = \"1.34.0\", features = [\"redactions\", \"yaml\", \"filters\"] }\nloco-rs     = { version = \"0.16\", features = [\"testing\"] }\nrstest      = \"0.18.2\"\nserial_test = \"2.0.0\"\n\n[patch.crates-io]\nloco-rs = { git = \"https://github.com/SeaQL/loco\", branch = \"master\" }\n"
  },
  {
    "path": "examples/loco_starter/README.md",
    "content": "# Getting Started with Loco & SeaORM\n\nThis is an REST notepad backend based on the Loco starter template, with addition of a new REST endpoint to handle file uploads.\n\nRead The full tutorial [here](https://www.sea-ql.org/blog/2024-05-28-getting-started-with-loco-seaorm/). The documentation of the REST API is available [here](https://documenter.getpostman.com/view/34752358/2sA3QmEF5q).\n\n![Screenshot App](Screenshot-App.png)\n\n![Screenshot API](Screenshot-API.png)\n"
  },
  {
    "path": "examples/loco_starter/config/development.yaml",
    "content": "# Loco configuration file documentation\n\n# Application logging configuration\nlogger:\n  # Enable or disable logging.\n  enable: true\n  # Enable pretty backtrace (sets RUST_BACKTRACE=1)\n  pretty_backtrace: true\n  # Log level, options: trace, debug, info, warn or error.\n  level: debug\n  # Define the logging format. options: compact, pretty or Json\n  format: compact\n  # By default the logger has filtering only logs that came from your code or logs that came from `loco` framework. to see all third party libraries\n  # Uncomment the line below to override to see all third party libraries you can enable this config and override the logger filters.\n  # override_filter: trace\n\n# Web server configuration\nserver:\n  # Port on which the server will listen. the server binding is 0.0.0.0:{PORT}\n  port: 3000\n  # The UI hostname or IP address that mailers will point to.\n  host: http://localhost\n  # Out of the box middleware configuration. to disable middleware you can changed the `enable` field to `false` of comment the middleware block\n  middlewares:\n    # Enable Etag cache header middleware\n    etag:\n      enable: true\n    # Allows to limit the payload size request. payload that bigger than this file will blocked the request.\n    limit_payload:\n      # Enable/Disable the middleware.\n      enable: true\n      # the limit size. can be b,kb,kib,mb,mib,gb,gib\n      body_limit: 5mb\n    # Generating a unique request ID and enhancing logging with additional information such as the start and completion of request processing, latency, status code, and other request details.\n    logger:\n      # Enable/Disable the middleware.\n      enable: true\n    # when your code is panicked, the request still returns 500 status code.\n    catch_panic:\n      # Enable/Disable the middleware.\n      enable: true\n    # Timeout for incoming requests middleware. requests that take more time from the configuration will cute and 408 status code will returned.\n    timeout_request:\n      # Enable/Disable the middleware.\n      enable: false\n      # Duration time in milliseconds.\n      timeout: 5000\n    cors:\n      enable: true\n      # Set the value of the [`Access-Control-Allow-Origin`][mdn] header\n      # allow_origins:\n      #   - https://loco.rs\n      # Set the value of the [`Access-Control-Allow-Headers`][mdn] header\n      # allow_headers:\n      # - Content-Type\n      # Set the value of the [`Access-Control-Allow-Methods`][mdn] header\n      # allow_methods:\n      #   - POST\n      # Set the value of the [`Access-Control-Max-Age`][mdn] header in seconds\n      # max_age: 3600\n\n# Worker Configuration\nworkers:\n  # specifies the worker mode. Options:\n  #   - BackgroundQueue - Workers operate asynchronously in the background, processing queued.\n  #   - ForegroundBlocking - Workers operate in the foreground and block until tasks are completed.\n  #   - BackgroundAsync - Workers operate asynchronously in the background, processing tasks with async capabilities.\n  mode: BackgroundQueue\n\n# Mailer Configuration.\nmailer:\n  # SMTP mailer configuration.\n  smtp:\n    # Enable/Disable smtp mailer.\n    enable: true\n    # SMTP server host. e.x localhost, smtp.gmail.com\n    host: {{ get_env(name=\"MAILER_HOST\", default=\"localhost\") }}\n    # SMTP server port\n    port: 1025\n    # Use secure connection (SSL/TLS).\n    secure: false\n    # auth:\n    #   user:\n    #   password:\n\n# Initializers Configuration\n# initializers:\n#  oauth2:\n#    authorization_code: # Authorization code grant type\n#      - client_identifier: google # Identifier for the OAuth2 provider. Replace 'google' with your provider's name if different, must be unique within the oauth2 config.\n#        ... other fields\n\n# Database Configuration\ndatabase:\n  # Database connection URI\n  uri: {{ get_env(name=\"DATABASE_URL\", default=\"postgres://loco:loco@localhost:5432/loco_starter_development\") }}\n  # When enabled, the sql query will be logged.\n  enable_logging: false\n  # Set the timeout duration when acquiring a connection.\n  connect_timeout: 500\n  # Set the idle duration before closing a connection.\n  idle_timeout: 500\n  # Minimum number of connections for a pool.\n  min_connections: 1\n  # Maximum number of connections for a pool.\n  max_connections: 1\n  # Run migration up when application loaded\n  auto_migrate: true\n  # Truncate database when application loaded. This is a dangerous operation, make sure that you using this flag only on dev environments or test mode\n  dangerously_truncate: false\n  # Recreating schema when application loaded.  This is a dangerous operation, make sure that you using this flag only on dev environments or test mode\n  dangerously_recreate: false\n\n# Redis Configuration\nredis:\n  # Redis connection URI\n  uri: {{ get_env(name=\"REDIS_URL\", default=\"redis://127.0.0.1\") }}\n  # Dangerously flush all data in Redis on startup. dangerous operation, make sure that you using this flag only on dev environments or test mode\n  dangerously_flush: false\n\n# Authentication Configuration\nauth:\n  # JWT authentication\n  jwt:\n    # Secret key for token generation and verification\n    secret: pByQUgg4GmXKAqQQvAGo\n    # Token expiration time in seconds\n    expiration: 604800 # 7 days\n\n"
  },
  {
    "path": "examples/loco_starter/examples/playground.rs",
    "content": "use eyre::Context;\n#[allow(unused_imports)]\nuse loco_rs::{cli::playground, prelude::*};\nuse loco_starter::app::App;\n\n#[tokio::main]\nasync fn main() -> eyre::Result<()> {\n    let _ctx = playground::<App>().await.context(\"playground\")?;\n\n    // let active_model: articles::ActiveModel = ActiveModel {\n    //     title: Set(Some(\"how to build apps in 3 steps\".to_string())),\n    //     content: Set(Some(\"use Loco: https://loco.rs\".to_string())),\n    //     ..Default::default()\n    // };\n    // active_model.insert(&ctx.db).await.unwrap();\n\n    // let res = articles::Entity::find().all(&ctx.db).await.unwrap();\n    // println!(\"{:?}\", res);\n    println!(\"welcome to playground. edit me at `examples/playground.rs`\");\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/loco_starter/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nloco-rs = { version = \"0.16\" }\ntokio   = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.\n    # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.\n    # e.g.\n    \"runtime-tokio-rustls\", # `ASYNC_RUNTIME` feature\n]\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/loco_starter/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Generate a new migration file\n    ```sh\n    cargo run -- migrate generate MIGRATION_NAME\n    ```\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/loco_starter/migration/src/lib.rs",
    "content": "#![allow(elided_lifetimes_in_paths)]\n#![allow(clippy::wildcard_imports)]\npub use sea_orm_migration::prelude::*;\n\nmod m20220101_000001_users;\nmod m20231103_114510_notes;\nmod m20240520_173001_files;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220101_000001_users::Migration),\n            Box::new(m20231103_114510_notes::Migration),\n            Box::new(m20240520_173001_files::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "examples/loco_starter/migration/src/m20220101_000001_users.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let table = table_auto(\"users\")\n            .col(pk_auto(\"id\"))\n            .col(uuid(\"pid\"))\n            .col(string_uniq(\"email\"))\n            .col(string(\"password\"))\n            .col(string(\"api_key\").unique_key())\n            .col(string(\"name\"))\n            .col(string_null(\"reset_token\"))\n            .col(timestamp_null(\"reset_sent_at\"))\n            .col(string_null(\"email_verification_token\"))\n            .col(timestamp_null(\"email_verification_sent_at\"))\n            .col(timestamp_null(\"email_verified_at\"))\n            .to_owned();\n        manager.create_table(table).await?;\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"users\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/loco_starter/migration/src/m20231103_114510_notes.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                table_auto(\"notes\")\n                    .col(pk_auto(\"id\"))\n                    .col(string_null(\"title\"))\n                    .col(string_null(\"content\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"notes\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/loco_starter/migration/src/m20240520_173001_files.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                table_auto(\"files\")\n                    .col(pk_auto(\"id\"))\n                    .col(integer(\"notes_id\"))\n                    .col(string(\"file_path\"))\n                    .foreign_key(\n                        ForeignKey::create()\n                            .name(\"FK_files_notes_id\")\n                            .from(\"files\", \"notes_id\")\n                            .to(\"notes\", \"id\"),\n                    )\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"files\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/loco_starter/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/loco_starter/src/app.rs",
    "content": "use std::path::Path;\n\nuse async_trait::async_trait;\nuse loco_rs::{\n    Result,\n    app::{AppContext, Hooks},\n    bgworker::{BackgroundWorker, Queue},\n    boot::{BootResult, StartMode, create_app},\n    config::Config,\n    controller::AppRoutes,\n    db::{self, truncate_table},\n    environment::Environment,\n    task::Tasks,\n};\nuse migration::Migrator;\n\nuse crate::{\n    controllers,\n    models::_entities::{notes, users},\n    tasks,\n    workers::downloader::DownloadWorker,\n};\n\npub struct App;\n#[async_trait]\nimpl Hooks for App {\n    fn app_name() -> &'static str {\n        env!(\"CARGO_CRATE_NAME\")\n    }\n\n    fn app_version() -> String {\n        format!(\n            \"{} ({})\",\n            env!(\"CARGO_PKG_VERSION\"),\n            option_env!(\"BUILD_SHA\")\n                .or(option_env!(\"GITHUB_SHA\"))\n                .unwrap_or(\"dev\")\n        )\n    }\n\n    async fn boot(\n        mode: StartMode,\n        environment: &Environment,\n        config: Config,\n    ) -> Result<BootResult> {\n        create_app::<Self, Migrator>(mode, environment, config).await\n    }\n\n    fn routes(_ctx: &AppContext) -> AppRoutes {\n        AppRoutes::with_default_routes()\n            .prefix(\"/api\")\n            .add_route(controllers::notes::routes())\n            .add_route(controllers::auth::routes())\n            .add_route(controllers::user::routes())\n            .add_route(controllers::files::routes())\n    }\n\n    async fn connect_workers(ctx: &AppContext, queue: &Queue) -> Result<()> {\n        queue.register(DownloadWorker::build(ctx)).await?;\n        Ok(())\n    }\n\n    fn register_tasks(tasks: &mut Tasks) {\n        tasks.register(tasks::seed::SeedData);\n    }\n\n    async fn truncate(ctx: &AppContext) -> Result<()> {\n        let db = &ctx.db;\n        truncate_table(db, users::Entity).await?;\n        truncate_table(db, notes::Entity).await?;\n        Ok(())\n    }\n\n    async fn seed(ctx: &AppContext, base: &Path) -> Result<()> {\n        let db = &ctx.db;\n        db::seed::<users::ActiveModel>(db, &base.join(\"users.yaml\").display().to_string()).await?;\n        db::seed::<notes::ActiveModel>(db, &base.join(\"notes.yaml\").display().to_string()).await?;\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/loco_starter/src/bin/main.rs",
    "content": "use loco_rs::cli;\nuse loco_starter::app::App;\nuse migration::Migrator;\n\n#[tokio::main]\nasync fn main() -> eyre::Result<()> {\n    cli::main::<App, Migrator>().await?;\n    Ok(())\n}\n"
  },
  {
    "path": "examples/loco_starter/src/controllers/auth.rs",
    "content": "use axum::debug_handler;\nuse loco_rs::prelude::*;\nuse serde::{Deserialize, Serialize};\n\nuse crate::{\n    mailers::auth::AuthMailer,\n    models::{\n        _entities::users,\n        users::{LoginParams, RegisterParams},\n    },\n    views::auth::LoginResponse,\n};\n#[derive(Debug, Deserialize, Serialize)]\npub struct VerifyParams {\n    pub token: String,\n}\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct ForgotParams {\n    pub email: String,\n}\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct ResetParams {\n    pub token: String,\n    pub password: String,\n}\n\n/// Register function creates a new user with the given parameters and sends a\n/// welcome email to the user\n#[debug_handler]\nasync fn register(\n    State(ctx): State<AppContext>,\n    Json(params): Json<RegisterParams>,\n) -> Result<Response> {\n    let res = users::Model::create_with_password(&ctx.db, &params).await;\n\n    let user = match res {\n        Ok(user) => user,\n        Err(err) => {\n            tracing::info!(\n                message = err.to_string(),\n                user_email = &params.email,\n                \"could not register user\",\n            );\n            return format::json(());\n        }\n    };\n\n    // Skip email verification, all new registrations are considered verified\n    let _user = user.into_active_model().verified(&ctx.db).await?;\n\n    // Skip sending verification email as we don't have a mail server\n    /*\n    let user = user\n        .into_active_model()\n        .set_email_verification_sent(&ctx.db)\n        .await?;\n\n    AuthMailer::send_welcome(&ctx, &user).await?;\n    */\n\n    format::json(())\n}\n\n/// Verify register user. if the user not verified his email, he can't login to\n/// the system.\n#[debug_handler]\nasync fn verify(\n    State(ctx): State<AppContext>,\n    Json(params): Json<VerifyParams>,\n) -> Result<Response> {\n    let user = users::Model::find_by_verification_token(&ctx.db, &params.token).await?;\n\n    if user.email_verified_at.is_some() {\n        tracing::info!(pid = user.pid.to_string(), \"user already verified\");\n    } else {\n        let active_model = user.into_active_model();\n        let user = active_model.verified(&ctx.db).await?;\n        tracing::info!(pid = user.pid.to_string(), \"user verified\");\n    }\n\n    format::json(())\n}\n\n/// In case the user forgot his password  this endpoints generate a forgot token\n/// and send email to the user. In case the email not found in our DB, we are\n/// returning a valid request for for security reasons (not exposing users DB\n/// list).\n#[debug_handler]\nasync fn forgot(\n    State(ctx): State<AppContext>,\n    Json(params): Json<ForgotParams>,\n) -> Result<Response> {\n    let Ok(user) = users::Model::find_by_email(&ctx.db, &params.email).await else {\n        // we don't want to expose our users email. if the email is invalid we still\n        // returning success to the caller\n        return format::json(());\n    };\n\n    let user = user\n        .into_active_model()\n        .set_forgot_password_sent(&ctx.db)\n        .await?;\n\n    AuthMailer::forgot_password(&ctx, &user).await?;\n\n    format::json(())\n}\n\n/// reset user password by the given parameters\n#[debug_handler]\nasync fn reset(State(ctx): State<AppContext>, Json(params): Json<ResetParams>) -> Result<Response> {\n    let Ok(user) = users::Model::find_by_reset_token(&ctx.db, &params.token).await else {\n        // we don't want to expose our users email. if the email is invalid we still\n        // returning success to the caller\n        tracing::info!(\"reset token not found\");\n\n        return format::json(());\n    };\n    user.into_active_model()\n        .reset_password(&ctx.db, &params.password)\n        .await?;\n\n    format::json(())\n}\n\n/// Creates a user login and returns a token\n#[debug_handler]\nasync fn login(State(ctx): State<AppContext>, Json(params): Json<LoginParams>) -> Result<Response> {\n    let user = users::Model::find_by_email(&ctx.db, &params.email).await?;\n\n    let valid = user.verify_password(&params.password);\n\n    if !valid {\n        return unauthorized(\"unauthorized!\");\n    }\n\n    let jwt_secret = ctx.config.get_jwt_config()?;\n\n    let token = user\n        .generate_jwt(&jwt_secret.secret, &jwt_secret.expiration)\n        .or_else(|_| unauthorized(\"unauthorized!\"))?;\n\n    format::json(LoginResponse::new(&user, &token))\n}\n\npub fn routes() -> Routes {\n    Routes::new()\n        .prefix(\"auth\")\n        .add(\"/register\", post(register))\n        .add(\"/verify\", post(verify))\n        .add(\"/login\", post(login))\n        .add(\"/forgot\", post(forgot))\n        .add(\"/reset\", post(reset))\n}\n"
  },
  {
    "path": "examples/loco_starter/src/controllers/files.rs",
    "content": "#![allow(clippy::missing_errors_doc)]\n#![allow(clippy::unnecessary_struct_initialization)]\n#![allow(clippy::unused_async)]\nuse std::path::PathBuf;\n\nuse axum::{body::Body, debug_handler, extract::Multipart};\nuse loco_rs::prelude::*;\nuse sea_orm::QueryOrder;\nuse tokio::{fs, io::AsyncWriteExt};\nuse tokio_util::io::ReaderStream;\n\nuse crate::models::_entities::files;\n\nconst UPLOAD_DIR: &str = \"./uploads\";\n\n#[debug_handler]\npub async fn upload(\n    _auth: auth::JWT,\n    Path(notes_id): Path<i32>,\n    State(ctx): State<AppContext>,\n    mut multipart: Multipart,\n) -> Result<Response> {\n    // Collect all uploaded files\n    let mut files = Vec::new();\n\n    // Iterate all files in the POST body\n    while let Some(field) = multipart.next_field().await.map_err(|err| {\n        tracing::error!(error = ?err,\"could not readd multipart\");\n        Error::BadRequest(\"could not readd multipart\".into())\n    })? {\n        // Get the file name\n        let file_name = match field.file_name() {\n            Some(file_name) => file_name.to_string(),\n            _ => return Err(Error::BadRequest(\"file name not found\".into())),\n        };\n\n        // Get the file content as bytes\n        let content = field.bytes().await.map_err(|err| {\n            tracing::error!(error = ?err,\"could not readd bytes\");\n            Error::BadRequest(\"could not readd bytes\".into())\n        })?;\n\n        // Create a folder to store the uploaded file\n        let now = chrono::offset::Local::now()\n            .format(\"%Y%m%d_%H%M%S\")\n            .to_string();\n        let uuid = uuid::Uuid::new_v4().to_string();\n        let folder = format!(\"{now}_{uuid}\");\n        let upload_folder = PathBuf::from(UPLOAD_DIR).join(&folder);\n        fs::create_dir_all(&upload_folder).await?;\n\n        // Write the file into the newly created folder\n        let path = upload_folder.join(file_name);\n        let mut f = fs::OpenOptions::new()\n            .create_new(true)\n            .write(true)\n            .open(&path)\n            .await?;\n        f.write_all(&content).await?;\n        f.flush().await?;\n\n        // Record the file upload in database\n        let file = files::ActiveModel {\n            notes_id: ActiveValue::Set(notes_id),\n            file_path: ActiveValue::Set(\n                path.strip_prefix(UPLOAD_DIR)\n                    .unwrap()\n                    .to_str()\n                    .unwrap()\n                    .to_string(),\n            ),\n            ..Default::default()\n        }\n        .insert(&ctx.db)\n        .await?;\n\n        files.push(file);\n    }\n\n    format::json(files)\n}\n\n#[debug_handler]\npub async fn list(\n    _auth: auth::JWT,\n    Path(notes_id): Path<i32>,\n    State(ctx): State<AppContext>,\n) -> Result<Response> {\n    // Fetch all files uploaded for a specific notes\n    let files = files::Entity::find()\n        .filter(files::Column::NotesId.eq(notes_id))\n        .order_by_asc(files::Column::Id)\n        .all(&ctx.db)\n        .await?;\n\n    format::json(files)\n}\n\n#[debug_handler]\npub async fn view(\n    _auth: auth::JWT,\n    Path(files_id): Path<i32>,\n    State(ctx): State<AppContext>,\n) -> Result<Response> {\n    // Fetch the file info from database\n    let file = files::Entity::find_by_id(files_id)\n        .one(&ctx.db)\n        .await?\n        .expect(\"File not found\");\n\n    // Stream the file\n    let file = fs::File::open(format!(\"{UPLOAD_DIR}/{}\", file.file_path)).await?;\n    let stream = ReaderStream::new(file);\n    let body = Body::from_stream(stream);\n\n    Ok(format::render().response().body(body)?)\n}\n\npub fn routes() -> Routes {\n    // Bind the routes\n    Routes::new()\n        .prefix(\"files\")\n        .add(\"/upload/{notes_id}\", post(upload))\n        .add(\"/list/{notes_id}\", get(list))\n        .add(\"/view/{files_id}\", get(view))\n}\n"
  },
  {
    "path": "examples/loco_starter/src/controllers/mod.rs",
    "content": "pub mod auth;\npub mod files;\npub mod notes;\npub mod user;\n"
  },
  {
    "path": "examples/loco_starter/src/controllers/notes.rs",
    "content": "#![allow(clippy::missing_errors_doc)]\n#![allow(clippy::unnecessary_struct_initialization)]\n#![allow(clippy::unused_async)]\nuse axum::debug_handler;\nuse loco_rs::prelude::*;\nuse serde::{Deserialize, Serialize};\n\nuse crate::models::_entities::notes::{ActiveModel, Entity, Model};\n\n#[derive(Clone, Debug, Serialize, Deserialize)]\npub struct Params {\n    pub title: Option<String>,\n    pub content: Option<String>,\n}\n\nimpl Params {\n    fn update(&self, item: &mut ActiveModel) {\n        item.title = Set(self.title.clone());\n        item.content = Set(self.content.clone());\n    }\n}\n\nasync fn load_item(ctx: &AppContext, id: i32) -> Result<Model> {\n    let item = Entity::find_by_id(id).one(&ctx.db).await?;\n    item.ok_or_else(|| Error::NotFound)\n}\n\n#[debug_handler]\npub async fn list(State(ctx): State<AppContext>) -> Result<Response> {\n    format::json(Entity::find().all(&ctx.db).await?)\n}\n\n#[debug_handler]\npub async fn add(State(ctx): State<AppContext>, Json(params): Json<Params>) -> Result<Response> {\n    let mut item = ActiveModel {\n        ..Default::default()\n    };\n    params.update(&mut item);\n    let item = item.insert(&ctx.db).await?;\n    format::json(item)\n}\n\n#[debug_handler]\npub async fn update(\n    Path(id): Path<i32>,\n    State(ctx): State<AppContext>,\n    Json(params): Json<Params>,\n) -> Result<Response> {\n    let item = load_item(&ctx, id).await?;\n    let mut item = item.into_active_model();\n    params.update(&mut item);\n    let item = item.update(&ctx.db).await?;\n    format::json(item)\n}\n\n#[debug_handler]\npub async fn remove(Path(id): Path<i32>, State(ctx): State<AppContext>) -> Result<Response> {\n    load_item(&ctx, id).await?.delete(&ctx.db).await?;\n    format::empty()\n}\n\n#[debug_handler]\npub async fn get_one(Path(id): Path<i32>, State(ctx): State<AppContext>) -> Result<Response> {\n    format::json(load_item(&ctx, id).await?)\n}\n\npub fn routes() -> Routes {\n    Routes::new()\n        .prefix(\"notes\")\n        .add(\"/\", get(list))\n        .add(\"/\", post(add))\n        .add(\"/{id}\", get(get_one))\n        .add(\"/{id}\", delete(remove))\n        .add(\"/{id}\", post(update))\n}\n"
  },
  {
    "path": "examples/loco_starter/src/controllers/user.rs",
    "content": "use axum::debug_handler;\nuse loco_rs::prelude::*;\n\nuse crate::{models::_entities::users, views::user::CurrentResponse};\n\n#[debug_handler]\nasync fn current(auth: auth::JWT, State(ctx): State<AppContext>) -> Result<Response> {\n    let user = users::Model::find_by_pid(&ctx.db, &auth.claims.pid).await?;\n    format::json(CurrentResponse::new(&user))\n}\n\npub fn routes() -> Routes {\n    Routes::new().prefix(\"user\").add(\"/current\", get(current))\n}\n"
  },
  {
    "path": "examples/loco_starter/src/fixtures/notes.yaml",
    "content": "---\n- id: 1\n  title: Loco note 1\n  content: Loco note 1 content\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n- id: 2\n  title: Loco note 2\n  content: Loco note 2 content\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n"
  },
  {
    "path": "examples/loco_starter/src/fixtures/users.yaml",
    "content": "---\n- id: 1\n  pid: 11111111-1111-1111-1111-111111111111\n  email: user1@example.com\n  password: \"$argon2id$v=19$m=19456,t=2,p=1$ETQBx4rTgNAZhSaeYZKOZg$eYTdH26CRT6nUJtacLDEboP0li6xUwUF/q5nSlQ8uuc\"\n  api_key: lo-95ec80d7-cb60-4b70-9b4b-9ef74cb88758\n  name: user1\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n- id: 2\n  pid: 22222222-2222-2222-2222-222222222222\n  email: user2@example.com\n  password: \"$argon2id$v=19$m=19456,t=2,p=1$ETQBx4rTgNAZhSaeYZKOZg$eYTdH26CRT6nUJtacLDEboP0li6xUwUF/q5nSlQ8uuc\"\n  api_key: lo-153561ca-fa84-4e1b-813a-c62526d0a77e\n  name: user2\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n"
  },
  {
    "path": "examples/loco_starter/src/lib.rs",
    "content": "pub mod app;\npub mod controllers;\npub mod mailers;\npub mod models;\npub mod tasks;\npub mod views;\npub mod workers;\n"
  },
  {
    "path": "examples/loco_starter/src/mailers/auth/forgot/html.t",
    "content": ";<html>\n\n<body>\n  Hey {{name}},\n  Forgot your password? No worries! You can reset it by clicking the link below:\n  <a href=\"http://{{domain}}/reset#{{resetToken}}\">Reset Your Password</a>\n  If you didn't request a password reset, please ignore this email.\n  Best regards,<br>The Loco Team</br>\n</body>\n\n</html>\n"
  },
  {
    "path": "examples/loco_starter/src/mailers/auth/forgot/subject.t",
    "content": "Your reset password link\n"
  },
  {
    "path": "examples/loco_starter/src/mailers/auth/forgot/text.t",
    "content": "Reset your password with this link:\n\nhttp://localhost/reset#{{resetToken}}\n"
  },
  {
    "path": "examples/loco_starter/src/mailers/auth/welcome/html.t",
    "content": ";<html>\n\n<body>\n  Dear {{name}},\n  Welcome to Loco! You can now log in to your account.\n  Before you get started, please verify your account by clicking the link below:\n  <a href=\"http://{{domain}}/verify#{{verifyToken}}\">\n    Verify Your Account\n  </a>\n  <p>Best regards,<br>The Loco Team</p>\n</body>\n\n</html>\n"
  },
  {
    "path": "examples/loco_starter/src/mailers/auth/welcome/subject.t",
    "content": "Welcome {{name}}\n"
  },
  {
    "path": "examples/loco_starter/src/mailers/auth/welcome/text.t",
    "content": "Welcome {{name}}, you can now log in.\n  Verify your account with the link below:\n\n  http://localhost/verify#{{verifyToken}}\n"
  },
  {
    "path": "examples/loco_starter/src/mailers/auth.rs",
    "content": "// auth mailer\n#![allow(non_upper_case_globals)]\n\nuse loco_rs::prelude::*;\nuse serde_json::json;\n\nuse crate::models::users;\n\nstatic welcome: Dir<'_> = include_dir!(\"src/mailers/auth/welcome\");\nstatic forgot: Dir<'_> = include_dir!(\"src/mailers/auth/forgot\");\n// #[derive(Mailer)] // -- disabled for faster build speed. it works. but lets\n// move on for now.\n\n#[allow(clippy::module_name_repetitions)]\npub struct AuthMailer {}\nimpl Mailer for AuthMailer {}\nimpl AuthMailer {\n    /// Sending welcome email the the given user\n    ///\n    /// # Errors\n    ///\n    /// When email sending is failed\n    pub async fn send_welcome(ctx: &AppContext, user: &users::Model) -> Result<()> {\n        Self::mail_template(\n            ctx,\n            &welcome,\n            mailer::Args {\n                to: user.email.to_string(),\n                locals: json!({\n                  \"name\": user.name,\n                  \"verifyToken\": user.email_verification_token,\n                  \"domain\": ctx.config.server.full_url()\n                }),\n                ..Default::default()\n            },\n        )\n        .await?;\n\n        Ok(())\n    }\n\n    /// Sending forgot password email\n    ///\n    /// # Errors\n    ///\n    /// When email sending is failed\n    pub async fn forgot_password(ctx: &AppContext, user: &users::Model) -> Result<()> {\n        Self::mail_template(\n            ctx,\n            &forgot,\n            mailer::Args {\n                to: user.email.to_string(),\n                locals: json!({\n                  \"name\": user.name,\n                  \"resetToken\": user.reset_token,\n                  \"domain\": ctx.config.server.full_url()\n                }),\n                ..Default::default()\n            },\n        )\n        .await?;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/loco_starter/src/mailers/mod.rs",
    "content": "pub mod auth;\n"
  },
  {
    "path": "examples/loco_starter/src/models/_entities/files.rs",
    "content": "use sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"files\")]\npub struct Model {\n    pub created_at: DateTime,\n    pub updated_at: DateTime,\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub notes_id: i32,\n    pub file_path: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::notes::Entity\",\n        from = \"Column::NotesId\",\n        to = \"super::notes::Column::Id\"\n    )]\n    Notes,\n}\n\nimpl Related<super::notes::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Notes.def()\n    }\n}\n"
  },
  {
    "path": "examples/loco_starter/src/models/_entities/mod.rs",
    "content": "pub mod prelude;\n\npub mod files;\npub mod notes;\npub mod users;\n"
  },
  {
    "path": "examples/loco_starter/src/models/_entities/notes.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.10\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"notes\")]\npub struct Model {\n    pub created_at: DateTime,\n    pub updated_at: DateTime,\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub title: Option<String>,\n    pub content: Option<String>,\n}\n"
  },
  {
    "path": "examples/loco_starter/src/models/_entities/prelude.rs",
    "content": "pub use super::{notes::Entity as Notes, users::Entity as Users};\n"
  },
  {
    "path": "examples/loco_starter/src/models/_entities/users.rs",
    "content": "use sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"users\")]\npub struct Model {\n    pub created_at: DateTime,\n    pub updated_at: DateTime,\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(unique)]\n    pub pid: Uuid,\n    #[sea_orm(unique)]\n    pub email: String,\n    pub password: String,\n    #[sea_orm(unique)]\n    pub api_key: String,\n    pub name: String,\n    pub reset_token: Option<String>,\n    pub reset_sent_at: Option<DateTime>,\n    pub email_verification_token: Option<String>,\n    pub email_verification_sent_at: Option<DateTime>,\n    pub email_verified_at: Option<DateTime>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n"
  },
  {
    "path": "examples/loco_starter/src/models/files.rs",
    "content": "use sea_orm::entity::prelude::*;\n\nuse super::_entities::files::ActiveModel;\n\nimpl ActiveModelBehavior for ActiveModel {\n    // extend activemodel below (keep comment for generators)\n}\n"
  },
  {
    "path": "examples/loco_starter/src/models/mod.rs",
    "content": "pub mod _entities;\npub mod files;\npub mod notes;\npub mod users;\n"
  },
  {
    "path": "examples/loco_starter/src/models/notes.rs",
    "content": "use sea_orm::entity::prelude::*;\n\nuse super::_entities::notes::ActiveModel;\n\nimpl ActiveModelBehavior for ActiveModel {\n    // extend activemodel below (keep comment for generators)\n}\n"
  },
  {
    "path": "examples/loco_starter/src/models/users.rs",
    "content": "use async_trait::async_trait;\nuse chrono::offset::Local;\nuse loco_rs::{auth::jwt, hash, prelude::*};\nuse serde::{Deserialize, Serialize};\nuse uuid::Uuid;\n\npub use super::_entities::users::{self, ActiveModel, Entity, Model};\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct LoginParams {\n    pub email: String,\n    pub password: String,\n}\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct RegisterParams {\n    pub email: String,\n    pub password: String,\n    pub name: String,\n}\n\n#[derive(Debug, Validate, Deserialize)]\npub struct Validator {\n    #[validate(length(min = 2, message = \"Name must be at least 2 characters long.\"))]\n    pub name: String,\n    #[validate(email(message = \"invalid email\"))]\n    pub email: String,\n}\n\nimpl Validatable for super::_entities::users::ActiveModel {\n    fn validator(&self) -> Box<dyn Validate> {\n        Box::new(Validator {\n            name: self.name.as_ref().to_owned(),\n            email: self.email.as_ref().to_owned(),\n        })\n    }\n}\n\n#[async_trait::async_trait]\nimpl ActiveModelBehavior for super::_entities::users::ActiveModel {\n    async fn before_save<C>(self, _db: &C, insert: bool) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.validate()?;\n        if insert {\n            let mut this = self;\n            this.pid = ActiveValue::Set(Uuid::new_v4());\n            this.api_key = ActiveValue::Set(format!(\"lo-{}\", Uuid::new_v4()));\n            Ok(this)\n        } else {\n            Ok(self)\n        }\n    }\n}\n\n#[async_trait]\nimpl Authenticable for super::_entities::users::Model {\n    async fn find_by_api_key(db: &DatabaseConnection, api_key: &str) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::ApiKey.eq(api_key))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    async fn find_by_claims_key(db: &DatabaseConnection, claims_key: &str) -> ModelResult<Self> {\n        Self::find_by_pid(db, claims_key).await\n    }\n}\n\nimpl super::_entities::users::Model {\n    /// finds a user by the provided email\n    ///\n    /// # Errors\n    ///\n    /// When could not find user by the given token or DB query error\n    pub async fn find_by_email(db: &DatabaseConnection, email: &str) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::Email.eq(email))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// finds a user by the provided verification token\n    ///\n    /// # Errors\n    ///\n    /// When could not find user by the given token or DB query error\n    pub async fn find_by_verification_token(\n        db: &DatabaseConnection,\n        token: &str,\n    ) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::EmailVerificationToken.eq(token))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// /// finds a user by the provided reset token\n    ///\n    /// # Errors\n    ///\n    /// When could not find user by the given token or DB query error\n    pub async fn find_by_reset_token(db: &DatabaseConnection, token: &str) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::ResetToken.eq(token))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// finds a user by the provided pid\n    ///\n    /// # Errors\n    ///\n    /// When could not find user  or DB query error\n    pub async fn find_by_pid(db: &DatabaseConnection, pid: &str) -> ModelResult<Self> {\n        let parse_uuid = Uuid::parse_str(pid).map_err(|e| ModelError::Any(e.into()))?;\n        let user = users::Entity::find()\n            .filter(users::Column::Pid.eq(parse_uuid))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// finds a user by the provided api key\n    ///\n    /// # Errors\n    ///\n    /// When could not find user by the given token or DB query error\n    pub async fn find_by_api_key(db: &DatabaseConnection, api_key: &str) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::ApiKey.eq(api_key))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// Verifies whether the provided plain password matches the hashed password\n    ///\n    /// # Errors\n    ///\n    /// when could not verify password\n    #[must_use]\n    pub fn verify_password(&self, password: &str) -> bool {\n        hash::verify_password(password, &self.password)\n    }\n\n    /// Asynchronously creates a user with a password and saves it to the\n    /// database.\n    ///\n    /// # Errors\n    ///\n    /// When could not save the user into the DB\n    pub async fn create_with_password(\n        db: &DatabaseConnection,\n        params: &RegisterParams,\n    ) -> ModelResult<Self> {\n        let txn = db.begin().await?;\n\n        if users::Entity::find()\n            .filter(users::Column::Email.eq(&params.email))\n            .one(&txn)\n            .await?\n            .is_some()\n        {\n            return Err(ModelError::EntityAlreadyExists {});\n        }\n\n        let password_hash =\n            hash::hash_password(&params.password).map_err(|e| ModelError::Any(e.into()))?;\n        let user = users::ActiveModel {\n            email: ActiveValue::set(params.email.to_string()),\n            password: ActiveValue::set(password_hash),\n            name: ActiveValue::set(params.name.to_string()),\n            ..Default::default()\n        }\n        .insert(&txn)\n        .await?;\n\n        txn.commit().await?;\n\n        Ok(user)\n    }\n\n    /// Creates a JWT\n    ///\n    /// # Errors\n    ///\n    /// when could not convert user claims to jwt token\n    pub fn generate_jwt(&self, secret: &str, expiration: &u64) -> ModelResult<String> {\n        Ok(jwt::JWT::new(secret).generate_token(\n            *expiration,\n            self.pid.to_string(),\n            Default::default(),\n        )?)\n    }\n}\n\nimpl super::_entities::users::ActiveModel {\n    /// Sets the email verification information for the user and\n    /// updates it in the database.\n    ///\n    /// This method is used to record the timestamp when the email verification\n    /// was sent and generate a unique verification token for the user.\n    ///\n    /// # Errors\n    ///\n    /// when has DB query error\n    pub async fn set_email_verification_sent(\n        mut self,\n        db: &DatabaseConnection,\n    ) -> ModelResult<Model> {\n        self.email_verification_sent_at = ActiveValue::set(Some(Local::now().naive_local()));\n        self.email_verification_token = ActiveValue::Set(Some(Uuid::new_v4().to_string()));\n        Ok(self.update(db).await?)\n    }\n\n    /// Sets the information for a reset password request,\n    /// generates a unique reset password token, and updates it in the\n    /// database.\n    ///\n    /// This method records the timestamp when the reset password token is sent\n    /// and generates a unique token for the user.\n    ///\n    /// # Arguments\n    ///\n    /// # Errors\n    ///\n    /// when has DB query error\n    pub async fn set_forgot_password_sent(mut self, db: &DatabaseConnection) -> ModelResult<Model> {\n        self.reset_sent_at = ActiveValue::set(Some(Local::now().naive_local()));\n        self.reset_token = ActiveValue::Set(Some(Uuid::new_v4().to_string()));\n        Ok(self.update(db).await?)\n    }\n\n    /// Records the verification time when a user verifies their\n    /// email and updates it in the database.\n    ///\n    /// This method sets the timestamp when the user successfully verifies their\n    /// email.\n    ///\n    /// # Errors\n    ///\n    /// when has DB query error\n    pub async fn verified(mut self, db: &DatabaseConnection) -> ModelResult<Model> {\n        self.email_verified_at = ActiveValue::set(Some(Local::now().naive_local()));\n        Ok(self.update(db).await?)\n    }\n\n    /// Resets the current user password with a new password and\n    /// updates it in the database.\n    ///\n    /// This method hashes the provided password and sets it as the new password\n    /// for the user.    \n    /// # Errors\n    ///\n    /// when has DB query error or could not hashed the given password\n    pub async fn reset_password(\n        mut self,\n        db: &DatabaseConnection,\n        password: &str,\n    ) -> ModelResult<Model> {\n        self.password =\n            ActiveValue::set(hash::hash_password(password).map_err(|e| ModelError::Any(e.into()))?);\n        Ok(self.update(db).await?)\n    }\n}\n"
  },
  {
    "path": "examples/loco_starter/src/tasks/mod.rs",
    "content": "pub mod seed;\n"
  },
  {
    "path": "examples/loco_starter/src/tasks/seed.rs",
    "content": "//! This task implements data seeding functionality for initializing new\n//! development/demo environments.\n//!\n//! # Example\n//!\n//! Run the task with the following command:\n//! ```sh\n//! cargo run task\n//! ```\n//!\n//! To override existing data and reset the data structure, use the following\n//! command with the `refresh:true` argument:\n//! ```sh\n//! cargo run task seed_data refresh:true\n//! ```\n\nuse loco_rs::{db, prelude::*};\nuse migration::Migrator;\n\nuse crate::app::App;\n\n#[allow(clippy::module_name_repetitions)]\npub struct SeedData;\n#[async_trait]\nimpl Task for SeedData {\n    fn task(&self) -> TaskInfo {\n        TaskInfo {\n            name: \"seed_data\".to_string(),\n            detail: \"Task for seeding data\".to_string(),\n        }\n    }\n\n    async fn run(&self, app_context: &AppContext, vars: &task::Vars) -> Result<()> {\n        let refresh = vars\n            .cli_arg(\"refresh\")\n            .is_ok_and(|refresh| refresh == \"true\");\n\n        if refresh {\n            db::reset::<Migrator>(&app_context.db).await?;\n        }\n        let path = std::path::Path::new(\"src/fixtures\");\n        db::run_app_seed::<App>(app_context, path).await?;\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/loco_starter/src/views/auth.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::models::_entities::users;\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct LoginResponse {\n    pub token: String,\n    pub pid: String,\n    pub name: String,\n    pub is_verified: bool,\n}\n\nimpl LoginResponse {\n    #[must_use]\n    pub fn new(user: &users::Model, token: &String) -> Self {\n        Self {\n            token: token.to_string(),\n            pid: user.pid.to_string(),\n            name: user.name.clone(),\n            is_verified: user.email_verified_at.is_some(),\n        }\n    }\n}\n"
  },
  {
    "path": "examples/loco_starter/src/views/mod.rs",
    "content": "pub mod auth;\npub mod user;\n"
  },
  {
    "path": "examples/loco_starter/src/views/user.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::models::_entities::users;\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct CurrentResponse {\n    pub pid: String,\n    pub name: String,\n    pub email: String,\n}\n\nimpl CurrentResponse {\n    #[must_use]\n    pub fn new(user: &users::Model) -> Self {\n        Self {\n            pid: user.pid.to_string(),\n            name: user.name.clone(),\n            email: user.email.clone(),\n        }\n    }\n}\n"
  },
  {
    "path": "examples/loco_starter/src/workers/downloader.rs",
    "content": "use std::time::Duration;\n\nuse loco_rs::prelude::*;\nuse serde::{Deserialize, Serialize};\nuse tokio::time::sleep;\n\nuse crate::models::users;\n\npub struct DownloadWorker {\n    pub ctx: AppContext,\n}\n\n#[derive(Deserialize, Debug, Serialize)]\npub struct DownloadWorkerArgs {\n    pub user_guid: String,\n}\n\n#[async_trait]\nimpl BackgroundWorker<DownloadWorkerArgs> for DownloadWorker {\n    fn build(ctx: &AppContext) -> Self {\n        Self { ctx: ctx.clone() }\n    }\n\n    async fn perform(&self, args: DownloadWorkerArgs) -> Result<()> {\n        // TODO: Some actual work goes here...\n        println!(\"================================================\");\n        println!(\"Sending payment report to user {}\", args.user_guid);\n\n        sleep(Duration::from_millis(2000)).await;\n\n        let all = users::Entity::find()\n            .all(&self.ctx.db)\n            .await\n            .map_err(Box::from)?;\n        for user in &all {\n            println!(\"user: {}\", user.id);\n        }\n        println!(\"================================================\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/loco_starter/src/workers/mod.rs",
    "content": "pub mod downloader;\n"
  },
  {
    "path": "examples/parquet_example/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-parquet-example\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nenv_logger = { version = \"0.11\" }\nfastrand   = \"2\"\nlog        = { version = \"0.4\" }\nparquet    = { version = \"58\", default-features = false, features = [\"arrow\"] }\ntokio      = { version = \"1\", features = [\"full\"] }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"sqlx-sqlite\",\n    \"runtime-tokio\",\n    \"with-arrow\",\n    \"with-chrono\",\n    \"with-rust_decimal\",\n]\npath = \"../../\"\n"
  },
  {
    "path": "examples/parquet_example/src/main.rs",
    "content": "use sea_orm::{\n    ArrowSchema,\n    entity::*,\n    prelude::{ChronoUtc, Decimal},\n    sea_query::prelude::chrono::Timelike,\n};\n\nuse log::info;\n\nmod measurement {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"measurement\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub recorded_at: ChronoDateTimeUtc,\n        pub sensor_id: i32,\n        pub temperature: f64,\n        #[sea_orm(column_type = \"Decimal(Some((10, 4)))\")]\n        pub voltage: Decimal,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[tokio::main]\nasync fn main() -> Result<(), Box<dyn std::error::Error>> {\n    let env = env_logger::Env::default().filter_or(\"RUST_LOG\", \"info,sea_orm=info,sqlx=warn\");\n    env_logger::Builder::from_env(env).init();\n\n    // -----------------------------------------------------------------------\n    // Step 1: Generate 100 random rows\n    // -----------------------------------------------------------------------\n    let base_ts = ChronoUtc::now();\n    let base_ts = base_ts\n        .with_nanosecond((base_ts.nanosecond() / 1000) * 1000)\n        .unwrap(); // truncate to microsecond\n    let mut rng = fastrand::Rng::new();\n\n    let models: Vec<measurement::ActiveModel> = (1..=100)\n        .map(|i| {\n            let offset = std::time::Duration::from_secs(rng.u64(0..86_400));\n            let ts = base_ts + offset;\n            let sensor_id = rng.i32(100..110);\n            let temperature = -10.0 + rng.f64() * 50.0; // -10 .. 40 °C\n            let voltage_raw = 30000 + rng.i64(0..5000); // 3.0000 .. 3.5000\n            measurement::ActiveModel {\n                id: Set(i),\n                recorded_at: Set(ts),\n                sensor_id: Set(sensor_id),\n                temperature: Set(temperature),\n                voltage: Set(Decimal::new(voltage_raw, 4)),\n            }\n        })\n        .collect();\n\n    let schema = measurement::Entity::arrow_schema();\n    info!(\"Arrow schema: {schema:?}\");\n\n    // -----------------------------------------------------------------------\n    // Step 2: Convert to Arrow RecordBatch and write to Parquet\n    // -----------------------------------------------------------------------\n    let batch = measurement::ActiveModel::to_arrow(&models, &schema)?;\n    info!(\n        \"RecordBatch: {} rows, {} columns\",\n        batch.num_rows(),\n        batch.num_columns()\n    );\n\n    let parquet_path = \"measurements.parquet\";\n\n    {\n        let file = std::fs::File::create(parquet_path)?;\n        let mut writer = parquet::arrow::ArrowWriter::try_new(file, schema.into(), None)?;\n        writer.write(&batch)?;\n        writer.close()?;\n    }\n    info!(\"Wrote Parquet file: {parquet_path}\");\n\n    // -----------------------------------------------------------------------\n    // Step 3: Read the Parquet file back into a RecordBatch\n    // -----------------------------------------------------------------------\n    let file = std::fs::File::open(parquet_path)?;\n    let reader =\n        parquet::arrow::arrow_reader::ParquetRecordBatchReaderBuilder::try_new(file)?.build()?;\n\n    let batches: Vec<_> = reader.collect::<Result<_, _>>()?;\n    info!(\"Read {} batch(es) from Parquet\", batches.len());\n\n    let read_batch = &batches[0];\n    assert_eq!(read_batch.num_rows(), 100);\n\n    // Convert back to ActiveModels\n    let restored = measurement::ActiveModel::from_arrow(read_batch)?;\n    info!(\"Restored {} ActiveModels from Parquet\", restored.len());\n\n    for (original, restored) in models.iter().zip(restored.iter()) {\n        assert_eq!(original, restored, \"Roundtrip mismatch\");\n    }\n    info!(\"Parquet roundtrip verified: all rows match.\");\n\n    // -----------------------------------------------------------------------\n    // Step 4: Dump into SQLite\n    // -----------------------------------------------------------------------\n\n    match std::fs::remove_file(\"measurements.sqlite\") {\n        Ok(_) => (),\n        Err(e) if e.kind() == std::io::ErrorKind::NotFound => (),\n        Err(e) => panic!(\"Failed to remove file: {e}\"),\n    }\n\n    let db = &sea_orm::Database::connect(\"sqlite://measurements.sqlite?mode=rwc\").await?;\n\n    db.get_schema_builder()\n        .register(measurement::Entity)\n        .apply(db)\n        .await?;\n    info!(\"SQLite schema created.\");\n\n    measurement::Entity::insert_many(restored).exec(db).await?;\n    info!(\"Inserted all rows into SQLite.\");\n\n    info!(\"Done!\");\n    Ok(())\n}\n"
  },
  {
    "path": "examples/poem_example/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"sea-orm-poem-example\"\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n[workspace]\nmembers = [\".\", \"api\", \"entity\", \"migration\"]\n\n[dependencies]\npoem-example-api = { path = \"api\" }\n"
  },
  {
    "path": "examples/poem_example/README.md",
    "content": "![screenshot](Screenshot.png)\n\n# Poem with SeaORM example app\n\n1. Modify the `DATABASE_URL` var in `.env` to point to your chosen database\n\n1. Turn on the appropriate database feature for your chosen db in `api/Cargo.toml` (the `\"sqlx-sqlite\",` line)\n\n1. Execute `cargo run` to start the server\n\n1. Visit [localhost:8000](http://localhost:8000) in browser after seeing the `server started` line\n\nRun tests:\n\n```bash\ncd api\ncargo test\n```\n\nRun migration:\n\n```bash\ncargo run -p migration -- up\n```\n\nRegenerate entity:\n\n```bash\nsea-orm-cli generate entity --output-dir ./entity/src --lib --entity-format dense --with-serde both\n```"
  },
  {
    "path": "examples/poem_example/api/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"poem-example-api\"\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\ndotenvy            = \"0.15\"\nentity             = { path = \"../entity\" }\nmigration          = { path = \"../migration\" }\npoem               = { version = \"1.3.56\", features = [\"static-files\"] }\nserde              = { version = \"1\", features = [\"derive\"] }\ntera               = \"1.19.0\"\ntokio              = { version = \"1.29.0\", features = [\"macros\", \"rt-multi-thread\"] }\ntracing-subscriber = { version = \"0.3.17\", features = [\"env-filter\"] }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"debug-print\",\n    \"runtime-tokio-native-tls\",\n    # \"sqlx-postgres\",\n    # \"sqlx-mysql\",\n    \"sqlx-sqlite\",\n]\npath = \"../../../\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n\n[dev-dependencies]\npoem-example-api = { path = \".\", features = [\"sqlite\"] }\n\n[features]\nsqlite = [\"sea-orm/sqlx-sqlite\"]\n"
  },
  {
    "path": "examples/poem_example/api/src/lib.rs",
    "content": "pub mod service;\n\nuse std::env;\n\nuse entity::post;\nuse migration::{Migrator, MigratorTrait};\nuse poem::endpoint::StaticFilesEndpoint;\nuse poem::error::InternalServerError;\nuse poem::http::StatusCode;\nuse poem::listener::TcpListener;\nuse poem::web::{Data, Form, Html, Path, Query};\nuse poem::{EndpointExt, Error, IntoResponse, Result, Route, Server, get, handler, post};\nuse sea_orm::{Database, DatabaseConnection};\nuse serde::Deserialize;\nuse service::{Mutation, Query as QueryService};\nuse tera::Tera;\n\nconst DEFAULT_POSTS_PER_PAGE: u64 = 5;\n\n#[derive(Debug, Clone)]\nstruct AppState {\n    templates: tera::Tera,\n    conn: DatabaseConnection,\n}\n\n#[derive(Deserialize)]\nstruct Params {\n    page: Option<u64>,\n    posts_per_page: Option<u64>,\n}\n\n#[handler]\nasync fn create(state: Data<&AppState>, form: Form<post::Model>) -> Result<impl IntoResponse> {\n    let form = form.0;\n    let conn = &state.conn;\n\n    Mutation::create_post(conn, form)\n        .await\n        .map_err(InternalServerError)?;\n\n    Ok(StatusCode::FOUND.with_header(\"location\", \"/\"))\n}\n\n#[handler]\nasync fn list(state: Data<&AppState>, Query(params): Query<Params>) -> Result<impl IntoResponse> {\n    let conn = &state.conn;\n    let page = params.page.unwrap_or(1);\n    let posts_per_page = params.posts_per_page.unwrap_or(DEFAULT_POSTS_PER_PAGE);\n\n    let (posts, num_pages) = QueryService::find_posts_in_page(conn, page, posts_per_page)\n        .await\n        .map_err(InternalServerError)?;\n\n    let mut ctx = tera::Context::new();\n    ctx.insert(\"posts\", &posts);\n    ctx.insert(\"page\", &page);\n    ctx.insert(\"posts_per_page\", &posts_per_page);\n    ctx.insert(\"num_pages\", &num_pages);\n\n    let body = state\n        .templates\n        .render(\"index.html.tera\", &ctx)\n        .map_err(InternalServerError)?;\n    Ok(Html(body))\n}\n\n#[handler]\nasync fn new(state: Data<&AppState>) -> Result<impl IntoResponse> {\n    let ctx = tera::Context::new();\n    let body = state\n        .templates\n        .render(\"new.html.tera\", &ctx)\n        .map_err(InternalServerError)?;\n    Ok(Html(body))\n}\n\n#[handler]\nasync fn edit(state: Data<&AppState>, Path(id): Path<i32>) -> Result<impl IntoResponse> {\n    let conn = &state.conn;\n\n    let post: post::Model = QueryService::find_post_by_id(conn, id)\n        .await\n        .map_err(InternalServerError)?\n        .ok_or_else(|| Error::from_status(StatusCode::NOT_FOUND))?;\n\n    let mut ctx = tera::Context::new();\n    ctx.insert(\"post\", &post);\n\n    let body = state\n        .templates\n        .render(\"edit.html.tera\", &ctx)\n        .map_err(InternalServerError)?;\n    Ok(Html(body))\n}\n\n#[handler]\nasync fn update(\n    state: Data<&AppState>,\n    Path(id): Path<i32>,\n    form: Form<post::Model>,\n) -> Result<impl IntoResponse> {\n    let conn = &state.conn;\n    let form = form.0;\n\n    Mutation::update_post_by_id(conn, id, form)\n        .await\n        .map_err(InternalServerError)?;\n\n    Ok(StatusCode::FOUND.with_header(\"location\", \"/\"))\n}\n\n#[handler]\nasync fn delete(state: Data<&AppState>, Path(id): Path<i32>) -> Result<impl IntoResponse> {\n    let conn = &state.conn;\n\n    Mutation::delete_post(conn, id)\n        .await\n        .map_err(InternalServerError)?;\n\n    Ok(StatusCode::FOUND.with_header(\"location\", \"/\"))\n}\n\n#[tokio::main]\nasync fn start() -> std::io::Result<()> {\n    unsafe {\n        std::env::set_var(\"RUST_LOG\", \"debug\");\n    }\n    tracing_subscriber::fmt::init();\n\n    // get env vars\n    dotenvy::dotenv().ok();\n    let db_url = env::var(\"DATABASE_URL\").expect(\"DATABASE_URL is not set in .env file\");\n    let host = env::var(\"HOST\").expect(\"HOST is not set in .env file\");\n    let port = env::var(\"PORT\").expect(\"PORT is not set in .env file\");\n    let server_url = format!(\"{host}:{port}\");\n\n    // create post table if not exists\n    let conn = Database::connect(&db_url).await.unwrap();\n    Migrator::up(&conn, None).await.unwrap();\n    let templates = Tera::new(concat!(env!(\"CARGO_MANIFEST_DIR\"), \"/templates/**/*\")).unwrap();\n    let state = AppState { templates, conn };\n\n    println!(\"Starting server at {server_url}\");\n\n    let app = Route::new()\n        .at(\"/\", post(create).get(list))\n        .at(\"/new\", new)\n        .at(\"/:id\", get(edit).post(update))\n        .at(\"/delete/:id\", post(delete))\n        .nest(\n            \"/static\",\n            StaticFilesEndpoint::new(concat!(env!(\"CARGO_MANIFEST_DIR\"), \"/static\")),\n        )\n        .data(state);\n    let server = Server::new(TcpListener::bind(format!(\"{host}:{port}\")));\n    server.run(app).await\n}\n\npub fn main() {\n    let result = start();\n\n    if let Some(err) = result.err() {\n        println!(\"Error: {err}\");\n    }\n}\n"
  },
  {
    "path": "examples/poem_example/api/src/service/mod.rs",
    "content": "mod mutation;\nmod query;\n\npub use mutation::*;\npub use query::*;\n"
  },
  {
    "path": "examples/poem_example/api/src/service/mutation.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Mutation;\n\nimpl Mutation {\n    pub async fn create_post(\n        db: &DbConn,\n        form_data: post::Model,\n    ) -> Result<post::ActiveModel, DbErr> {\n        post::ActiveModel {\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n            ..Default::default()\n        }\n        .save(db)\n        .await\n    }\n\n    pub async fn update_post_by_id(\n        db: &DbConn,\n        id: i32,\n        form_data: post::Model,\n    ) -> Result<post::Model, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post::ActiveModel {\n            id: post.id,\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n        }\n        .update(db)\n        .await\n    }\n\n    pub async fn delete_post(db: &DbConn, id: i32) -> Result<DeleteResult, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post.delete(db).await\n    }\n\n    pub async fn delete_all_posts(db: &DbConn) -> Result<DeleteResult, DbErr> {\n        Post::delete_many().exec(db).await\n    }\n}\n"
  },
  {
    "path": "examples/poem_example/api/src/service/query.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Query;\n\nimpl Query {\n    pub async fn find_post_by_id(db: &DbConn, id: i32) -> Result<Option<post::Model>, DbErr> {\n        Post::find_by_id(id).one(db).await\n    }\n\n    /// If ok, returns (post models, num pages).\n    pub async fn find_posts_in_page(\n        db: &DbConn,\n        page: u64,\n        posts_per_page: u64,\n    ) -> Result<(Vec<post::Model>, u64), DbErr> {\n        // Setup paginator\n        let paginator = Post::find()\n            .order_by_asc(post::Column::Id)\n            .paginate(db, posts_per_page);\n        let num_pages = paginator.num_pages().await?;\n\n        // Fetch paginated posts\n        paginator.fetch_page(page - 1).await.map(|p| (p, num_pages))\n    }\n}\n"
  },
  {
    "path": "examples/poem_example/api/static/css/normalize.css",
    "content": "/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\n\n/**\n * 1. Set default font family to sans-serif.\n * 2. Prevent iOS text size adjust after orientation change, without disabling\n *    user zoom.\n */\n\nhtml {\n  font-family: sans-serif; /* 1 */\n  -ms-text-size-adjust: 100%; /* 2 */\n  -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/**\n * Remove default margin.\n */\n\nbody {\n  margin: 0;\n}\n\n/* HTML5 display definitions\n   ========================================================================== */\n\n/**\n * Correct `block` display not defined for any HTML5 element in IE 8/9.\n * Correct `block` display not defined for `details` or `summary` in IE 10/11\n * and Firefox.\n * Correct `block` display not defined for `main` in IE 11.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n/**\n * 1. Correct `inline-block` display not defined in IE 8/9.\n * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n */\n\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block; /* 1 */\n  vertical-align: baseline; /* 2 */\n}\n\n/**\n * Prevent modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n/**\n * Address `[hidden]` styling not present in IE 8/9/10.\n * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.\n */\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n/* Links\n   ========================================================================== */\n\n/**\n * Remove the gray background color from active links in IE 10.\n */\n\na {\n  background-color: transparent;\n}\n\n/**\n * Improve readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n  outline: 0;\n}\n\n/* Text-level semantics\n   ========================================================================== */\n\n/**\n * Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n */\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n/**\n * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n */\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n/**\n * Address styling not present in Safari and Chrome.\n */\n\ndfn {\n  font-style: italic;\n}\n\n/**\n * Address variable `h1` font-size and margin within `section` and `article`\n * contexts in Firefox 4+, Safari, and Chrome.\n */\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n/**\n * Address styling not present in IE 8/9.\n */\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n/**\n * Address inconsistent and variable font size in all browsers.\n */\n\nsmall {\n  font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n/* Embedded content\n   ========================================================================== */\n\n/**\n * Remove border when inside `a` element in IE 8/9/10.\n */\n\nimg {\n  border: 0;\n}\n\n/**\n * Correct overflow not hidden in IE 9/10/11.\n */\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n/* Grouping content\n   ========================================================================== */\n\n/**\n * Address margin not present in IE 8/9 and Safari.\n */\n\nfigure {\n  margin: 1em 40px;\n}\n\n/**\n * Address differences between Firefox and other browsers.\n */\n\nhr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\n\n/**\n * Contain overflow in all browsers.\n */\n\npre {\n  overflow: auto;\n}\n\n/**\n * Address odd `em`-unit font size rendering in all browsers.\n */\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n/* Forms\n   ========================================================================== */\n\n/**\n * Known limitation: by default, Chrome and Safari on OS X allow very limited\n * styling of `select`, unless a `border` property is set.\n */\n\n/**\n * 1. Correct color not being inherited.\n *    Known issue: affects color of disabled elements.\n * 2. Correct font properties not being inherited.\n * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit; /* 1 */\n  font: inherit; /* 2 */\n  margin: 0; /* 3 */\n}\n\n/**\n * Address `overflow` set to `hidden` in IE 8/9/10/11.\n */\n\nbutton {\n  overflow: visible;\n}\n\n/**\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\n * All other form control elements do not inherit `text-transform` values.\n * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n * Correct `select` style inheritance in Firefox.\n */\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n/**\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *    and `video` controls.\n * 2. Correct inability to style clickable `input` types in iOS.\n * 3. Improve usability and consistency of cursor style between image-type\n *    `input` and others.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; /* 2 */\n  cursor: pointer; /* 3 */\n}\n\n/**\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n/**\n * Remove inner padding and border in Firefox 4+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n/**\n * Address Firefox 4+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\ninput {\n  line-height: normal;\n}\n\n/**\n * It's recommended that you don't attempt to style these elements.\n * Firefox's implementation doesn't respect box-sizing, padding, or width.\n *\n * 1. Address box sizing set to `content-box` in IE 8/9/10.\n * 2. Remove excess padding in IE 8/9/10.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Fix the cursor style for Chrome's increment/decrement buttons. For certain\n * `font-size` values of the `input`, it causes the cursor style of the\n * decrement button to change from `default` to `text`.\n */\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n/**\n * 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n * 2. Address `box-sizing` set to `border-box` in Safari and Chrome\n *    (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; /* 1 */\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box; /* 2 */\n  box-sizing: content-box;\n}\n\n/**\n * Remove inner padding and search cancel button in Safari and Chrome on OS X.\n * Safari (but not Chrome) clips the cancel button when the search input has\n * padding (and `textfield` appearance).\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n/**\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n/**\n * 1. Correct `color` not being inherited in IE 8/9/10/11.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\n\nlegend {\n  border: 0; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Remove default vertical scrollbar in IE 8/9/10/11.\n */\n\ntextarea {\n  overflow: auto;\n}\n\n/**\n * Don't inherit the `font-weight` (applied by a rule above).\n * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n */\n\noptgroup {\n  font-weight: bold;\n}\n\n/* Tables\n   ========================================================================== */\n\n/**\n * Remove most spacing between table cells.\n */\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n"
  },
  {
    "path": "examples/poem_example/api/static/css/skeleton.css",
    "content": "/*\n* Skeleton V2.0.4\n* Copyright 2014, Dave Gamache\n* www.getskeleton.com\n* Free to use under the MIT license.\n* https://opensource.org/licenses/mit-license.php\n* 12/29/2014\n*/\n\n\n/* Table of contents\n––––––––––––––––––––––––––––––––––––––––––––––––––\n- Grid\n- Base Styles\n- Typography\n- Links\n- Buttons\n- Forms\n- Lists\n- Code\n- Tables\n- Spacing\n- Utilities\n- Clearing\n- Media Queries\n*/\n\n\n/* Grid\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.container {\n  position: relative;\n  width: 100%;\n  max-width: 960px;\n  margin: 0 auto;\n  padding: 0 20px;\n  box-sizing: border-box; }\n.column,\n.columns {\n  width: 100%;\n  float: left;\n  box-sizing: border-box; }\n\n/* For devices larger than 400px */\n@media (min-width: 400px) {\n  .container {\n    width: 85%;\n    padding: 0; }\n}\n\n/* For devices larger than 550px */\n@media (min-width: 550px) {\n  .container {\n    width: 80%; }\n  .column,\n  .columns {\n    margin-left: 4%; }\n  .column:first-child,\n  .columns:first-child {\n    margin-left: 0; }\n\n  .one.column,\n  .one.columns                    { width: 4.66666666667%; }\n  .two.columns                    { width: 13.3333333333%; }\n  .three.columns                  { width: 22%;            }\n  .four.columns                   { width: 30.6666666667%; }\n  .five.columns                   { width: 39.3333333333%; }\n  .six.columns                    { width: 48%;            }\n  .seven.columns                  { width: 56.6666666667%; }\n  .eight.columns                  { width: 65.3333333333%; }\n  .nine.columns                   { width: 74.0%;          }\n  .ten.columns                    { width: 82.6666666667%; }\n  .eleven.columns                 { width: 91.3333333333%; }\n  .twelve.columns                 { width: 100%; margin-left: 0; }\n\n  .one-third.column               { width: 30.6666666667%; }\n  .two-thirds.column              { width: 65.3333333333%; }\n\n  .one-half.column                { width: 48%; }\n\n  /* Offsets */\n  .offset-by-one.column,\n  .offset-by-one.columns          { margin-left: 8.66666666667%; }\n  .offset-by-two.column,\n  .offset-by-two.columns          { margin-left: 17.3333333333%; }\n  .offset-by-three.column,\n  .offset-by-three.columns        { margin-left: 26%;            }\n  .offset-by-four.column,\n  .offset-by-four.columns         { margin-left: 34.6666666667%; }\n  .offset-by-five.column,\n  .offset-by-five.columns         { margin-left: 43.3333333333%; }\n  .offset-by-six.column,\n  .offset-by-six.columns          { margin-left: 52%;            }\n  .offset-by-seven.column,\n  .offset-by-seven.columns        { margin-left: 60.6666666667%; }\n  .offset-by-eight.column,\n  .offset-by-eight.columns        { margin-left: 69.3333333333%; }\n  .offset-by-nine.column,\n  .offset-by-nine.columns         { margin-left: 78.0%;          }\n  .offset-by-ten.column,\n  .offset-by-ten.columns          { margin-left: 86.6666666667%; }\n  .offset-by-eleven.column,\n  .offset-by-eleven.columns       { margin-left: 95.3333333333%; }\n\n  .offset-by-one-third.column,\n  .offset-by-one-third.columns    { margin-left: 34.6666666667%; }\n  .offset-by-two-thirds.column,\n  .offset-by-two-thirds.columns   { margin-left: 69.3333333333%; }\n\n  .offset-by-one-half.column,\n  .offset-by-one-half.columns     { margin-left: 52%; }\n\n}\n\n\n/* Base Styles\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n/* NOTE\nhtml is set to 62.5% so that all the REM measurements throughout Skeleton\nare based on 10px sizing. So basically 1.5rem = 15px :) */\nhtml {\n  font-size: 62.5%; }\nbody {\n  font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */\n  line-height: 1.6;\n  font-weight: 400;\n  font-family: \"Raleway\", \"HelveticaNeue\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  color: #222; }\n\n\n/* Typography\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nh1, h2, h3, h4, h5, h6 {\n  margin-top: 0;\n  margin-bottom: 2rem;\n  font-weight: 300; }\nh1 { font-size: 4.0rem; line-height: 1.2;  letter-spacing: -.1rem;}\nh2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; }\nh3 { font-size: 3.0rem; line-height: 1.3;  letter-spacing: -.1rem; }\nh4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; }\nh5 { font-size: 1.8rem; line-height: 1.5;  letter-spacing: -.05rem; }\nh6 { font-size: 1.5rem; line-height: 1.6;  letter-spacing: 0; }\n\n/* Larger than phablet */\n@media (min-width: 550px) {\n  h1 { font-size: 5.0rem; }\n  h2 { font-size: 4.2rem; }\n  h3 { font-size: 3.6rem; }\n  h4 { font-size: 3.0rem; }\n  h5 { font-size: 2.4rem; }\n  h6 { font-size: 1.5rem; }\n}\n\np {\n  margin-top: 0; }\n\n\n/* Links\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\na {\n  color: #1EAEDB; }\na:hover {\n  color: #0FA0CE; }\n\n\n/* Buttons\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.button,\nbutton,\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n  display: inline-block;\n  height: 38px;\n  padding: 0 30px;\n  color: #555;\n  text-align: center;\n  font-size: 11px;\n  font-weight: 600;\n  line-height: 38px;\n  letter-spacing: .1rem;\n  text-transform: uppercase;\n  text-decoration: none;\n  white-space: nowrap;\n  background-color: transparent;\n  border-radius: 4px;\n  border: 1px solid #bbb;\n  cursor: pointer;\n  box-sizing: border-box; }\n.button:hover,\nbutton:hover,\ninput[type=\"submit\"]:hover,\ninput[type=\"reset\"]:hover,\ninput[type=\"button\"]:hover,\n.button:focus,\nbutton:focus,\ninput[type=\"submit\"]:focus,\ninput[type=\"reset\"]:focus,\ninput[type=\"button\"]:focus {\n  color: #333;\n  border-color: #888;\n  outline: 0; }\n.button.button-primary,\nbutton.button-primary,\nbutton.primary,\ninput[type=\"submit\"].button-primary,\ninput[type=\"reset\"].button-primary,\ninput[type=\"button\"].button-primary {\n  color: #FFF;\n  background-color: #33C3F0;\n  border-color: #33C3F0; }\n.button.button-primary:hover,\nbutton.button-primary:hover,\nbutton.primary:hover,\ninput[type=\"submit\"].button-primary:hover,\ninput[type=\"reset\"].button-primary:hover,\ninput[type=\"button\"].button-primary:hover,\n.button.button-primary:focus,\nbutton.button-primary:focus,\nbutton.primary:focus,\ninput[type=\"submit\"].button-primary:focus,\ninput[type=\"reset\"].button-primary:focus,\ninput[type=\"button\"].button-primary:focus {\n  color: #FFF;\n  background-color: #1EAEDB;\n  border-color: #1EAEDB; }\n\n\n/* Forms\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ninput[type=\"text\"],\ninput[type=\"tel\"],\ninput[type=\"url\"],\ninput[type=\"password\"],\ntextarea,\nselect {\n  height: 38px;\n  padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */\n  background-color: #fff;\n  border: 1px solid #D1D1D1;\n  border-radius: 4px;\n  box-shadow: none;\n  box-sizing: border-box; }\n/* Removes awkward default styles on some inputs for iOS */\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ninput[type=\"text\"],\ninput[type=\"tel\"],\ninput[type=\"url\"],\ninput[type=\"password\"],\ntextarea {\n  -webkit-appearance: none;\n     -moz-appearance: none;\n          appearance: none; }\ntextarea {\n  min-height: 65px;\n  padding-top: 6px;\n  padding-bottom: 6px; }\ninput[type=\"email\"]:focus,\ninput[type=\"number\"]:focus,\ninput[type=\"search\"]:focus,\ninput[type=\"text\"]:focus,\ninput[type=\"tel\"]:focus,\ninput[type=\"url\"]:focus,\ninput[type=\"password\"]:focus,\ntextarea:focus,\nselect:focus {\n  border: 1px solid #33C3F0;\n  outline: 0; }\nlabel,\nlegend {\n  display: block;\n  margin-bottom: .5rem;\n  font-weight: 600; }\nfieldset {\n  padding: 0;\n  border-width: 0; }\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  display: inline; }\nlabel > .label-body {\n  display: inline-block;\n  margin-left: .5rem;\n  font-weight: normal; }\n\n\n/* Lists\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nul {\n  list-style: circle inside; }\nol {\n  list-style: decimal inside; }\nol, ul {\n  padding-left: 0;\n  margin-top: 0; }\nul ul,\nul ol,\nol ol,\nol ul {\n  margin: 1.5rem 0 1.5rem 3rem;\n  font-size: 90%; }\nli {\n  margin-bottom: 1rem; }\n\n\n/* Code\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\ncode {\n  padding: .2rem .5rem;\n  margin: 0 .2rem;\n  font-size: 90%;\n  white-space: nowrap;\n  background: #F1F1F1;\n  border: 1px solid #E1E1E1;\n  border-radius: 4px; }\npre > code {\n  display: block;\n  padding: 1rem 1.5rem;\n  white-space: pre; }\n\n\n/* Tables\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nth,\ntd {\n  padding: 12px 15px;\n  text-align: left;\n  border-bottom: 1px solid #E1E1E1; }\nth:first-child,\ntd:first-child {\n  padding-left: 0; }\nth:last-child,\ntd:last-child {\n  padding-right: 0; }\n\n\n/* Spacing\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nbutton,\n.button {\n  margin-bottom: 1rem; }\ninput,\ntextarea,\nselect,\nfieldset {\n  margin-bottom: 1.5rem; }\npre,\nblockquote,\ndl,\nfigure,\ntable,\np,\nul,\nol,\nform {\n  margin-bottom: 2.5rem; }\n\n\n/* Utilities\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.u-full-width {\n  width: 100%;\n  box-sizing: border-box; }\n.u-max-full-width {\n  max-width: 100%;\n  box-sizing: border-box; }\n.u-pull-right {\n  float: right; }\n.u-pull-left {\n  float: left; }\n\n\n/* Misc\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nhr {\n  margin-top: 3rem;\n  margin-bottom: 3.5rem;\n  border-width: 0;\n  border-top: 1px solid #E1E1E1; }\n\n\n/* Clearing\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n\n/* Self Clearing Goodness */\n.container:after,\n.row:after,\n.u-cf {\n  content: \"\";\n  display: table;\n  clear: both; }\n\n\n/* Media Queries\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n/*\nNote: The best way to structure the use of media queries is to create the queries\nnear the relevant code. For example, if you wanted to change the styles for buttons\non small devices, paste the mobile query code up in the buttons section and style it\nthere.\n*/\n\n\n/* Larger than mobile */\n@media (min-width: 400px) {}\n\n/* Larger than phablet (also point when grid becomes active) */\n@media (min-width: 550px) {}\n\n/* Larger than tablet */\n@media (min-width: 750px) {}\n\n/* Larger than desktop */\n@media (min-width: 1000px) {}\n\n/* Larger than Desktop HD */\n@media (min-width: 1200px) {}\n"
  },
  {
    "path": "examples/poem_example/api/static/css/style.css",
    "content": ".field-error {\n  border: 1px solid #ff0000 !important;\n}\n\n.field-error-flash {\n  color: #ff0000;\n  display: block;\n  margin: -10px 0 10px 0;\n}\n\n.field-success {\n  border: 1px solid #5ab953 !important;\n}\n\n.field-success-flash {\n  color: #5ab953;\n  display: block;\n  margin: -10px 0 10px 0;\n}\n\nspan.completed {\n  text-decoration: line-through;\n}\n\nform.inline {\n  display: inline;\n}\n\nform.link,\nbutton.link {\n  display: inline;\n  color: #1eaedb;\n  border: none;\n  outline: none;\n  background: none;\n  cursor: pointer;\n  padding: 0;\n  margin: 0 0 0 0;\n  height: inherit;\n  text-decoration: underline;\n  font-size: inherit;\n  text-transform: none;\n  font-weight: normal;\n  line-height: inherit;\n  letter-spacing: inherit;\n}\n\nform.link:hover,\nbutton.link:hover {\n  color: #0fa0ce;\n}\n\nbutton.small {\n  height: 20px;\n  padding: 0 10px;\n  font-size: 10px;\n  line-height: 20px;\n  margin: 0 2.5px;\n}\n\n.post:hover {\n  background-color: #bce2ee;\n}\n\n.post td {\n  padding: 5px;\n  width: 150px;\n}\n\n#delete-button {\n  color: red;\n  border-color: red;\n}\n"
  },
  {
    "path": "examples/poem_example/api/templates/edit.html.tera",
    "content": "{% extends \"layout.html.tera\" %} {% block content %}\n<div class=\"row\">\n  <h4>Edit Post</h4>\n  <div class=\"twelve columns\">\n    <div class=\"ten columns\">\n      <form action=\"/{{ post.id }}\" method=\"post\">\n        <div class=\"twelve columns\">\n          <input\n            type=\"text\"\n            placeholder=\"title\"\n            name=\"title\"\n            id=\"title\"\n            value=\"{{ post.title }}\"\n            autofocus\n            class=\"u-full-width\"\n          />\n          <input\n            type=\"text\"\n            placeholder=\"content\"\n            name=\"text\"\n            id=\"text\"\n            value=\"{{ post.text }}\"\n            autofocus\n            class=\"u-full-width\"\n          />\n        </div>\n        <div class=\"twelve columns\">\n          <div class=\"two columns\">\n            <a href=\"/\">\n              <input type=\"button\" value=\"cancel\" />\n            </a>\n          </div>\n          <div class=\"eight columns\"></div>\n          <div class=\"two columns\">\n            <input type=\"submit\" value=\"save post\" />\n          </div>\n        </div>\n      </form>\n    </div>\n    <div class=\"two columns\">\n      <form action=\"/delete/{{ post.id }}\" method=\"post\">\n        <div class=\"two columns\">\n          <input id=\"delete-button\" type=\"submit\" value=\"delete post\" />\n        </div>\n      </form>\n    </div>\n  </div>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/poem_example/api/templates/error/404.html.tera",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>404 - tera</title>\n  </head>\n  <body>\n    <h1>404: Hey! There's nothing here.</h1>\n    The page at {{ uri }} does not exist!\n  </body>\n</html>\n"
  },
  {
    "path": "examples/poem_example/api/templates/index.html.tera",
    "content": "{% extends \"layout.html.tera\" %} {% block content %}\n<div class=\"container\">\n  <p><!--Nothing to see here --></p>\n  <h1>Posts</h1>\n  {% if flash %}\n  <small class=\"field-{{ flash.kind }}-flash\">\n    {{ flash.message }}\n  </small>\n  {% endif %}\n  <table>\n    <tbody>\n      <thead>\n        <tr>\n          <th>ID</th>\n          <th>Title</th>\n          <th>Text</th>\n        </tr>\n      </thead>\n      {% for post in posts %}\n      <tr class=\"post\" onclick=\"window.location='/{{ post.id }}';\">\n        <td>{{ post.id }}</td>\n        <td>{{ post.title }}</td>\n        <td>{{ post.text }}</td>\n      </tr>\n      {% endfor %}\n    </tbody>\n    <tfoot>\n      <tr>\n        <td></td>\n        <td>\n          {% if page == 1 %} Previous {% else %}\n          <a href=\"/?page={{ page - 1 }}&posts_per_page={{ posts_per_page }}\"\n            >Previous</a\n          >\n          {% endif %} | {% if page == num_pages %} Next {% else %}\n          <a href=\"/?page={{ page + 1 }}&posts_per_page={{ posts_per_page }}\"\n            >Next</a\n          >\n          {% endif %}\n        </td>\n        <td></td>\n      </tr>\n    </tfoot>\n  </table>\n\n  <div class=\"twelve columns\">\n    <a href=\"/new\">\n      <input type=\"button\" value=\"add post\" />\n    </a>\n  </div>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/poem_example/api/templates/layout.html.tera",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>Poem Example</title>\n    <meta name=\"description\" content=\"Actix - SeaOrm integration example\" />\n    <meta name=\"author\" content=\"Sam Samai\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\n    <link\n      href=\"//fonts.googleapis.com/css?family=Raleway:400,300,600\"\n      rel=\"stylesheet\"\n      type=\"text/css\"\n    />\n    <link rel=\"stylesheet\" href=\"/static/css/normalize.css\" />\n    <link rel=\"stylesheet\" href=\"/static/css/skeleton.css\" />\n    <link rel=\"stylesheet\" href=\"/static/css/style.css\" />\n    <link rel=\"icon\" type=\"image/png\" href=\"/static/images/favicon.png\" />\n  </head>\n  <body>\n    <div class=\"container\">\n      <p><!--Nothing to see here --></p>\n      {% block content %}{% endblock content %}\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/poem_example/api/templates/new.html.tera",
    "content": "{% extends \"layout.html.tera\" %} {% block content %}\n<div class=\"row\">\n  <h4>New Post</h4>\n  <form action=\"/\" method=\"post\">\n    <div class=\"twelve columns\">\n      <input\n        type=\"text\"\n        placeholder=\"enter title\"\n        name=\"title\"\n        id=\"title\"\n        value=\"\"\n        autofocus\n        class=\"u-full-width\"\n      />\n      <input\n        type=\"text\"\n        placeholder=\"enter content\"\n        name=\"text\"\n        id=\"text\"\n        value=\"\"\n        autofocus\n        class=\"u-full-width\"\n      />\n    </div>\n    <div class=\"twelve columns\">\n      <div class=\"two columns\">\n        <a href=\"/\">\n          <input type=\"button\" value=\"cancel\" />\n        </a>\n      </div>\n      <div class=\"eight columns\"></div>\n      <div class=\"two columns\">\n        <input type=\"submit\" value=\"save post\" />\n      </div>\n    </div>\n  </form>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/poem_example/api/tests/crud_tests.rs",
    "content": "use entity::post;\nuse poem_example_api::service::{Mutation, Query};\nuse sea_orm::Database;\n\n#[tokio::test]\nasync fn crud_tests() {\n    let db = &Database::connect(\"sqlite::memory:\").await.unwrap();\n\n    db.get_schema_builder()\n        .register(post::Entity)\n        .apply(db)\n        .await\n        .unwrap();\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title A\".to_owned(),\n                text: \"Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(1),\n                title: sea_orm::ActiveValue::Unchanged(\"Title A\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text A\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title B\".to_owned(),\n                text: \"Text B\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(2),\n                title: sea_orm::ActiveValue::Unchanged(\"Title B\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text B\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 1).await.unwrap().unwrap();\n\n        assert_eq!(post.id, 1);\n        assert_eq!(post.title, \"Title A\");\n    }\n\n    {\n        let post = Mutation::update_post_by_id(\n            db,\n            1,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            }\n        );\n    }\n\n    {\n        let result = Mutation::delete_post(db, 2).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 2).await.unwrap();\n        assert!(post.is_none());\n    }\n\n    {\n        let result = Mutation::delete_all_posts(db).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n}\n"
  },
  {
    "path": "examples/poem_example/entity/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"entity\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"entity\"\npath = \"src/lib.rs\"\n\n[dependencies]\nserde = { version = \"1\", features = [\"derive\"] }\n\n[dependencies.sea-orm]\npath    = \"../../../\"    # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n"
  },
  {
    "path": "examples/poem_example/entity/src/lib.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub mod prelude;\n\npub mod post;\n"
  },
  {
    "path": "examples/poem_example/entity/src/post.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"post\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    pub title: String,\n    #[sea_orm(column_type = \"Text\")]\n    pub text: String,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/poem_example/entity/src/prelude.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub use super::post::Entity as Post;\n"
  },
  {
    "path": "examples/poem_example/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nentity = { path = \"../entity\" }\ntokio  = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable following runtime and db backend features if you want to run migration via CLI\n    \"runtime-tokio-native-tls\",\n    \"sqlx-sqlite\",\n]\npath = \"../../../sea-orm-migration\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/poem_example/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/poem_example/migration/src/lib.rs",
    "content": "pub use sea_orm_migration::prelude::*;\n\nmod m20220120_000001_create_post_table;\nmod m20220120_000002_seed_posts;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220120_000001_create_post_table::Migration),\n            Box::new(m20220120_000002_seed_posts::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "examples/poem_example/migration/src/m20220120_000001_create_post_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"post\")\n                    .if_not_exists()\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"title\"))\n                    .col(string(\"text\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"post\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/poem_example/migration/src/m20220120_000002_seed_posts.rs",
    "content": "use entity::post;\nuse sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};\nuse sea_orm_migration::prelude::*;\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let seed_data = vec![\n            (\"First Post\", \"This is the first post.\"),\n            (\"Second Post\", \"This is another post.\"),\n        ];\n\n        for (title, text) in seed_data {\n            let model = post::ActiveModel {\n                title: Set(title.to_string()),\n                text: Set(text.to_string()),\n                ..Default::default()\n            };\n            model.insert(db).await?;\n        }\n\n        println!(\"Posts table seeded successfully.\");\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let titles_to_delete = vec![\"First Post\", \"Second Post\"];\n        post::Entity::delete_many()\n            .filter(post::Column::Title.is_in(titles_to_delete))\n            .exec(db)\n            .await?;\n\n        println!(\"Posts seeded data removed.\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/poem_example/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/poem_example/src/main.rs",
    "content": "fn main() {\n    poem_example_api::main();\n}\n"
  },
  {
    "path": "examples/proxy_cloudflare_worker_example/.gitignore",
    "content": "target\nnode_modules\n.wrangler\nbuild\ndist\n"
  },
  {
    "path": "examples/proxy_cloudflare_worker_example/Cargo.toml",
    "content": "[package]\nauthors      = [\"Langyo <langyo.china@gmail.com>\"]\nedition      = \"2024\"\nname         = \"sea-orm-proxy-cloudflare-worker-example\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[workspace]\n\n[package.metadata.release]\nrelease = false\n\n# https://github.com/rustwasm/wasm-pack/issues/1247\n[package.metadata.wasm-pack.profile.release]\nwasm-opt = false\n\n[lib]\ncrate-type = [\"cdylib\"]\n\n[dependencies]\nanyhow      = \"1\"\nasync-trait = \"0.1\"\nonce_cell   = \"1\"\nserde       = { version = \"1\", features = [\"derive\"] }\nserde_json  = \"1\"\n\naxum          = { version = \"0.7\", default-features = false, features = [\"macros\"] }\ntower-service = \"0.3.2\"\nworker        = { version = \"0.3.0\", features = ['http', 'axum', \"d1\"] }\nworker-macros = { version = \"0.3.0\", features = ['http'] }\n\nchrono = \"0.4\"\nuuid   = { version = \"1\", features = [\"v4\"] }\n\nconsole_error_panic_hook = { version = \"0.1\" }\ngloo                     = \"0.11\"\noneshot                  = \"0.1\"\nwasm-bindgen             = \"0.2.92\"\nwasm-bindgen-futures     = { version = \"0.4\" }\n\nsea-orm = { path = \"../../\", default-features = false, features = [\n    \"macros\",\n    \"proxy\",\n    \"with-uuid\",\n    \"with-chrono\",\n    \"with-json\",\n    \"debug-print\",\n] }\n\n[patch.crates-io]\n# https://github.com/cloudflare/workers-rs/pull/591\nworker = { git = \"https://github.com/cloudflare/workers-rs.git\", rev = \"ff2e6a0fd58b7e7b4b7651aba46e04067597eb03\" }\n"
  },
  {
    "path": "examples/proxy_cloudflare_worker_example/README.md",
    "content": "# SeaORM Proxy Demo for Cloudflare Workers\n\nThis is a simple Cloudflare worker written in Rust. It uses the `sea-orm` ORM to interact with SQLite that is stored in the Cloudflare D1. It also uses `axum` as the server framework.\n\nIt's inspired by the [Cloudflare Workers Demo with Rust](https://github.com/logankeenan/full-stack-rust-cloudflare-axum).\n\n## Run\n\nMake sure you have `npm` and `cargo` installed. Be sure to use the latest version of `nodejs` and `rust`.\n\n```bash\nnpx wrangler dev\n```\n"
  },
  {
    "path": "examples/proxy_cloudflare_worker_example/Wrangler.toml",
    "content": "compatibility_date = \"2024-07-08\"\nmain               = \"build/worker/shim.mjs\"\nname               = \"axum\"\n\n[[d1_databases]]\nbinding       = \"test-d1\"\ndatabase_name = \"axumtest\"\n# Change it if you want to use your own database\ndatabase_id = \"00000000-0000-0000-0000-000000000000\"\n\n[build]\ncommand = \"cargo install -q worker-build && worker-build --release\"\n"
  },
  {
    "path": "examples/proxy_cloudflare_worker_example/src/entity.rs",
    "content": "use sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)]\n#[sea_orm(table_name = \"posts\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i64,\n\n    pub title: String,\n    pub text: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/proxy_cloudflare_worker_example/src/lib.rs",
    "content": "use anyhow::Result;\nuse axum::{body::Body, response::Response};\nuse tower_service::Service;\nuse worker::{Context, Env, HttpRequest, event};\n\npub(crate) mod entity;\npub(crate) mod orm;\npub(crate) mod route;\n\n// https://developers.cloudflare.com/workers/languages/rust\n#[event(fetch)]\nasync fn fetch(req: HttpRequest, env: Env, _ctx: Context) -> Result<Response<Body>> {\n    console_error_panic_hook::set_once();\n\n    Ok(route::router(env).call(req).await?)\n}\n"
  },
  {
    "path": "examples/proxy_cloudflare_worker_example/src/orm.rs",
    "content": "use anyhow::{Context, Result, anyhow};\nuse std::{collections::BTreeMap, sync::Arc};\nuse wasm_bindgen::JsValue;\n\nuse sea_orm::{\n    ConnectionTrait, Database, DatabaseConnection, DbBackend, DbErr, ProxyDatabaseTrait,\n    ProxyExecResult, ProxyRow, RuntimeErr, Schema, Statement, Value, Values,\n};\nuse worker::{Env, console_log};\n\nstruct ProxyDb {\n    env: Arc<Env>,\n}\n\nimpl std::fmt::Debug for ProxyDb {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        f.debug_struct(\"ProxyDb\").finish()\n    }\n}\n\nimpl ProxyDb {\n    async fn do_query(env: Arc<Env>, statement: Statement) -> Result<Vec<ProxyRow>> {\n        let sql = statement.sql.clone();\n        let values = match statement.values {\n            Some(Values(values)) => values\n                .iter()\n                .map(|val| match &val {\n                    Value::BigInt(Some(val)) => JsValue::from(val.to_string()),\n                    Value::BigUnsigned(Some(val)) => JsValue::from(val.to_string()),\n                    Value::Int(Some(val)) => JsValue::from(*val),\n                    Value::Unsigned(Some(val)) => JsValue::from(*val),\n                    Value::SmallInt(Some(val)) => JsValue::from(*val),\n                    Value::SmallUnsigned(Some(val)) => JsValue::from(*val),\n                    Value::TinyInt(Some(val)) => JsValue::from(*val),\n                    Value::TinyUnsigned(Some(val)) => JsValue::from(*val),\n\n                    Value::Float(Some(val)) => JsValue::from_f64(*val as f64),\n                    Value::Double(Some(val)) => JsValue::from_f64(*val),\n\n                    Value::Bool(Some(val)) => JsValue::from(*val),\n                    Value::Bytes(Some(val)) => JsValue::from(format!(\n                        \"X'{}'\",\n                        val.iter()\n                            .map(|byte| format!(\"{:02x}\", byte))\n                            .collect::<String>()\n                    )),\n                    Value::Char(Some(val)) => JsValue::from(val.to_string()),\n                    Value::Json(Some(val)) => JsValue::from(val.to_string()),\n                    Value::String(Some(val)) => JsValue::from(val.to_string()),\n\n                    Value::ChronoDate(Some(val)) => JsValue::from(val.to_string()),\n                    Value::ChronoDateTime(Some(val)) => JsValue::from(val.to_string()),\n                    Value::ChronoDateTimeLocal(Some(val)) => JsValue::from(val.to_string()),\n                    Value::ChronoDateTimeUtc(Some(val)) => JsValue::from(val.to_string()),\n                    Value::ChronoDateTimeWithTimeZone(Some(val)) => JsValue::from(val.to_string()),\n\n                    _ => JsValue::NULL,\n                })\n                .collect(),\n            None => Vec::new(),\n        };\n\n        console_log!(\"SQL query values: {:?}\", values);\n        let ret = env.d1(\"test-d1\")?.prepare(sql).bind(&values)?.all().await?;\n        if let Some(message) = ret.error() {\n            return Err(anyhow!(message.to_string()));\n        }\n\n        let ret = ret.results::<serde_json::Value>()?;\n        let ret = ret\n            .iter()\n            .map(|row| {\n                let mut values = BTreeMap::new();\n                for (key, value) in row.as_object().unwrap() {\n                    values.insert(\n                        key.clone(),\n                        match &value {\n                            serde_json::Value::Bool(val) => Value::Bool(Some(*val)),\n                            serde_json::Value::Number(val) => {\n                                if val.is_i64() {\n                                    Value::BigInt(Some(val.as_i64().unwrap()))\n                                } else if val.is_u64() {\n                                    Value::BigUnsigned(Some(val.as_u64().unwrap()))\n                                } else {\n                                    Value::Double(Some(val.as_f64().unwrap()))\n                                }\n                            }\n                            serde_json::Value::String(val) => {\n                                Value::String(Some(Box::new(val.clone())))\n                            }\n                            _ => unreachable!(\"Unsupported JSON value\"),\n                        },\n                    );\n                }\n                ProxyRow { values }\n            })\n            .collect();\n        console_log!(\"SQL query result: {:?}\", ret);\n\n        Ok(ret)\n    }\n\n    async fn do_execute(env: Arc<Env>, statement: Statement) -> Result<ProxyExecResult> {\n        let sql = statement.sql.clone();\n        let values = match statement.values {\n            Some(Values(values)) => values\n                .iter()\n                .map(|val| match &val {\n                    Value::BigInt(Some(val)) => JsValue::from(val.to_string()),\n                    Value::BigUnsigned(Some(val)) => JsValue::from(val.to_string()),\n                    Value::Int(Some(val)) => JsValue::from(*val),\n                    Value::Unsigned(Some(val)) => JsValue::from(*val),\n                    Value::SmallInt(Some(val)) => JsValue::from(*val),\n                    Value::SmallUnsigned(Some(val)) => JsValue::from(*val),\n                    Value::TinyInt(Some(val)) => JsValue::from(*val),\n                    Value::TinyUnsigned(Some(val)) => JsValue::from(*val),\n\n                    Value::Float(Some(val)) => JsValue::from_f64(*val as f64),\n                    Value::Double(Some(val)) => JsValue::from_f64(*val),\n\n                    Value::Bool(Some(val)) => JsValue::from(*val),\n                    Value::Bytes(Some(val)) => JsValue::from(format!(\n                        \"X'{}'\",\n                        val.iter()\n                            .map(|byte| format!(\"{:02x}\", byte))\n                            .collect::<String>()\n                    )),\n                    Value::Char(Some(val)) => JsValue::from(val.to_string()),\n                    Value::Json(Some(val)) => JsValue::from(val.to_string()),\n                    Value::String(Some(val)) => JsValue::from(val.to_string()),\n\n                    Value::ChronoDate(Some(val)) => JsValue::from(val.to_string()),\n                    Value::ChronoDateTime(Some(val)) => JsValue::from(val.to_string()),\n                    Value::ChronoDateTimeLocal(Some(val)) => JsValue::from(val.to_string()),\n                    Value::ChronoDateTimeUtc(Some(val)) => JsValue::from(val.to_string()),\n                    Value::ChronoDateTimeWithTimeZone(Some(val)) => JsValue::from(val.to_string()),\n\n                    _ => JsValue::NULL,\n                })\n                .collect(),\n            None => Vec::new(),\n        };\n\n        let ret = env\n            .d1(\"test-d1\")?\n            .prepare(sql)\n            .bind(&values)?\n            .run()\n            .await?\n            .meta()?;\n        console_log!(\"SQL execute result: {:?}\", ret);\n\n        let last_insert_id = ret\n            .as_ref()\n            .map(|meta| meta.last_row_id.unwrap_or(0))\n            .unwrap_or(0) as u64;\n        let rows_affected = ret\n            .as_ref()\n            .map(|meta| meta.rows_written.unwrap_or(0))\n            .unwrap_or(0) as u64;\n\n        Ok(ProxyExecResult {\n            last_insert_id,\n            rows_affected,\n        })\n    }\n}\n\n#[async_trait::async_trait]\nimpl ProxyDatabaseTrait for ProxyDb {\n    async fn query(&self, statement: Statement) -> Result<Vec<ProxyRow>, DbErr> {\n        console_log!(\"SQL query: {:?}\", statement);\n\n        let env = self.env.clone();\n        let (tx, rx) = oneshot::channel();\n        wasm_bindgen_futures::spawn_local(async move {\n            let ret = Self::do_query(env, statement).await;\n            tx.send(ret).unwrap();\n        });\n\n        let ret = rx.await.unwrap();\n        ret.map_err(|err| DbErr::Conn(RuntimeErr::Internal(err.to_string())))\n    }\n\n    async fn execute(&self, statement: Statement) -> Result<ProxyExecResult, DbErr> {\n        console_log!(\"SQL execute: {:?}\", statement);\n\n        let env = self.env.clone();\n        let (tx, rx) = oneshot::channel();\n        wasm_bindgen_futures::spawn_local(async move {\n            let ret = Self::do_execute(env, statement).await;\n            tx.send(ret).unwrap();\n        });\n\n        let ret = rx.await.unwrap();\n        ret.map_err(|err| DbErr::Conn(RuntimeErr::Internal(err.to_string())))\n    }\n}\n\npub async fn init_db(env: Arc<Env>) -> Result<DatabaseConnection> {\n    let db = Database::connect_proxy(DbBackend::Sqlite, Arc::new(Box::new(ProxyDb { env })))\n        .await\n        .context(\"Failed to connect to database\")?;\n    let builder = db.get_database_backend();\n\n    console_log!(\"Connected to database\");\n\n    db.execute(\n        builder.build(\n            Schema::new(builder)\n                .create_table_from_entity(crate::entity::Entity)\n                .if_not_exists(),\n        ),\n    )\n    .await?;\n\n    Ok(db)\n}\n"
  },
  {
    "path": "examples/proxy_cloudflare_worker_example/src/route.rs",
    "content": "use anyhow::Result;\nuse std::sync::Arc;\n\nuse axum::{Router, extract::State, http::StatusCode, response::IntoResponse, routing::get};\nuse worker::{Env, console_error, console_log};\n\nuse sea_orm::{\n    ActiveModelTrait,\n    ActiveValue::{NotSet, Set},\n    EntityTrait,\n};\n\n#[derive(Clone)]\nstruct CFEnv {\n    pub env: Arc<Env>,\n}\n\nunsafe impl Send for CFEnv {}\nunsafe impl Sync for CFEnv {}\n\npub fn router(env: Env) -> Router {\n    let state = CFEnv { env: Arc::new(env) };\n\n    Router::new()\n        .route(\"/\", get(handler_get))\n        .route(\"/generate\", get(handler_generate))\n        .with_state(state)\n}\n\nasync fn handler_get(\n    State(state): State<CFEnv>,\n) -> Result<impl IntoResponse, (StatusCode, String)> {\n    let env = state.env.clone();\n    let db = crate::orm::init_db(env).await.map_err(|err| {\n        console_log!(\"Failed to connect to database: {:?}\", err);\n        (\n            StatusCode::INTERNAL_SERVER_ERROR,\n            \"Failed to connect to database\".to_string(),\n        )\n    })?;\n\n    let ret = crate::entity::Entity::find()\n        .all(&db)\n        .await\n        .map_err(|err| {\n            console_log!(\"Failed to query database: {:?}\", err);\n            (\n                StatusCode::INTERNAL_SERVER_ERROR,\n                \"Failed to query database\".to_string(),\n            )\n        })?;\n    let ret = serde_json::to_string(&ret).map_err(|err| {\n        console_error!(\"Failed to serialize response: {:?}\", err);\n        (\n            StatusCode::INTERNAL_SERVER_ERROR,\n            \"Failed to serialize response\".to_string(),\n        )\n    })?;\n\n    Ok(ret.into_response())\n}\n\nasync fn handler_generate(\n    State(state): State<CFEnv>,\n) -> Result<impl IntoResponse, (StatusCode, String)> {\n    let env = state.env.clone();\n    let db = crate::orm::init_db(env).await.map_err(|err| {\n        console_log!(\"Failed to connect to database: {:?}\", err);\n        (\n            StatusCode::INTERNAL_SERVER_ERROR,\n            \"Failed to connect to database\".to_string(),\n        )\n    })?;\n\n    let ret = crate::entity::ActiveModel {\n        id: NotSet,\n        title: Set(chrono::Utc::now().to_rfc3339()),\n        text: Set(uuid::Uuid::new_v4().to_string()),\n    };\n\n    let ret = ret.insert(&db).await.map_err(|err| {\n        console_log!(\"Failed to insert into database: {:?}\", err);\n        (\n            StatusCode::INTERNAL_SERVER_ERROR,\n            \"Failed to insert into database\".to_string(),\n        )\n    })?;\n\n    Ok(format!(\"Inserted: {:?}\", ret).into_response())\n}\n"
  },
  {
    "path": "examples/proxy_gluesql_example/Cargo.toml",
    "content": "[package]\nauthors      = [\"Langyo <langyo.china@gmail.com>\"]\nedition      = \"2024\"\nname         = \"sea-orm-proxy-gluesql-example\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[workspace]\n\n[dependencies]\nasync-std    = { version = \"1.12\", features = [\"attributes\", \"tokio1\"] }\nasync-stream = { version = \"0.3\" }\nasync-trait  = { version = \"0.1\" }\nbigdecimal   = { version = \"=0.4.9\" }\nfutures      = { version = \"0.3\" }\nfutures-util = { version = \"0.3\" }\nserde        = { version = \"1\" }\nserde_json   = { version = \"1\" }\n\ngluesql = { version = \"0.15\", default-features = false, features = [\n    \"memory-storage\",\n] }\nsea-orm = { path = \"../../\", default-features = false, features = [\n    \"macros\",\n    \"proxy\",\n    \"debug-print\",\n] }\nsqlparser = \"0.40\"\n\n[dev-dependencies]\nsmol       = { version = \"1.2\" }\nsmol-potat = { version = \"1.1\" }\n"
  },
  {
    "path": "examples/proxy_gluesql_example/README.md",
    "content": "# SeaORM Proxy Demo for GlueSQL\n\nRun this demo for [GlueSQL](https://gluesql.org/) with the following command:\n\n```bash\ncargo run\n```\n"
  },
  {
    "path": "examples/proxy_gluesql_example/src/entity/mod.rs",
    "content": "pub mod post;\n"
  },
  {
    "path": "examples/proxy_gluesql_example/src/entity/post.rs",
    "content": "use sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize)]\n#[sea_orm(table_name = \"posts\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i64,\n\n    pub title: String,\n    pub text: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/proxy_gluesql_example/src/main.rs",
    "content": "//! Proxy connection example.\n\n#![deny(missing_docs)]\n\nmod entity;\n\nuse std::{\n    collections::BTreeMap,\n    sync::{Arc, Mutex},\n};\n\nuse gluesql::{memory_storage::MemoryStorage, prelude::Glue};\nuse sea_orm::{\n    ActiveValue::Set, Database, DbBackend, DbErr, EntityTrait, ProxyDatabaseTrait, ProxyExecResult,\n    ProxyRow, Statement,\n};\n\nuse entity::post::{ActiveModel, Entity};\n\nstruct ProxyDb {\n    mem: Mutex<Glue<MemoryStorage>>,\n}\n\nimpl std::fmt::Debug for ProxyDb {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        f.debug_struct(\"ProxyDb\").finish()\n    }\n}\n\n#[async_trait::async_trait]\nimpl ProxyDatabaseTrait for ProxyDb {\n    async fn query(&self, statement: Statement) -> Result<Vec<ProxyRow>, DbErr> {\n        println!(\"SQL query: {:?}\", statement);\n        let sql = statement.sql.clone();\n\n        let mut ret: Vec<ProxyRow> = vec![];\n        async_std::task::block_on(async {\n            for payload in self.mem.lock().unwrap().execute(sql).await.unwrap().iter() {\n                match payload {\n                    gluesql::prelude::Payload::Select { labels, rows } => {\n                        for row in rows.iter() {\n                            let mut map = BTreeMap::new();\n                            for (label, column) in labels.iter().zip(row.iter()) {\n                                map.insert(\n                                    label.to_owned(),\n                                    match column {\n                                        gluesql::prelude::Value::I64(val) => {\n                                            sea_orm::Value::BigInt(Some(*val))\n                                        }\n                                        gluesql::prelude::Value::Str(val) => {\n                                            sea_orm::Value::String(Some(val.to_owned()))\n                                        }\n                                        _ => unreachable!(\"Unsupported value: {:?}\", column),\n                                    },\n                                );\n                            }\n                            ret.push(map.into());\n                        }\n                    }\n                    _ => unreachable!(\"Unsupported payload: {:?}\", payload),\n                }\n            }\n        });\n\n        Ok(ret)\n    }\n\n    async fn execute(&self, statement: Statement) -> Result<ProxyExecResult, DbErr> {\n        let sql = if let Some(values) = statement.values {\n            // Replace all the '?' with the statement values\n            use sqlparser::ast::{Expr, Value};\n            use sqlparser::dialect::GenericDialect;\n            use sqlparser::parser::Parser;\n\n            let dialect = GenericDialect {};\n            let mut ast = Parser::parse_sql(&dialect, statement.sql.as_str()).unwrap();\n            match &mut ast[0] {\n                sqlparser::ast::Statement::Insert {\n                    columns, source, ..\n                } => {\n                    for item in columns.iter_mut() {\n                        item.quote_style = Some('\"');\n                    }\n\n                    if let Some(obj) = source {\n                        match &mut *obj.body {\n                            sqlparser::ast::SetExpr::Values(obj) => {\n                                for (mut item, val) in obj.rows[0].iter_mut().zip(values.0.iter()) {\n                                    match &mut item {\n                                        Expr::Value(item) => {\n                                            *item = match val {\n                                                sea_orm::Value::String(val) => {\n                                                    Value::SingleQuotedString(match val {\n                                                        Some(val) => val.to_string(),\n                                                        None => \"\".to_string(),\n                                                    })\n                                                }\n                                                sea_orm::Value::BigInt(val) => Value::Number(\n                                                    val.unwrap_or(0).to_string(),\n                                                    false,\n                                                ),\n                                                _ => todo!(),\n                                            };\n                                        }\n                                        _ => todo!(),\n                                    }\n                                }\n                            }\n                            _ => todo!(),\n                        }\n                    }\n                }\n                _ => todo!(),\n            }\n\n            let statement = &ast[0];\n            statement.to_string()\n        } else {\n            statement.sql\n        };\n\n        println!(\"SQL execute: {}\", sql);\n        async_std::task::block_on(async {\n            self.mem.lock().unwrap().execute(sql).await.unwrap();\n        });\n\n        Ok(ProxyExecResult {\n            last_insert_id: 1,\n            rows_affected: 1,\n        })\n    }\n}\n\n#[async_std::main]\nasync fn main() {\n    let mem = MemoryStorage::default();\n    let mut glue = Glue::new(mem);\n\n    glue.execute(\n        r#\"\n            CREATE TABLE IF NOT EXISTS posts (\n                id INTEGER PRIMARY KEY,\n                title TEXT NOT NULL,\n                text TEXT NOT NULL\n            )\n        \"#,\n    )\n    .await\n    .unwrap();\n\n    let db = Database::connect_proxy(\n        DbBackend::Sqlite,\n        Arc::new(Box::new(ProxyDb {\n            mem: Mutex::new(glue),\n        })),\n    )\n    .await\n    .unwrap();\n\n    println!(\"Initialized\");\n\n    let data = ActiveModel {\n        id: Set(11),\n        title: Set(\"Homo\".to_owned()),\n        text: Set(\"いいよ、来いよ\".to_owned()),\n    };\n    Entity::insert(data).exec(&db).await.unwrap();\n    let data = ActiveModel {\n        id: Set(45),\n        title: Set(\"Homo\".to_owned()),\n        text: Set(\"そうだよ\".to_owned()),\n    };\n    Entity::insert(data).exec(&db).await.unwrap();\n    let data = ActiveModel {\n        id: Set(14),\n        title: Set(\"Homo\".to_owned()),\n        text: Set(\"悔い改めて\".to_owned()),\n    };\n    Entity::insert(data).exec(&db).await.unwrap();\n\n    let list = Entity::find().all(&db).await.unwrap().to_vec();\n    println!(\"Result: {:?}\", list);\n}\n\n#[cfg(test)]\nmod tests {\n    #[smol_potat::test]\n    async fn try_run() {\n        crate::main()\n    }\n}\n"
  },
  {
    "path": "examples/quickstart/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-quickstart\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nenv_logger = { version = \"0.11\" }\nlog        = { version = \"0.4\" }\ntokio      = { version = \"1\", features = [\"full\"] }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"sqlx-sqlite\",\n    \"runtime-tokio\",\n    \"debug-print\",\n    \"entity-registry\",\n    \"schema-sync\",\n]\npath = \"../../\"\n"
  },
  {
    "path": "examples/quickstart/README.md",
    "content": "# SeaORM Quick Start\n\nThis is a single file app that strives to minimize dependency and code noise. It uses an in-memory SQLite database so there is no setup. Just do `cargo run`!"
  },
  {
    "path": "examples/quickstart/src/main.rs",
    "content": "use log::info;\n\nmod user {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"user\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n        #[sea_orm(unique)]\n        pub email: String,\n        #[sea_orm(has_one)]\n        pub profile: HasOne<super::profile::Entity>,\n        #[sea_orm(has_many)]\n        pub posts: HasMany<super::post::Entity>,\n        #[sea_orm(self_ref, via = \"user_follower\", from = \"User\", to = \"Follower\")]\n        pub followers: HasMany<Entity>,\n        #[sea_orm(self_ref, via = \"user_follower\", reverse)]\n        pub following: HasMany<Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod profile {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"profile\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub picture: String,\n        #[sea_orm(unique)]\n        pub user_id: i32,\n        #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n        pub user: HasOne<super::user::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod post {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"post\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub user_id: i32,\n        pub title: String,\n        #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n        pub author: HasOne<super::user::Entity>,\n        #[sea_orm(has_many)]\n        pub comments: HasMany<super::comment::Entity>,\n        #[sea_orm(has_many, via = \"post_tag\")]\n        pub tags: HasMany<super::tag::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod comment {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"comment\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub comment: String,\n        pub user_id: i32,\n        pub post_id: i32,\n        #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n        pub user: HasOne<super::user::Entity>,\n        #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n        pub post: HasOne<super::post::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod tag {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"tag\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub tag: String,\n        #[sea_orm(has_many, via = \"post_tag\")]\n        pub posts: HasMany<super::post::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod post_tag {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n    #[sea_orm(table_name = \"post_tag\")]\n    pub struct Model {\n        #[sea_orm(primary_key, auto_increment = false)]\n        pub post_id: i32,\n        #[sea_orm(primary_key, auto_increment = false)]\n        pub tag_id: i32,\n        #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n        pub post: Option<super::post::Entity>,\n        #[sea_orm(belongs_to, from = \"tag_id\", to = \"id\")]\n        pub tag: Option<super::tag::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod user_follower {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n    #[sea_orm(table_name = \"user_follower\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub user_id: i32,\n        #[sea_orm(primary_key)]\n        pub follower_id: i32,\n        #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n        pub user: Option<super::user::Entity>,\n        #[sea_orm(\n            belongs_to,\n            relation_enum = \"Follower\",\n            from = \"follower_id\",\n            to = \"id\"\n        )]\n        pub follower: Option<super::user::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[tokio::main]\nasync fn main() -> Result<(), sea_orm::DbErr> {\n    ///// Part 0: Setup Environment /////\n\n    // This disables sqlx's logging and enables sea-orm's logging with parameter injection,\n    // which is easier to debug.\n    let env = env_logger::Env::default().filter_or(\"RUST_LOG\", \"info,sea_orm=debug,sqlx=warn\");\n    env_logger::Builder::from_env(env).init();\n\n    use sea_orm::{entity::*, query::*};\n\n    // Use a SQLite in memory database so no setup needed.\n    // SeaORM supports MySQL, Postgres, SQL Server as well.\n    let db = &sea_orm::Database::connect(\"sqlite::memory:\").await?;\n\n    // Populate this fresh database with tables.\n    //\n    // All entities defined in this crate are automatically registered\n    // into the schema registry, regardless of which module they live in.\n    //\n    // The registry may also include entities from upstream crates,\n    // so here we restrict it to entities defined in this crate only.\n    //\n    // The order of entity definitions does not matter.\n    // SeaORM resolves foreign key dependencies automatically\n    // and creates the tables in the correct order with their keys.\n    db.get_schema_registry(\"sea_orm_quickstart::*\")\n        .sync(db)\n        .await?;\n\n    info!(\"Schema created.\");\n\n    ///// Part 1: CRUD with nested 1-1 and 1-N relations /////\n\n    info!(\"Create user Bob with a profile:\");\n    let bob = user::ActiveModel::builder()\n        .set_name(\"Bob\")\n        .set_email(\"bob@sea-ql.org\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Tennis\"))\n        .insert(db)\n        .await?;\n\n    info!(\"Find Bob by email:\");\n    assert_eq!(\n        bob,\n        // this method is generated by #[sea_orm::model] on unique keys\n        user::Entity::find_by_email(\"bob@sea-ql.org\")\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    info!(\"Query user with profile in a single query:\");\n    let mut bob = user::Entity::load()\n        .filter_by_id(bob.id)\n        .with(profile::Entity)\n        .one(db)\n        .await?\n        .expect(\"Not found\");\n    assert_eq!(bob.name, \"Bob\");\n    assert_eq!(bob.profile.as_ref().unwrap().picture, \"Tennis\");\n\n    // Here we take ownership of the nested model, modify in place and save it\n    info!(\"Update Bob's profile:\");\n    bob.profile\n        .take()\n        .unwrap()\n        .into_active_model()\n        .set_picture(\"Landscape\")\n        .save(db)\n        .await?;\n\n    info!(\"Confirmed that it's been updated:\");\n    assert_eq!(\n        profile::Entity::find_by_user_id(bob.id).all(db).await?[0].picture,\n        \"Landscape\"\n    );\n\n    // we don't have to set the `user_id` of the posts, they're automatically set to Bob\n    info!(\"Bob wrote some posts:\");\n    let mut bob = bob.into_active_model();\n    bob.posts\n        .push(\n            post::ActiveModel::builder()\n                .set_title(\"Lorem ipsum dolor sit amet, consectetur adipiscing elit\"),\n        )\n        .push(\n            post::ActiveModel::builder()\n                .set_title(\"Ut enim ad minim veniam, quis nostrud exercitation\"),\n        );\n    bob.save(db).await?;\n\n    info!(\"Find Bob's profile and his posts:\");\n    let bob = user::Entity::load()\n        .filter(user::COLUMN.name.eq(\"Bob\"))\n        .with(profile::Entity)\n        .with(post::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(bob.name, \"Bob\");\n    assert_eq!(bob.profile.as_ref().unwrap().picture, \"Landscape\");\n    assert!(bob.posts[0].title.starts_with(\"Lorem ipsum\"));\n    assert!(bob.posts[1].title.starts_with(\"Ut enim ad\"));\n\n    // It's actually fine to create user + profile the other way round.\n    // SeaORM figures out the dependency and creates the user first.\n    info!(\"Create a new user Alice:\");\n    let alice = profile::ActiveModel::builder()\n        .set_user(\n            user::ActiveModel::builder()\n                .set_name(\"Alice\")\n                .set_email(\"alice@rust-lang.org\"),\n        )\n        .set_picture(\"Park\")\n        .insert(db)\n        .await?\n        .user\n        .unwrap();\n\n    // Not only can we insert new posts via the bob active model,\n    // we can also add new comments to the posts.\n    // SeaORM walks the document tree and figures out what's changed,\n    // and perform the operation in one transaction.\n    let mut bob = bob.into_active_model();\n    info!(\"Alice commented on Bob's post:\");\n    bob.posts[0].comments.push(\n        comment::ActiveModel::builder()\n            .set_comment(\"nice post!\")\n            .set_user_id(alice.id),\n    );\n    bob.posts[1].comments.push(\n        comment::ActiveModel::builder()\n            .set_comment(\"interesting!\")\n            .set_user_id(alice.id),\n    );\n    let bob = bob.save(db).await?;\n\n    info!(\"Find all posts with author along with comments and who commented:\");\n    let posts = post::Entity::load()\n        .with(user::Entity)\n        .with((comment::Entity, user::Entity))\n        .all(db)\n        .await?;\n\n    assert!(posts[0].title.starts_with(\"Lorem ipsum\"));\n    assert_eq!(posts[0].author.as_ref().unwrap().name, \"Bob\");\n    assert_eq!(posts[0].comments.len(), 1);\n    assert_eq!(posts[0].comments[0].comment, \"nice post!\");\n    assert_eq!(posts[0].comments[0].user.as_ref().unwrap().name, \"Alice\");\n\n    assert!(posts[1].title.starts_with(\"Ut enim ad\"));\n    assert_eq!(posts[1].author.as_ref().unwrap().name, \"Bob\");\n    assert_eq!(posts[1].comments.len(), 1);\n    assert_eq!(posts[1].comments[0].comment, \"interesting!\");\n\n    // Again, we can apply multiple changes in one operation,\n    // the queries are executed inside a transaction.\n    info!(\"Update post title and comment on first post:\");\n    let mut post = posts[0].clone().into_active_model();\n    post.title = Set(\"Lorem ipsum dolor sit amet\".into()); // shorten it\n    post.comments[0].comment = Set(\"nice post! I learnt a lot\".into());\n    post.save(db).await?;\n\n    info!(\"Confirm the post and comment is updated\");\n    let post = post::Entity::load()\n        .filter_by_id(posts[0].id)\n        .with(comment::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(post.title, \"Lorem ipsum dolor sit amet\");\n    assert_eq!(post.comments[0].comment, \"nice post! I learnt a lot\");\n\n    // Comments belongs to post. They will be deleted first, otherwise the foreign key\n    // would prevent the operation.\n    info!(\"Delete the post along with all comments\");\n    post.delete(db).await?;\n\n    assert!(\n        post::Entity::find_by_id(posts[0].id)\n            .one(db)\n            .await?\n            .is_none()\n    );\n\n    ///// Part 2: managing M-N relations /////\n\n    // A unique feature of SeaORM is modelling many-to-many relations in a high level way\n\n    info!(\"Insert one tag for later use\");\n    let sunny = tag::ActiveModel::builder()\n        .set_tag(\"sunny\")\n        .save(db)\n        .await?;\n\n    info!(\"Insert a new post with 2 tags\");\n    let mut post = post::ActiveModel::builder()\n        .set_title(\"A perfect day out\")\n        .set_user_id(alice.id)\n        .add_tag(sunny.clone()) // an existing tag\n        .add_tag(tag::ActiveModel::builder().set_tag(\"foodie\")) // a new tag\n        .save(db) // new tag will be created and associcated to the new post\n        .await?;\n\n    let post_id = post.id.clone().unwrap();\n\n    {\n        info!(\"get back the post and tags\");\n        let post = post::Entity::load()\n            .filter_by_id(post_id)\n            .with(tag::Entity)\n            .one(db)\n            .await?\n            .unwrap();\n        assert_eq!(post.title, \"A perfect day out\");\n        assert_eq!(post.tags.len(), 2);\n        assert_eq!(post.tags[0].tag, \"sunny\");\n        assert_eq!(post.tags[1].tag, \"foodie\");\n    }\n\n    info!(\"Add new tag to post\");\n    post.tags\n        .push(tag::ActiveModel::builder().set_tag(\"downtown\"));\n    let mut post = post.save(db).await?;\n\n    {\n        info!(\"get back the post and tags\");\n        let post = post::Entity::load()\n            .filter_by_id(post_id)\n            .with(tag::Entity)\n            .one(db)\n            .await?\n            .unwrap();\n        assert_eq!(post.tags.len(), 3);\n        assert_eq!(post.tags[0].tag, \"sunny\");\n        assert_eq!(post.tags[1].tag, \"foodie\");\n        assert_eq!(post.tags[2].tag, \"downtown\");\n    }\n\n    info!(\"Update post title and remove a tag\");\n    let mut tags = post.tags.take();\n    tags.as_mut_vec().remove(0); // it actually rained\n    post.title = Set(\"Almost a perfect day out\".into());\n    post.tags.replace_all(tags);\n    // converting the field from append to replace would delete associations not in this list\n    let post = post.save(db).await?;\n\n    {\n        info!(\"get back the post and tags\");\n        let post = post::Entity::load()\n            .filter_by_id(post_id)\n            .with(tag::Entity)\n            .one(db)\n            .await?\n            .unwrap();\n        assert_eq!(post.tags.len(), 2);\n        assert_eq!(post.title, \"Almost a perfect day out\");\n        assert_eq!(post.tags[0].tag, \"foodie\");\n        assert_eq!(post.tags[1].tag, \"downtown\");\n    }\n\n    // only the association between post and tag is removed,\n    // but the tag itself is not deleted\n    info!(\"check that the tag sunny still exists\");\n    assert!(tag::Entity::find_by_tag(\"sunny\").one(db).await?.is_some());\n\n    info!(\"cascade delete post, remove tag associations\");\n    post.delete(db).await?;\n\n    ///// Part 3: self-referencing relations /////\n\n    info!(\"save a new user with a new profile\");\n    let sam = user::ActiveModel::builder()\n        .set_name(\"Sam\")\n        .set_email(\"sam@rustacean.net\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Crab.jpg\"))\n        .save(db)\n        .await?;\n\n    // we can do it from left to right: user <- follower\n    info!(\"Add follower to Alice\");\n    let alice = alice.into_active_model().add_follower(bob).save(db).await?;\n\n    // we can also do it in reverse: user -> following\n    info!(\"Sam starts following Alice\");\n    sam.add_following(alice).save(db).await?;\n\n    info!(\"Query Alice's profile and followers\");\n    let alice = user::Entity::load()\n        .filter_by_email(\"alice@rust-lang.org\")\n        .with(profile::Entity)\n        .with(user_follower::Entity)\n        .with(user_follower::Entity::REVERSE)\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(alice.name, \"Alice\");\n    assert_eq!(alice.profile.as_ref().unwrap().picture, \"Park\");\n    assert_eq!(alice.followers.len(), 2);\n    assert_eq!(alice.followers[0].name, \"Bob\");\n    assert_eq!(alice.followers[1].name, \"Sam\");\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/react_admin/README.md",
    "content": "# GraphQL based Admin Dashboard with Loco and Seaography\n\nIn this tutorial, we would develop a GraphQL based admin dashboard with [Seaography](https://github.com/SeaQL/seaography) and Loco.\n\nRead The full tutorial [here](https://www.sea-ql.org/blog/2024-08-08-graphql-admin-dashboard-with-loco-seaography/).\n\nRead our first and second tutorial of the series, [Getting Started with Loco & SeaORM](https://www.sea-ql.org/blog/2024-05-28-getting-started-with-loco-seaorm/), [Adding GraphQL Support to Loco with Seaography](https://www.sea-ql.org/blog/2024-07-01-graphql-support-with-loco-seaography/), if you haven't.\n\n![Screenshot List](Screenshot-List.png)\n\n![Screenshot View](Screenshot-View.png)\n"
  },
  {
    "path": "examples/react_admin/backend/.cargo/config.toml",
    "content": "[alias]\nloco       = \"run --\"\nplayground = \"run --example playground\"\n"
  },
  {
    "path": "examples/react_admin/backend/.devcontainer/Dockerfile",
    "content": "FROM mcr.microsoft.com/devcontainers/rust:1\n\nRUN apt-get update && export DEBIAN_FRONTEND=noninteractive \\\n     && apt-get -y install --no-install-recommends postgresql-client \\\n     && cargo install sea-orm-cli cargo-insta \\\n     && chown -R vscode /usr/local/cargo\n\nCOPY .env /.env\n"
  },
  {
    "path": "examples/react_admin/backend/.devcontainer/devcontainer.json",
    "content": "{\n    \"name\": \"Loco\",\n    \"dockerComposeFile\": \"docker-compose.yml\",\n    \"service\": \"app\",\n    \"workspaceFolder\": \"/workspaces/${localWorkspaceFolderBasename}\",\n    \"forwardPorts\": [\n        3000\n    ]\n}"
  },
  {
    "path": "examples/react_admin/backend/.devcontainer/docker-compose.yml",
    "content": "version: \"3\"\n\nservices:\n  app:\n    build:\n      context: .\n      dockerfile: Dockerfile\n    command: sleep infinity\n    networks:\n      - db\n      - redis\n      - mailer\n    volumes:\n      - ../..:/workspaces:cached\n    env_file:\n      - .env\n  db:\n    image: postgres:15.3-alpine\n    restart: unless-stopped\n    ports:\n      - 5432:5432\n    networks:\n      - db\n    volumes:\n      - postgres-data:/var/lib/postgresql/data\n    env_file:\n      - .env\n  redis:\n    image: redis:latest\n    restart: unless-stopped\n    ports:\n      - 6379:6379\n    networks:\n      - redis\n  mailer:\n    image: mailtutan/mailtutan:latest\n    restart: unless-stopped\n    ports:\n      - 1080:1080\n      - 1025:1025\n    networks:\n      - mailer\n\nvolumes:\n  postgres-data:\n\nnetworks:\n  db:\n  redis:\n  mailer:\n"
  },
  {
    "path": "examples/react_admin/backend/.github/workflows/ci.yaml",
    "content": "name: CI\non:\n  push:\n    branches:\n      - master\n      - main\n  pull_request:\n\nenv:\n  RUST_TOOLCHAIN: stable\n  TOOLCHAIN_PROFILE: minimal\n\njobs:\n  rustfmt:\n    name: Check Style\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: read\n\n    steps:\n      - name: Checkout the code\n        uses: actions/checkout@v4\n      - uses: actions-rs/toolchain@v1\n        with:\n          profile: ${{ env.TOOLCHAIN_PROFILE }}\n          toolchain: ${{ env.RUST_TOOLCHAIN }}\n          override: true\n          components: rustfmt\n      - name: Run cargo fmt\n        uses: actions-rs/cargo@v1\n        with:\n          command: fmt\n          args: --all -- --check\n\n  clippy:\n    name: Run Clippy\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: read\n\n    steps:\n      - name: Checkout the code\n        uses: actions/checkout@v4\n      - uses: actions-rs/toolchain@v1\n        with:\n          profile: ${{ env.TOOLCHAIN_PROFILE }}\n          toolchain: ${{ env.RUST_TOOLCHAIN }}\n          override: true\n      - name: Setup Rust cache\n        uses: Swatinem/rust-cache@v2\n      - name: Run cargo clippy\n        uses: actions-rs/cargo@v1\n        with:\n          command: clippy\n          args: --all-features -- -D warnings -W clippy::pedantic -W clippy::nursery -W rust-2018-idioms\n\n  test:\n    name: Run Tests\n    runs-on: ubuntu-latest\n\n    permissions:\n      contents: read\n\n    services:\n      redis:\n        image: redis\n        options: >-\n          --health-cmd \"redis-cli ping\"\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n        ports:\n          - \"6379:6379\"\n      postgres:\n        image: postgres\n        env:\n          POSTGRES_DB: postgres_test\n          POSTGRES_USER: postgres\n          POSTGRES_PASSWORD: postgres\n        ports:\n          - \"5432:5432\"\n        # Set health checks to wait until postgres has started\n        options: --health-cmd pg_isready\n          --health-interval 10s\n          --health-timeout 5s\n          --health-retries 5\n\n    steps:\n      - name: Checkout the code\n        uses: actions/checkout@v4\n      - uses: actions-rs/toolchain@v1\n        with:\n          profile: ${{ env.TOOLCHAIN_PROFILE }}\n          toolchain: ${{ env.RUST_TOOLCHAIN }}\n          override: true\n      - name: Setup Rust cache\n        uses: Swatinem/rust-cache@v2\n      - name: Run cargo test\n        uses: actions-rs/cargo@v1\n        with:\n          command: test\n          args: --all-features --all\n        env:\n          REDIS_URL: redis://localhost:${{job.services.redis.ports[6379]}}\n          DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres_test\n"
  },
  {
    "path": "examples/react_admin/backend/.gitignore",
    "content": "**/config/local.yaml\n**/config/*.local.yaml\n**/config/production.yaml\n\n# Generated by Cargo\n# will have compiled files and executables\ndebug/\ntarget/\n\n# include cargo lock\n!Cargo.lock\n\n# These are backup files generated by rustfmt\n**/*.rs.bk\n\n# MSVC Windows builds of rustc generate these, which store debugging information\n*.pdb\n\nuploads\n"
  },
  {
    "path": "examples/react_admin/backend/.rustfmt.toml",
    "content": "comment_width        = 80\nformat_strings       = true\ngroup_imports        = \"StdExternalCrate\"\nimports_granularity  = \"Crate\"\nmax_width            = 100\nuse_small_heuristics = \"Default\"\nwrap_comments        = true\n"
  },
  {
    "path": "examples/react_admin/backend/Cargo.lock",
    "content": "# This file is automatically @generated by Cargo.\n# It is not intended for manual editing.\nversion = 4\n\n[[package]]\nname = \"Inflector\"\nversion = \"0.11.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3\"\ndependencies = [\n \"lazy_static\",\n \"regex\",\n]\n\n[[package]]\nname = \"addr2line\"\nversion = \"0.24.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1\"\ndependencies = [\n \"gimli\",\n]\n\n[[package]]\nname = \"adler2\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627\"\n\n[[package]]\nname = \"ahash\"\nversion = \"0.7.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9\"\ndependencies = [\n \"getrandom 0.2.15\",\n \"once_cell\",\n \"version_check\",\n]\n\n[[package]]\nname = \"ahash\"\nversion = \"0.8.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011\"\ndependencies = [\n \"cfg-if\",\n \"getrandom 0.2.15\",\n \"once_cell\",\n \"version_check\",\n \"zerocopy 0.7.35\",\n]\n\n[[package]]\nname = \"aho-corasick\"\nversion = \"1.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"aliasable\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd\"\n\n[[package]]\nname = \"alloc-no-stdlib\"\nversion = \"2.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3\"\n\n[[package]]\nname = \"alloc-stdlib\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece\"\ndependencies = [\n \"alloc-no-stdlib\",\n]\n\n[[package]]\nname = \"allocator-api2\"\nversion = \"0.2.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923\"\n\n[[package]]\nname = \"android-tzdata\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0\"\n\n[[package]]\nname = \"android_system_properties\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"anstream\"\nversion = \"0.6.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b\"\ndependencies = [\n \"anstyle\",\n \"anstyle-parse\",\n \"anstyle-query\",\n \"anstyle-wincon\",\n \"colorchoice\",\n \"is_terminal_polyfill\",\n \"utf8parse\",\n]\n\n[[package]]\nname = \"anstyle\"\nversion = \"1.0.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9\"\n\n[[package]]\nname = \"anstyle-parse\"\nversion = \"0.2.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9\"\ndependencies = [\n \"utf8parse\",\n]\n\n[[package]]\nname = \"anstyle-query\"\nversion = \"1.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c\"\ndependencies = [\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"anstyle-wincon\"\nversion = \"3.0.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e\"\ndependencies = [\n \"anstyle\",\n \"once_cell\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"anyhow\"\nversion = \"1.0.95\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04\"\n\n[[package]]\nname = \"argon2\"\nversion = \"0.5.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072\"\ndependencies = [\n \"base64ct\",\n \"blake2\",\n \"cpufeatures\",\n \"password-hash\",\n]\n\n[[package]]\nname = \"arrayvec\"\nversion = \"0.7.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50\"\n\n[[package]]\nname = \"ascii_utils\"\nversion = \"0.9.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a\"\n\n[[package]]\nname = \"assert-json-diff\"\nversion = \"2.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12\"\ndependencies = [\n \"serde\",\n \"serde_json\",\n]\n\n[[package]]\nname = \"async-attributes\"\nversion = \"1.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5\"\ndependencies = [\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"async-channel\"\nversion = \"1.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35\"\ndependencies = [\n \"concurrent-queue\",\n \"event-listener 2.5.3\",\n \"futures-core\",\n]\n\n[[package]]\nname = \"async-channel\"\nversion = \"2.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a\"\ndependencies = [\n \"concurrent-queue\",\n \"event-listener-strategy\",\n \"futures-core\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"async-compression\"\nversion = \"0.4.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522\"\ndependencies = [\n \"brotli\",\n \"flate2\",\n \"futures-core\",\n \"memchr\",\n \"pin-project-lite\",\n \"tokio\",\n \"zstd\",\n \"zstd-safe\",\n]\n\n[[package]]\nname = \"async-executor\"\nversion = \"1.13.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec\"\ndependencies = [\n \"async-task\",\n \"concurrent-queue\",\n \"fastrand\",\n \"futures-lite\",\n \"slab\",\n]\n\n[[package]]\nname = \"async-global-executor\"\nversion = \"2.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c\"\ndependencies = [\n \"async-channel 2.3.1\",\n \"async-executor\",\n \"async-io\",\n \"async-lock\",\n \"blocking\",\n \"futures-lite\",\n \"once_cell\",\n \"tokio\",\n]\n\n[[package]]\nname = \"async-graphql\"\nversion = \"7.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"036618f842229ba0b89652ffe425f96c7c16a49f7e3cb23b56fca7f61fd74980\"\ndependencies = [\n \"async-graphql-derive\",\n \"async-graphql-parser\",\n \"async-graphql-value\",\n \"async-stream\",\n \"async-trait\",\n \"base64 0.22.1\",\n \"bytes\",\n \"chrono\",\n \"fast_chemail\",\n \"fnv\",\n \"futures-channel\",\n \"futures-timer\",\n \"futures-util\",\n \"handlebars\",\n \"http\",\n \"indexmap\",\n \"lru\",\n \"mime\",\n \"multer\",\n \"num-traits\",\n \"pin-project-lite\",\n \"regex\",\n \"rust_decimal\",\n \"serde\",\n \"serde_json\",\n \"serde_urlencoded\",\n \"static_assertions_next\",\n \"tempfile\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"async-graphql-axum\"\nversion = \"7.0.14\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0344482a065904d2595377810e0bb35ad445ca4712b459757436303251d81b65\"\ndependencies = [\n \"async-graphql\",\n \"axum\",\n \"bytes\",\n \"futures-util\",\n \"serde_json\",\n \"tokio\",\n \"tokio-stream\",\n \"tokio-util\",\n \"tower-service\",\n]\n\n[[package]]\nname = \"async-graphql-derive\"\nversion = \"7.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fd45deb3dbe5da5cdb8d6a670a7736d735ba65b455328440f236dfb113727a3d\"\ndependencies = [\n \"Inflector\",\n \"async-graphql-parser\",\n \"darling\",\n \"proc-macro-crate\",\n \"proc-macro2\",\n \"quote\",\n \"strum 0.26.3\",\n \"syn 2.0.98\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"async-graphql-parser\"\nversion = \"7.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"60b7607e59424a35dadbc085b0d513aa54ec28160ee640cf79ec3b634eba66d3\"\ndependencies = [\n \"async-graphql-value\",\n \"pest\",\n \"serde\",\n \"serde_json\",\n]\n\n[[package]]\nname = \"async-graphql-value\"\nversion = \"7.0.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34ecdaff7c9cffa3614a9f9999bf9ee4c3078fe3ce4d6a6e161736b56febf2de\"\ndependencies = [\n \"bytes\",\n \"indexmap\",\n \"serde\",\n \"serde_json\",\n]\n\n[[package]]\nname = \"async-io\"\nversion = \"2.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059\"\ndependencies = [\n \"async-lock\",\n \"cfg-if\",\n \"concurrent-queue\",\n \"futures-io\",\n \"futures-lite\",\n \"parking\",\n \"polling\",\n \"rustix\",\n \"slab\",\n \"tracing\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"async-lock\"\nversion = \"3.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18\"\ndependencies = [\n \"event-listener 5.4.0\",\n \"event-listener-strategy\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"async-std\"\nversion = \"1.13.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615\"\ndependencies = [\n \"async-attributes\",\n \"async-channel 1.9.0\",\n \"async-global-executor\",\n \"async-io\",\n \"async-lock\",\n \"crossbeam-utils\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-io\",\n \"futures-lite\",\n \"gloo-timers\",\n \"kv-log-macro\",\n \"log\",\n \"memchr\",\n \"once_cell\",\n \"pin-project-lite\",\n \"pin-utils\",\n \"slab\",\n \"wasm-bindgen-futures\",\n]\n\n[[package]]\nname = \"async-stream\"\nversion = \"0.3.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476\"\ndependencies = [\n \"async-stream-impl\",\n \"futures-core\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"async-stream-impl\"\nversion = \"0.3.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"async-task\"\nversion = \"4.7.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de\"\n\n[[package]]\nname = \"async-trait\"\nversion = \"0.1.86\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"atoi\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528\"\ndependencies = [\n \"num-traits\",\n]\n\n[[package]]\nname = \"atomic-waker\"\nversion = \"1.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0\"\n\n[[package]]\nname = \"auto-future\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373\"\n\n[[package]]\nname = \"autocfg\"\nversion = \"1.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26\"\n\n[[package]]\nname = \"axum\"\nversion = \"0.8.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6d6fd624c75e18b3b4c6b9caf42b1afe24437daaee904069137d8bab077be8b8\"\ndependencies = [\n \"axum-core\",\n \"axum-macros\",\n \"base64 0.22.1\",\n \"bytes\",\n \"form_urlencoded\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"hyper\",\n \"hyper-util\",\n \"itoa\",\n \"matchit\",\n \"memchr\",\n \"mime\",\n \"multer\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"rustversion\",\n \"serde\",\n \"serde_json\",\n \"serde_path_to_error\",\n \"serde_urlencoded\",\n \"sha1\",\n \"sync_wrapper\",\n \"tokio\",\n \"tokio-tungstenite\",\n \"tower 0.5.2\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"axum-core\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df1362f362fd16024ae199c1970ce98f9661bf5ef94b9808fee734bc3698b733\"\ndependencies = [\n \"bytes\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"mime\",\n \"pin-project-lite\",\n \"rustversion\",\n \"sync_wrapper\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"axum-extra\"\nversion = \"0.10.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"460fc6f625a1f7705c6cf62d0d070794e94668988b1c38111baeec177c715f7b\"\ndependencies = [\n \"axum\",\n \"axum-core\",\n \"bytes\",\n \"cookie\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"mime\",\n \"pin-project-lite\",\n \"serde\",\n \"tower 0.5.2\",\n \"tower-layer\",\n \"tower-service\",\n]\n\n[[package]]\nname = \"axum-macros\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"axum-test\"\nversion = \"17.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"317c1f4ecc1e68e0ad5decb78478421055c963ce215e736ed97463fa609cd196\"\ndependencies = [\n \"anyhow\",\n \"assert-json-diff\",\n \"auto-future\",\n \"axum\",\n \"bytes\",\n \"bytesize\",\n \"cookie\",\n \"http\",\n \"http-body-util\",\n \"hyper\",\n \"hyper-util\",\n \"mime\",\n \"pretty_assertions\",\n \"reserve-port\",\n \"rust-multipart-rfc7578_2\",\n \"serde\",\n \"serde_json\",\n \"serde_urlencoded\",\n \"smallvec\",\n \"tokio\",\n \"tower 0.5.2\",\n \"url\",\n]\n\n[[package]]\nname = \"backon\"\nversion = \"1.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba5289ec98f68f28dd809fd601059e6aa908bb8f6108620930828283d4ee23d7\"\ndependencies = [\n \"fastrand\",\n \"gloo-timers\",\n \"tokio\",\n]\n\n[[package]]\nname = \"backtrace\"\nversion = \"0.3.74\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a\"\ndependencies = [\n \"addr2line\",\n \"cfg-if\",\n \"libc\",\n \"miniz_oxide\",\n \"object\",\n \"rustc-demangle\",\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"backtrace_printer\"\nversion = \"1.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e8d28de81c708c843640982b66573df0f0168d87e42854b563971f326745aab7\"\ndependencies = [\n \"btparse-stable\",\n \"colored 2.2.0\",\n \"regex\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"base64\"\nversion = \"0.21.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567\"\n\n[[package]]\nname = \"base64\"\nversion = \"0.22.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6\"\n\n[[package]]\nname = \"base64ct\"\nversion = \"1.6.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b\"\n\n[[package]]\nname = \"bigdecimal\"\nversion = \"0.4.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7f31f3af01c5c65a07985c804d3366560e6fa7883d640a122819b14ec327482c\"\ndependencies = [\n \"autocfg\",\n \"libm\",\n \"num-bigint\",\n \"num-integer\",\n \"num-traits\",\n \"serde\",\n]\n\n[[package]]\nname = \"bitflags\"\nversion = \"2.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"bitvec\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c\"\ndependencies = [\n \"funty\",\n \"radium\",\n \"tap\",\n \"wyz\",\n]\n\n[[package]]\nname = \"blake2\"\nversion = \"0.10.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe\"\ndependencies = [\n \"digest\",\n]\n\n[[package]]\nname = \"block-buffer\"\nversion = \"0.10.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71\"\ndependencies = [\n \"generic-array\",\n]\n\n[[package]]\nname = \"blocking\"\nversion = \"1.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea\"\ndependencies = [\n \"async-channel 2.3.1\",\n \"async-task\",\n \"futures-io\",\n \"futures-lite\",\n \"piper\",\n]\n\n[[package]]\nname = \"borsh\"\nversion = \"1.5.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5430e3be710b68d984d1391c854eb431a9d548640711faa54eecb1df93db91cc\"\ndependencies = [\n \"borsh-derive\",\n \"cfg_aliases\",\n]\n\n[[package]]\nname = \"borsh-derive\"\nversion = \"1.5.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f8b668d39970baad5356d7c83a86fee3a539e6f93bf6764c97368243e17a0487\"\ndependencies = [\n \"once_cell\",\n \"proc-macro-crate\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"brotli\"\nversion = \"7.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd\"\ndependencies = [\n \"alloc-no-stdlib\",\n \"alloc-stdlib\",\n \"brotli-decompressor\",\n]\n\n[[package]]\nname = \"brotli-decompressor\"\nversion = \"4.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"74fa05ad7d803d413eb8380983b092cbbaf9a85f151b871360e7b00cd7060b37\"\ndependencies = [\n \"alloc-no-stdlib\",\n \"alloc-stdlib\",\n]\n\n[[package]]\nname = \"bstr\"\nversion = \"1.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0\"\ndependencies = [\n \"memchr\",\n \"serde\",\n]\n\n[[package]]\nname = \"btparse-stable\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0d75b8252ed252f881d1dc4482ae3c3854df6ee8183c1906bac50ff358f4f89f\"\n\n[[package]]\nname = \"bumpalo\"\nversion = \"3.17.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf\"\n\n[[package]]\nname = \"byte-unit\"\nversion = \"4.0.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c\"\ndependencies = [\n \"serde\",\n \"utf8-width\",\n]\n\n[[package]]\nname = \"bytecheck\"\nversion = \"0.6.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2\"\ndependencies = [\n \"bytecheck_derive\",\n \"ptr_meta\",\n \"simdutf8\",\n]\n\n[[package]]\nname = \"bytecheck_derive\"\nversion = \"0.6.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"byteorder\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b\"\n\n[[package]]\nname = \"bytes\"\nversion = \"1.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"bytesize\"\nversion = \"1.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc\"\n\n[[package]]\nname = \"cc\"\nversion = \"1.2.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e4730490333d58093109dc02c23174c3f4d490998c3fed3cc8e82d57afedb9cf\"\ndependencies = [\n \"jobserver\",\n \"libc\",\n \"shlex\",\n]\n\n[[package]]\nname = \"cfg-if\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd\"\n\n[[package]]\nname = \"cfg_aliases\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724\"\n\n[[package]]\nname = \"chrono\"\nversion = \"0.4.39\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825\"\ndependencies = [\n \"android-tzdata\",\n \"iana-time-zone\",\n \"js-sys\",\n \"num-traits\",\n \"serde\",\n \"wasm-bindgen\",\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"chrono-tz\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb\"\ndependencies = [\n \"chrono\",\n \"chrono-tz-build\",\n \"phf\",\n]\n\n[[package]]\nname = \"chrono-tz-build\"\nversion = \"0.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1\"\ndependencies = [\n \"parse-zoneinfo\",\n \"phf\",\n \"phf_codegen\",\n]\n\n[[package]]\nname = \"chumsky\"\nversion = \"0.9.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9\"\ndependencies = [\n \"hashbrown 0.14.5\",\n \"stacker\",\n]\n\n[[package]]\nname = \"clap\"\nversion = \"4.5.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796\"\ndependencies = [\n \"clap_builder\",\n \"clap_derive\",\n]\n\n[[package]]\nname = \"clap_builder\"\nversion = \"4.5.27\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7\"\ndependencies = [\n \"anstream\",\n \"anstyle\",\n \"clap_lex\",\n \"strsim\",\n]\n\n[[package]]\nname = \"clap_derive\"\nversion = \"4.5.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c\"\ndependencies = [\n \"heck 0.5.0\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"clap_lex\"\nversion = \"0.7.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6\"\n\n[[package]]\nname = \"colorchoice\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990\"\n\n[[package]]\nname = \"colored\"\nversion = \"2.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c\"\ndependencies = [\n \"lazy_static\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"colored\"\nversion = \"3.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e\"\ndependencies = [\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"combine\"\nversion = \"4.6.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"memchr\",\n \"pin-project-lite\",\n \"tokio\",\n \"tokio-util\",\n]\n\n[[package]]\nname = \"concurrent-queue\"\nversion = \"2.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"console\"\nversion = \"0.15.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b\"\ndependencies = [\n \"encode_unicode\",\n \"libc\",\n \"once_cell\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"const-oid\"\nversion = \"0.9.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8\"\n\n[[package]]\nname = \"cookie\"\nversion = \"0.18.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747\"\ndependencies = [\n \"percent-encoding\",\n \"time\",\n \"version_check\",\n]\n\n[[package]]\nname = \"core-foundation-sys\"\nversion = \"0.8.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b\"\n\n[[package]]\nname = \"cpufeatures\"\nversion = \"0.2.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"crc\"\nversion = \"3.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636\"\ndependencies = [\n \"crc-catalog\",\n]\n\n[[package]]\nname = \"crc-catalog\"\nversion = \"2.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5\"\n\n[[package]]\nname = \"crc32fast\"\nversion = \"1.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3\"\ndependencies = [\n \"cfg-if\",\n]\n\n[[package]]\nname = \"cron\"\nversion = \"0.12.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6f8c3e73077b4b4a6ab1ea5047c37c57aee77657bc8ecd6f29b0af082d0b0c07\"\ndependencies = [\n \"chrono\",\n \"nom\",\n \"once_cell\",\n]\n\n[[package]]\nname = \"crossbeam-channel\"\nversion = \"0.5.14\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-deque\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51\"\ndependencies = [\n \"crossbeam-epoch\",\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-epoch\"\nversion = \"0.9.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-queue\"\nversion = \"0.3.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115\"\ndependencies = [\n \"crossbeam-utils\",\n]\n\n[[package]]\nname = \"crossbeam-utils\"\nversion = \"0.8.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28\"\n\n[[package]]\nname = \"cruet\"\nversion = \"0.13.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"113a9e83d8f614be76de8df1f25bf9d0ea6e85ea573710a3d3f3abe1438ae49c\"\ndependencies = [\n \"once_cell\",\n \"regex\",\n]\n\n[[package]]\nname = \"cruet\"\nversion = \"0.14.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6132609543972496bc97b1e01f1ce6586768870aeb4cabeb3385f4e05b5caead\"\ndependencies = [\n \"once_cell\",\n \"regex\",\n]\n\n[[package]]\nname = \"crypto-common\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3\"\ndependencies = [\n \"generic-array\",\n \"typenum\",\n]\n\n[[package]]\nname = \"cssparser\"\nversion = \"0.34.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b7c66d1cd8ed61bf80b38432613a7a2f09401ab8d0501110655f8b341484a3e3\"\ndependencies = [\n \"cssparser-macros\",\n \"dtoa-short\",\n \"itoa\",\n \"phf\",\n \"smallvec\",\n]\n\n[[package]]\nname = \"cssparser-macros\"\nversion = \"0.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331\"\ndependencies = [\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"darling\"\nversion = \"0.20.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989\"\ndependencies = [\n \"darling_core\",\n \"darling_macro\",\n]\n\n[[package]]\nname = \"darling_core\"\nversion = \"0.20.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5\"\ndependencies = [\n \"fnv\",\n \"ident_case\",\n \"proc-macro2\",\n \"quote\",\n \"strsim\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"darling_macro\"\nversion = \"0.20.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806\"\ndependencies = [\n \"darling_core\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"dashmap\"\nversion = \"5.5.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856\"\ndependencies = [\n \"cfg-if\",\n \"hashbrown 0.14.5\",\n \"lock_api\",\n \"once_cell\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"dashmap\"\nversion = \"6.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf\"\ndependencies = [\n \"cfg-if\",\n \"crossbeam-utils\",\n \"hashbrown 0.14.5\",\n \"lock_api\",\n \"once_cell\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"data-encoding\"\nversion = \"2.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f\"\n\n[[package]]\nname = \"der\"\nversion = \"0.7.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0\"\ndependencies = [\n \"const-oid\",\n \"pem-rfc7468\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"deranged\"\nversion = \"0.3.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4\"\ndependencies = [\n \"powerfmt\",\n \"serde\",\n]\n\n[[package]]\nname = \"derive_more\"\nversion = \"0.99.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"deunicode\"\nversion = \"1.6.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00\"\n\n[[package]]\nname = \"diff\"\nversion = \"0.1.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8\"\n\n[[package]]\nname = \"digest\"\nversion = \"0.10.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292\"\ndependencies = [\n \"block-buffer\",\n \"const-oid\",\n \"crypto-common\",\n \"subtle\",\n]\n\n[[package]]\nname = \"displaydoc\"\nversion = \"0.2.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"dotenvy\"\nversion = \"0.15.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b\"\n\n[[package]]\nname = \"dtoa\"\nversion = \"1.0.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653\"\n\n[[package]]\nname = \"dtoa-short\"\nversion = \"0.3.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87\"\ndependencies = [\n \"dtoa\",\n]\n\n[[package]]\nname = \"duct\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d7478638a31d1f1f3d6c9f5e57c76b906a04ac4879d6fd0fb6245bc88f73fd0b\"\ndependencies = [\n \"libc\",\n \"os_pipe\",\n \"shared_child\",\n \"shared_thread\",\n]\n\n[[package]]\nname = \"duct_sh\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8139179d1d133ab7153920ba3812915b17c61e2514a6f98b1fd03f2c07668d1\"\ndependencies = [\n \"duct\",\n]\n\n[[package]]\nname = \"ego-tree\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7c6ba7d4eec39eaa9ab24d44a0e73a7949a1095a8b3f3abb11eddf27dbb56a53\"\n\n[[package]]\nname = \"either\"\nversion = \"1.13.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"email-encoding\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ea3d894bbbab314476b265f9b2d46bf24b123a36dd0e96b06a1b49545b9d9dcc\"\ndependencies = [\n \"base64 0.22.1\",\n \"memchr\",\n]\n\n[[package]]\nname = \"email_address\"\nversion = \"0.2.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449\"\n\n[[package]]\nname = \"encode_unicode\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0\"\n\n[[package]]\nname = \"encoding_rs\"\nversion = \"0.8.35\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3\"\ndependencies = [\n \"cfg-if\",\n]\n\n[[package]]\nname = \"english-to-cron\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c16423ac933fee80f05a52b435a912d5b08edbbbfe936e0042ebb3accdf303da\"\ndependencies = [\n \"lazy_static\",\n \"regex\",\n]\n\n[[package]]\nname = \"equivalent\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5\"\n\n[[package]]\nname = \"errno\"\nversion = \"0.3.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"etcetera\"\nversion = \"0.8.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943\"\ndependencies = [\n \"cfg-if\",\n \"home\",\n \"windows-sys 0.48.0\",\n]\n\n[[package]]\nname = \"event-listener\"\nversion = \"2.5.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0\"\n\n[[package]]\nname = \"event-listener\"\nversion = \"5.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae\"\ndependencies = [\n \"concurrent-queue\",\n \"parking\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"event-listener-strategy\"\nversion = \"0.5.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2\"\ndependencies = [\n \"event-listener 5.4.0\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"eyre\"\nversion = \"0.6.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec\"\ndependencies = [\n \"indenter\",\n \"once_cell\",\n]\n\n[[package]]\nname = \"fast_chemail\"\nversion = \"0.9.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"495a39d30d624c2caabe6312bfead73e7717692b44e0b32df168c275a2e8e9e4\"\ndependencies = [\n \"ascii_utils\",\n]\n\n[[package]]\nname = \"fastrand\"\nversion = \"2.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be\"\n\n[[package]]\nname = \"flagset\"\nversion = \"0.4.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b3ea1ec5f8307826a5b71094dd91fc04d4ae75d5709b20ad351c7fb4815c86ec\"\n\n[[package]]\nname = \"flate2\"\nversion = \"1.0.35\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c\"\ndependencies = [\n \"crc32fast\",\n \"miniz_oxide\",\n]\n\n[[package]]\nname = \"flume\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095\"\ndependencies = [\n \"futures-core\",\n \"futures-sink\",\n \"spin\",\n]\n\n[[package]]\nname = \"fnv\"\nversion = \"1.0.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1\"\n\n[[package]]\nname = \"foldhash\"\nversion = \"0.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f\"\n\n[[package]]\nname = \"form_urlencoded\"\nversion = \"1.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456\"\ndependencies = [\n \"percent-encoding\",\n]\n\n[[package]]\nname = \"fs-err\"\nversion = \"2.11.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41\"\ndependencies = [\n \"autocfg\",\n]\n\n[[package]]\nname = \"funty\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c\"\n\n[[package]]\nname = \"futf\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843\"\ndependencies = [\n \"mac\",\n \"new_debug_unreachable\",\n]\n\n[[package]]\nname = \"futures\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"futures-executor\",\n \"futures-io\",\n \"futures-sink\",\n \"futures-task\",\n \"futures-util\",\n]\n\n[[package]]\nname = \"futures-channel\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10\"\ndependencies = [\n \"futures-core\",\n \"futures-sink\",\n]\n\n[[package]]\nname = \"futures-core\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e\"\n\n[[package]]\nname = \"futures-executor\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f\"\ndependencies = [\n \"futures-core\",\n \"futures-task\",\n \"futures-util\",\n]\n\n[[package]]\nname = \"futures-intrusive\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f\"\ndependencies = [\n \"futures-core\",\n \"lock_api\",\n \"parking_lot\",\n]\n\n[[package]]\nname = \"futures-io\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6\"\n\n[[package]]\nname = \"futures-lite\"\nversion = \"2.6.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532\"\ndependencies = [\n \"fastrand\",\n \"futures-core\",\n \"futures-io\",\n \"parking\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"futures-macro\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"futures-sink\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7\"\n\n[[package]]\nname = \"futures-task\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988\"\n\n[[package]]\nname = \"futures-timer\"\nversion = \"3.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24\"\n\n[[package]]\nname = \"futures-util\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"futures-io\",\n \"futures-macro\",\n \"futures-sink\",\n \"futures-task\",\n \"memchr\",\n \"pin-project-lite\",\n \"pin-utils\",\n \"slab\",\n]\n\n[[package]]\nname = \"fxhash\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c\"\ndependencies = [\n \"byteorder\",\n]\n\n[[package]]\nname = \"generator\"\nversion = \"0.8.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"log\",\n \"rustversion\",\n \"windows 0.58.0\",\n]\n\n[[package]]\nname = \"generic-array\"\nversion = \"0.14.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a\"\ndependencies = [\n \"typenum\",\n \"version_check\",\n]\n\n[[package]]\nname = \"getopts\"\nversion = \"0.2.21\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5\"\ndependencies = [\n \"unicode-width\",\n]\n\n[[package]]\nname = \"getrandom\"\nversion = \"0.2.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7\"\ndependencies = [\n \"cfg-if\",\n \"js-sys\",\n \"libc\",\n \"wasi 0.11.0+wasi-snapshot-preview1\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"getrandom\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"wasi 0.13.3+wasi-0.2.2\",\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"gimli\"\nversion = \"0.31.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f\"\n\n[[package]]\nname = \"glob\"\nversion = \"0.3.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2\"\n\n[[package]]\nname = \"globset\"\nversion = \"0.4.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19\"\ndependencies = [\n \"aho-corasick\",\n \"bstr\",\n \"log\",\n \"regex-automata 0.4.9\",\n \"regex-syntax 0.8.5\",\n]\n\n[[package]]\nname = \"globwalk\"\nversion = \"0.9.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757\"\ndependencies = [\n \"bitflags\",\n \"ignore\",\n \"walkdir\",\n]\n\n[[package]]\nname = \"gloo-timers\"\nversion = \"0.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994\"\ndependencies = [\n \"futures-channel\",\n \"futures-core\",\n \"js-sys\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"handlebars\"\nversion = \"5.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b\"\ndependencies = [\n \"log\",\n \"pest\",\n \"pest_derive\",\n \"serde\",\n \"serde_json\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.12.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888\"\ndependencies = [\n \"ahash 0.7.8\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.14.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1\"\ndependencies = [\n \"ahash 0.8.11\",\n \"allocator-api2\",\n]\n\n[[package]]\nname = \"hashbrown\"\nversion = \"0.15.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289\"\ndependencies = [\n \"allocator-api2\",\n \"equivalent\",\n \"foldhash\",\n]\n\n[[package]]\nname = \"hashlink\"\nversion = \"0.10.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1\"\ndependencies = [\n \"hashbrown 0.15.2\",\n]\n\n[[package]]\nname = \"heck\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8\"\n\n[[package]]\nname = \"heck\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea\"\n\n[[package]]\nname = \"hermit-abi\"\nversion = \"0.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc\"\n\n[[package]]\nname = \"hex\"\nversion = \"0.4.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70\"\n\n[[package]]\nname = \"hkdf\"\nversion = \"0.12.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7\"\ndependencies = [\n \"hmac\",\n]\n\n[[package]]\nname = \"hmac\"\nversion = \"0.12.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e\"\ndependencies = [\n \"digest\",\n]\n\n[[package]]\nname = \"home\"\nversion = \"0.5.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf\"\ndependencies = [\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"hostname\"\nversion = \"0.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"windows 0.52.0\",\n]\n\n[[package]]\nname = \"html5ever\"\nversion = \"0.29.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2e15626aaf9c351bc696217cbe29cb9b5e86c43f8a46b5e2f5c6c5cf7cb904ce\"\ndependencies = [\n \"log\",\n \"mac\",\n \"markup5ever\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"http\"\nversion = \"1.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea\"\ndependencies = [\n \"bytes\",\n \"fnv\",\n \"itoa\",\n]\n\n[[package]]\nname = \"http-body\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184\"\ndependencies = [\n \"bytes\",\n \"http\",\n]\n\n[[package]]\nname = \"http-body-util\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f\"\ndependencies = [\n \"bytes\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"pin-project-lite\",\n]\n\n[[package]]\nname = \"http-range-header\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c\"\n\n[[package]]\nname = \"httparse\"\nversion = \"1.10.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a\"\n\n[[package]]\nname = \"httpdate\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9\"\n\n[[package]]\nname = \"humansize\"\nversion = \"2.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7\"\ndependencies = [\n \"libm\",\n]\n\n[[package]]\nname = \"hyper\"\nversion = \"1.6.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80\"\ndependencies = [\n \"bytes\",\n \"futures-channel\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"httparse\",\n \"httpdate\",\n \"itoa\",\n \"pin-project-lite\",\n \"smallvec\",\n \"tokio\",\n \"want\",\n]\n\n[[package]]\nname = \"hyper-util\"\nversion = \"0.1.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4\"\ndependencies = [\n \"bytes\",\n \"futures-channel\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"hyper\",\n \"pin-project-lite\",\n \"socket2 0.5.8\",\n \"tokio\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"iana-time-zone\"\nversion = \"0.1.61\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220\"\ndependencies = [\n \"android_system_properties\",\n \"core-foundation-sys\",\n \"iana-time-zone-haiku\",\n \"js-sys\",\n \"wasm-bindgen\",\n \"windows-core 0.52.0\",\n]\n\n[[package]]\nname = \"iana-time-zone-haiku\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f\"\ndependencies = [\n \"cc\",\n]\n\n[[package]]\nname = \"icu_collections\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526\"\ndependencies = [\n \"displaydoc\",\n \"yoke\",\n \"zerofrom\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_locid\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637\"\ndependencies = [\n \"displaydoc\",\n \"litemap\",\n \"tinystr\",\n \"writeable\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_locid_transform\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e\"\ndependencies = [\n \"displaydoc\",\n \"icu_locid\",\n \"icu_locid_transform_data\",\n \"icu_provider\",\n \"tinystr\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_locid_transform_data\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e\"\n\n[[package]]\nname = \"icu_normalizer\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f\"\ndependencies = [\n \"displaydoc\",\n \"icu_collections\",\n \"icu_normalizer_data\",\n \"icu_properties\",\n \"icu_provider\",\n \"smallvec\",\n \"utf16_iter\",\n \"utf8_iter\",\n \"write16\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_normalizer_data\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516\"\n\n[[package]]\nname = \"icu_properties\"\nversion = \"1.5.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5\"\ndependencies = [\n \"displaydoc\",\n \"icu_collections\",\n \"icu_locid_transform\",\n \"icu_properties_data\",\n \"icu_provider\",\n \"tinystr\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_properties_data\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569\"\n\n[[package]]\nname = \"icu_provider\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9\"\ndependencies = [\n \"displaydoc\",\n \"icu_locid\",\n \"icu_provider_macros\",\n \"stable_deref_trait\",\n \"tinystr\",\n \"writeable\",\n \"yoke\",\n \"zerofrom\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"icu_provider_macros\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"ident_case\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39\"\n\n[[package]]\nname = \"idna\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e\"\ndependencies = [\n \"idna_adapter\",\n \"smallvec\",\n \"utf8_iter\",\n]\n\n[[package]]\nname = \"idna_adapter\"\nversion = \"1.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71\"\ndependencies = [\n \"icu_normalizer\",\n \"icu_properties\",\n]\n\n[[package]]\nname = \"ignore\"\nversion = \"0.4.23\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b\"\ndependencies = [\n \"crossbeam-deque\",\n \"globset\",\n \"log\",\n \"memchr\",\n \"regex-automata 0.4.9\",\n \"same-file\",\n \"walkdir\",\n \"winapi-util\",\n]\n\n[[package]]\nname = \"include_dir\"\nversion = \"0.7.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd\"\ndependencies = [\n \"include_dir_macros\",\n]\n\n[[package]]\nname = \"include_dir_macros\"\nversion = \"0.7.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n]\n\n[[package]]\nname = \"indenter\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683\"\n\n[[package]]\nname = \"indexmap\"\nversion = \"2.7.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652\"\ndependencies = [\n \"equivalent\",\n \"hashbrown 0.15.2\",\n \"serde\",\n]\n\n[[package]]\nname = \"inherent\"\nversion = \"1.0.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"insta\"\nversion = \"1.42.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"71c1b125e30d93896b365e156c33dadfffab45ee8400afcbba4752f59de08a86\"\ndependencies = [\n \"console\",\n \"linked-hash-map\",\n \"once_cell\",\n \"pest\",\n \"pest_derive\",\n \"pin-project\",\n \"regex\",\n \"serde\",\n \"similar\",\n]\n\n[[package]]\nname = \"io-uring\"\nversion = \"0.7.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4\"\ndependencies = [\n \"bitflags\",\n \"cfg-if\",\n \"libc\",\n]\n\n[[package]]\nname = \"ipnet\"\nversion = \"2.11.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130\"\n\n[[package]]\nname = \"ipnetwork\"\nversion = \"0.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"is_terminal_polyfill\"\nversion = \"1.70.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf\"\n\n[[package]]\nname = \"itertools\"\nversion = \"0.12.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569\"\ndependencies = [\n \"either\",\n]\n\n[[package]]\nname = \"itoa\"\nversion = \"1.0.14\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674\"\n\n[[package]]\nname = \"jobserver\"\nversion = \"0.1.32\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"js-sys\"\nversion = \"0.3.77\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f\"\ndependencies = [\n \"once_cell\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"jsonwebtoken\"\nversion = \"9.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f\"\ndependencies = [\n \"base64 0.21.7\",\n \"js-sys\",\n \"pem\",\n \"ring\",\n \"serde\",\n \"serde_json\",\n \"simple_asn1\",\n]\n\n[[package]]\nname = \"kv-log-macro\"\nversion = \"1.0.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f\"\ndependencies = [\n \"log\",\n]\n\n[[package]]\nname = \"lazy_static\"\nversion = \"1.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe\"\ndependencies = [\n \"spin\",\n]\n\n[[package]]\nname = \"lettre\"\nversion = \"0.11.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e882e1489810a45919477602194312b1a7df0e5acc30a6188be7b520268f63f8\"\ndependencies = [\n \"async-trait\",\n \"base64 0.22.1\",\n \"chumsky\",\n \"email-encoding\",\n \"email_address\",\n \"fastrand\",\n \"futures-io\",\n \"futures-util\",\n \"hostname\",\n \"httpdate\",\n \"idna\",\n \"mime\",\n \"nom\",\n \"percent-encoding\",\n \"quoted_printable\",\n \"rustls\",\n \"rustls-pemfile\",\n \"rustls-pki-types\",\n \"socket2 0.5.8\",\n \"tokio\",\n \"tokio-rustls\",\n \"url\",\n \"webpki-roots\",\n]\n\n[[package]]\nname = \"libc\"\nversion = \"0.2.174\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776\"\n\n[[package]]\nname = \"libm\"\nversion = \"0.2.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa\"\n\n[[package]]\nname = \"libsqlite3-sys\"\nversion = \"0.30.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149\"\ndependencies = [\n \"cc\",\n \"pkg-config\",\n \"vcpkg\",\n]\n\n[[package]]\nname = \"linked-hash-map\"\nversion = \"0.5.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f\"\n\n[[package]]\nname = \"linux-raw-sys\"\nversion = \"0.4.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab\"\n\n[[package]]\nname = \"litemap\"\nversion = \"0.7.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104\"\n\n[[package]]\nname = \"lock_api\"\nversion = \"0.4.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17\"\ndependencies = [\n \"autocfg\",\n \"scopeguard\",\n]\n\n[[package]]\nname = \"loco-gen\"\nversion = \"0.16.1\"\nsource = \"git+https://github.com/SeaQL/loco?branch=master#a5637bc645c5290597335b8f5032525ef9c727c7\"\ndependencies = [\n \"chrono\",\n \"clap\",\n \"colored 3.0.0\",\n \"cruet 0.14.0\",\n \"duct\",\n \"heck 0.4.1\",\n \"include_dir\",\n \"regex\",\n \"rrgen\",\n \"serde\",\n \"serde_json\",\n \"tera\",\n \"thiserror 1.0.69\",\n \"tracing\",\n]\n\n[[package]]\nname = \"loco-rs\"\nversion = \"0.16.1\"\nsource = \"git+https://github.com/SeaQL/loco?branch=master#a5637bc645c5290597335b8f5032525ef9c727c7\"\ndependencies = [\n \"argon2\",\n \"async-trait\",\n \"axum\",\n \"axum-extra\",\n \"axum-test\",\n \"backtrace_printer\",\n \"byte-unit\",\n \"bytes\",\n \"chrono\",\n \"clap\",\n \"colored 3.0.0\",\n \"cruet 0.13.3\",\n \"dashmap 6.1.0\",\n \"duct\",\n \"duct_sh\",\n \"english-to-cron\",\n \"futures-util\",\n \"heck 0.4.1\",\n \"include_dir\",\n \"ipnetwork\",\n \"jsonwebtoken\",\n \"lettre\",\n \"loco-gen\",\n \"moka\",\n \"opendal\",\n \"rand 0.9.2\",\n \"redis\",\n \"regex\",\n \"scraper\",\n \"sea-orm\",\n \"sea-orm-migration\",\n \"semver\",\n \"serde\",\n \"serde_json\",\n \"serde_variant\",\n \"serde_yaml\",\n \"sqlx\",\n \"tera\",\n \"thiserror 1.0.69\",\n \"tokio\",\n \"tokio-cron-scheduler\",\n \"tokio-util\",\n \"toml\",\n \"tower 0.4.13\",\n \"tower-http\",\n \"tracing\",\n \"tracing-appender\",\n \"tracing-subscriber\",\n \"tree-fs\",\n \"ulid\",\n \"uuid\",\n \"validator\",\n]\n\n[[package]]\nname = \"loco_seaography\"\nversion = \"0.1.0\"\ndependencies = [\n \"async-graphql\",\n \"async-graphql-axum\",\n \"async-trait\",\n \"axum\",\n \"chrono\",\n \"eyre\",\n \"include_dir\",\n \"insta\",\n \"lazy_static\",\n \"loco-rs\",\n \"migration\",\n \"rstest\",\n \"sea-orm\",\n \"seaography\",\n \"serde\",\n \"serde_json\",\n \"serial_test\",\n \"tokio\",\n \"tokio-util\",\n \"tower-service\",\n \"tracing\",\n \"tracing-subscriber\",\n \"uuid\",\n \"validator\",\n]\n\n[[package]]\nname = \"log\"\nversion = \"0.4.25\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f\"\ndependencies = [\n \"value-bag\",\n]\n\n[[package]]\nname = \"loom\"\nversion = \"0.7.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca\"\ndependencies = [\n \"cfg-if\",\n \"generator\",\n \"scoped-tls\",\n \"tracing\",\n \"tracing-subscriber\",\n]\n\n[[package]]\nname = \"lru\"\nversion = \"0.12.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38\"\ndependencies = [\n \"hashbrown 0.15.2\",\n]\n\n[[package]]\nname = \"mac\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4\"\n\n[[package]]\nname = \"markup5ever\"\nversion = \"0.14.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"82c88c6129bd24319e62a0359cb6b958fa7e8be6e19bb1663bc396b90883aca5\"\ndependencies = [\n \"log\",\n \"phf\",\n \"phf_codegen\",\n \"string_cache\",\n \"string_cache_codegen\",\n \"tendril\",\n]\n\n[[package]]\nname = \"matchers\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558\"\ndependencies = [\n \"regex-automata 0.1.10\",\n]\n\n[[package]]\nname = \"matchit\"\nversion = \"0.8.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3\"\n\n[[package]]\nname = \"md-5\"\nversion = \"0.10.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf\"\ndependencies = [\n \"cfg-if\",\n \"digest\",\n]\n\n[[package]]\nname = \"memchr\"\nversion = \"2.7.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3\"\n\n[[package]]\nname = \"migration\"\nversion = \"0.1.0\"\ndependencies = [\n \"async-std\",\n \"loco-rs\",\n \"sea-orm-migration\",\n]\n\n[[package]]\nname = \"mime\"\nversion = \"0.3.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a\"\n\n[[package]]\nname = \"mime_guess\"\nversion = \"2.0.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e\"\ndependencies = [\n \"mime\",\n \"unicase\",\n]\n\n[[package]]\nname = \"minimal-lexical\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a\"\n\n[[package]]\nname = \"miniz_oxide\"\nversion = \"0.8.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924\"\ndependencies = [\n \"adler2\",\n]\n\n[[package]]\nname = \"mio\"\nversion = \"1.0.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd\"\ndependencies = [\n \"libc\",\n \"wasi 0.11.0+wasi-snapshot-preview1\",\n \"windows-sys 0.52.0\",\n]\n\n[[package]]\nname = \"moka\"\nversion = \"0.12.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926\"\ndependencies = [\n \"crossbeam-channel\",\n \"crossbeam-epoch\",\n \"crossbeam-utils\",\n \"loom\",\n \"parking_lot\",\n \"portable-atomic\",\n \"rustc_version\",\n \"smallvec\",\n \"tagptr\",\n \"thiserror 1.0.69\",\n \"uuid\",\n]\n\n[[package]]\nname = \"multer\"\nversion = \"3.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b\"\ndependencies = [\n \"bytes\",\n \"encoding_rs\",\n \"futures-util\",\n \"http\",\n \"httparse\",\n \"memchr\",\n \"mime\",\n \"spin\",\n \"version_check\",\n]\n\n[[package]]\nname = \"new_debug_unreachable\"\nversion = \"1.0.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086\"\n\n[[package]]\nname = \"nom\"\nversion = \"7.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a\"\ndependencies = [\n \"memchr\",\n \"minimal-lexical\",\n]\n\n[[package]]\nname = \"nu-ansi-term\"\nversion = \"0.46.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84\"\ndependencies = [\n \"overload\",\n \"winapi\",\n]\n\n[[package]]\nname = \"num-bigint\"\nversion = \"0.4.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9\"\ndependencies = [\n \"num-integer\",\n \"num-traits\",\n]\n\n[[package]]\nname = \"num-bigint-dig\"\nversion = \"0.8.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151\"\ndependencies = [\n \"byteorder\",\n \"lazy_static\",\n \"libm\",\n \"num-integer\",\n \"num-iter\",\n \"num-traits\",\n \"rand 0.8.5\",\n \"smallvec\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"num-conv\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9\"\n\n[[package]]\nname = \"num-derive\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"num-integer\"\nversion = \"0.1.46\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f\"\ndependencies = [\n \"num-traits\",\n]\n\n[[package]]\nname = \"num-iter\"\nversion = \"0.1.45\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf\"\ndependencies = [\n \"autocfg\",\n \"num-integer\",\n \"num-traits\",\n]\n\n[[package]]\nname = \"num-traits\"\nversion = \"0.2.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841\"\ndependencies = [\n \"autocfg\",\n \"libm\",\n]\n\n[[package]]\nname = \"object\"\nversion = \"0.36.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"once_cell\"\nversion = \"1.20.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775\"\n\n[[package]]\nname = \"opendal\"\nversion = \"0.50.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cb28bb6c64e116ceaf8dd4e87099d3cfea4a58e85e62b104fef74c91afba0f44\"\ndependencies = [\n \"anyhow\",\n \"async-trait\",\n \"backon\",\n \"base64 0.22.1\",\n \"bytes\",\n \"chrono\",\n \"flagset\",\n \"futures\",\n \"getrandom 0.2.15\",\n \"http\",\n \"log\",\n \"md-5\",\n \"once_cell\",\n \"percent-encoding\",\n \"quick-xml\",\n \"reqwest\",\n \"serde\",\n \"serde_json\",\n \"tokio\",\n \"uuid\",\n]\n\n[[package]]\nname = \"ordered-float\"\nversion = \"4.6.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951\"\ndependencies = [\n \"num-traits\",\n]\n\n[[package]]\nname = \"os_pipe\"\nversion = \"1.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"db335f4760b14ead6290116f2427bf33a14d4f0617d49f78a246de10c1831224\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"ouroboros\"\nversion = \"0.18.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59\"\ndependencies = [\n \"aliasable\",\n \"ouroboros_macro\",\n \"static_assertions\",\n]\n\n[[package]]\nname = \"ouroboros_macro\"\nversion = \"0.18.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0\"\ndependencies = [\n \"heck 0.4.1\",\n \"proc-macro2\",\n \"proc-macro2-diagnostics\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"overload\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39\"\n\n[[package]]\nname = \"parking\"\nversion = \"2.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba\"\n\n[[package]]\nname = \"parking_lot\"\nversion = \"0.12.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27\"\ndependencies = [\n \"lock_api\",\n \"parking_lot_core\",\n]\n\n[[package]]\nname = \"parking_lot_core\"\nversion = \"0.9.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8\"\ndependencies = [\n \"cfg-if\",\n \"libc\",\n \"redox_syscall\",\n \"smallvec\",\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"parse-zoneinfo\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24\"\ndependencies = [\n \"regex\",\n]\n\n[[package]]\nname = \"password-hash\"\nversion = \"0.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166\"\ndependencies = [\n \"base64ct\",\n \"rand_core 0.6.4\",\n \"subtle\",\n]\n\n[[package]]\nname = \"pem\"\nversion = \"3.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae\"\ndependencies = [\n \"base64 0.22.1\",\n \"serde\",\n]\n\n[[package]]\nname = \"pem-rfc7468\"\nversion = \"0.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412\"\ndependencies = [\n \"base64ct\",\n]\n\n[[package]]\nname = \"percent-encoding\"\nversion = \"2.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e\"\n\n[[package]]\nname = \"pest\"\nversion = \"2.7.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc\"\ndependencies = [\n \"memchr\",\n \"thiserror 2.0.11\",\n \"ucd-trie\",\n]\n\n[[package]]\nname = \"pest_derive\"\nversion = \"2.7.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e\"\ndependencies = [\n \"pest\",\n \"pest_generator\",\n]\n\n[[package]]\nname = \"pest_generator\"\nversion = \"2.7.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b\"\ndependencies = [\n \"pest\",\n \"pest_meta\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"pest_meta\"\nversion = \"2.7.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea\"\ndependencies = [\n \"once_cell\",\n \"pest\",\n \"sha2\",\n]\n\n[[package]]\nname = \"pgvector\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fc58e2d255979a31caa7cabfa7aac654af0354220719ab7a68520ae7a91e8c0b\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"phf\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078\"\ndependencies = [\n \"phf_macros\",\n \"phf_shared\",\n]\n\n[[package]]\nname = \"phf_codegen\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a\"\ndependencies = [\n \"phf_generator\",\n \"phf_shared\",\n]\n\n[[package]]\nname = \"phf_generator\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d\"\ndependencies = [\n \"phf_shared\",\n \"rand 0.8.5\",\n]\n\n[[package]]\nname = \"phf_macros\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216\"\ndependencies = [\n \"phf_generator\",\n \"phf_shared\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"phf_shared\"\nversion = \"0.11.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5\"\ndependencies = [\n \"siphasher\",\n]\n\n[[package]]\nname = \"pin-project\"\nversion = \"1.1.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916\"\ndependencies = [\n \"pin-project-internal\",\n]\n\n[[package]]\nname = \"pin-project-internal\"\nversion = \"1.1.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"pin-project-lite\"\nversion = \"0.2.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b\"\n\n[[package]]\nname = \"pin-utils\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184\"\n\n[[package]]\nname = \"piper\"\nversion = \"0.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066\"\ndependencies = [\n \"atomic-waker\",\n \"fastrand\",\n \"futures-io\",\n]\n\n[[package]]\nname = \"pkcs1\"\nversion = \"0.7.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f\"\ndependencies = [\n \"der\",\n \"pkcs8\",\n \"spki\",\n]\n\n[[package]]\nname = \"pkcs8\"\nversion = \"0.10.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7\"\ndependencies = [\n \"der\",\n \"spki\",\n]\n\n[[package]]\nname = \"pkg-config\"\nversion = \"0.3.31\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2\"\n\n[[package]]\nname = \"polling\"\nversion = \"3.7.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f\"\ndependencies = [\n \"cfg-if\",\n \"concurrent-queue\",\n \"hermit-abi\",\n \"pin-project-lite\",\n \"rustix\",\n \"tracing\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"portable-atomic\"\nversion = \"1.10.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6\"\n\n[[package]]\nname = \"powerfmt\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391\"\n\n[[package]]\nname = \"ppv-lite86\"\nversion = \"0.2.20\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04\"\ndependencies = [\n \"zerocopy 0.7.35\",\n]\n\n[[package]]\nname = \"precomputed-hash\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c\"\n\n[[package]]\nname = \"pretty_assertions\"\nversion = \"1.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d\"\ndependencies = [\n \"diff\",\n \"yansi\",\n]\n\n[[package]]\nname = \"proc-macro-crate\"\nversion = \"3.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b\"\ndependencies = [\n \"toml_edit\",\n]\n\n[[package]]\nname = \"proc-macro-error-attr2\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n]\n\n[[package]]\nname = \"proc-macro-error2\"\nversion = \"2.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802\"\ndependencies = [\n \"proc-macro-error-attr2\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"proc-macro2\"\nversion = \"1.0.93\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99\"\ndependencies = [\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"proc-macro2-diagnostics\"\nversion = \"0.10.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n \"version_check\",\n \"yansi\",\n]\n\n[[package]]\nname = \"psm\"\nversion = \"0.1.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810\"\ndependencies = [\n \"cc\",\n]\n\n[[package]]\nname = \"ptr_meta\"\nversion = \"0.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1\"\ndependencies = [\n \"ptr_meta_derive\",\n]\n\n[[package]]\nname = \"ptr_meta_derive\"\nversion = \"0.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"quick-xml\"\nversion = \"0.36.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe\"\ndependencies = [\n \"memchr\",\n \"serde\",\n]\n\n[[package]]\nname = \"quote\"\nversion = \"1.0.38\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc\"\ndependencies = [\n \"proc-macro2\",\n]\n\n[[package]]\nname = \"quoted_printable\"\nversion = \"0.5.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"640c9bd8497b02465aeef5375144c26062e0dcd5939dfcbb0f5db76cb8c17c73\"\n\n[[package]]\nname = \"radium\"\nversion = \"0.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09\"\n\n[[package]]\nname = \"rand\"\nversion = \"0.8.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404\"\ndependencies = [\n \"libc\",\n \"rand_chacha 0.3.1\",\n \"rand_core 0.6.4\",\n]\n\n[[package]]\nname = \"rand\"\nversion = \"0.9.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1\"\ndependencies = [\n \"rand_chacha 0.9.0\",\n \"rand_core 0.9.0\",\n]\n\n[[package]]\nname = \"rand_chacha\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88\"\ndependencies = [\n \"ppv-lite86\",\n \"rand_core 0.6.4\",\n]\n\n[[package]]\nname = \"rand_chacha\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb\"\ndependencies = [\n \"ppv-lite86\",\n \"rand_core 0.9.0\",\n]\n\n[[package]]\nname = \"rand_core\"\nversion = \"0.6.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c\"\ndependencies = [\n \"getrandom 0.2.15\",\n]\n\n[[package]]\nname = \"rand_core\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff\"\ndependencies = [\n \"getrandom 0.3.1\",\n \"zerocopy 0.8.14\",\n]\n\n[[package]]\nname = \"redis\"\nversion = \"0.31.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0bc1ea653e0b2e097db3ebb5b7f678be339620b8041f66b30a308c1d45d36a7f\"\ndependencies = [\n \"bytes\",\n \"cfg-if\",\n \"combine\",\n \"futures-util\",\n \"itoa\",\n \"num-bigint\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"ryu\",\n \"sha1_smol\",\n \"socket2 0.5.8\",\n \"tokio\",\n \"tokio-util\",\n \"url\",\n]\n\n[[package]]\nname = \"redox_syscall\"\nversion = \"0.5.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834\"\ndependencies = [\n \"bitflags\",\n]\n\n[[package]]\nname = \"regex\"\nversion = \"1.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191\"\ndependencies = [\n \"aho-corasick\",\n \"memchr\",\n \"regex-automata 0.4.9\",\n \"regex-syntax 0.8.5\",\n]\n\n[[package]]\nname = \"regex-automata\"\nversion = \"0.1.10\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132\"\ndependencies = [\n \"regex-syntax 0.6.29\",\n]\n\n[[package]]\nname = \"regex-automata\"\nversion = \"0.4.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908\"\ndependencies = [\n \"aho-corasick\",\n \"memchr\",\n \"regex-syntax 0.8.5\",\n]\n\n[[package]]\nname = \"regex-syntax\"\nversion = \"0.6.29\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1\"\n\n[[package]]\nname = \"regex-syntax\"\nversion = \"0.8.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c\"\n\n[[package]]\nname = \"relative-path\"\nversion = \"1.9.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2\"\n\n[[package]]\nname = \"rend\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c\"\ndependencies = [\n \"bytecheck\",\n]\n\n[[package]]\nname = \"reqwest\"\nversion = \"0.12.12\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da\"\ndependencies = [\n \"base64 0.22.1\",\n \"bytes\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"hyper\",\n \"hyper-util\",\n \"ipnet\",\n \"js-sys\",\n \"log\",\n \"mime\",\n \"once_cell\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"serde\",\n \"serde_json\",\n \"serde_urlencoded\",\n \"sync_wrapper\",\n \"tokio\",\n \"tokio-util\",\n \"tower 0.5.2\",\n \"tower-service\",\n \"url\",\n \"wasm-bindgen\",\n \"wasm-bindgen-futures\",\n \"wasm-streams\",\n \"web-sys\",\n \"windows-registry\",\n]\n\n[[package]]\nname = \"reserve-port\"\nversion = \"2.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"359fc315ed556eb0e42ce74e76f4b1cd807b50fa6307f3de4e51f92dbe86e2d5\"\ndependencies = [\n \"lazy_static\",\n \"thiserror 2.0.11\",\n]\n\n[[package]]\nname = \"ring\"\nversion = \"0.17.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d\"\ndependencies = [\n \"cc\",\n \"cfg-if\",\n \"getrandom 0.2.15\",\n \"libc\",\n \"spin\",\n \"untrusted\",\n \"windows-sys 0.52.0\",\n]\n\n[[package]]\nname = \"rkyv\"\nversion = \"0.7.45\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b\"\ndependencies = [\n \"bitvec\",\n \"bytecheck\",\n \"bytes\",\n \"hashbrown 0.12.3\",\n \"ptr_meta\",\n \"rend\",\n \"rkyv_derive\",\n \"seahash\",\n \"tinyvec\",\n \"uuid\",\n]\n\n[[package]]\nname = \"rkyv_derive\"\nversion = \"0.7.45\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 1.0.109\",\n]\n\n[[package]]\nname = \"rrgen\"\nversion = \"0.5.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ee7a7ede035354391a37e42aa4935b3d8921f0ded896d2ce44bb1a3b6dd76bab\"\ndependencies = [\n \"cruet 0.13.3\",\n \"fs-err\",\n \"glob\",\n \"heck 0.4.1\",\n \"regex\",\n \"serde\",\n \"serde_json\",\n \"serde_regex\",\n \"serde_yaml\",\n \"tera\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"rsa\"\nversion = \"0.9.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519\"\ndependencies = [\n \"const-oid\",\n \"digest\",\n \"num-bigint-dig\",\n \"num-integer\",\n \"num-traits\",\n \"pkcs1\",\n \"pkcs8\",\n \"rand_core 0.6.4\",\n \"signature\",\n \"spki\",\n \"subtle\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"rstest\"\nversion = \"0.18.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"97eeab2f3c0a199bc4be135c36c924b6590b88c377d416494288c14f2db30199\"\ndependencies = [\n \"futures\",\n \"futures-timer\",\n \"rstest_macros\",\n \"rustc_version\",\n]\n\n[[package]]\nname = \"rstest_macros\"\nversion = \"0.18.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d428f8247852f894ee1be110b375111b586d4fa431f6c46e64ba5a0dcccbe605\"\ndependencies = [\n \"cfg-if\",\n \"glob\",\n \"proc-macro2\",\n \"quote\",\n \"regex\",\n \"relative-path\",\n \"rustc_version\",\n \"syn 2.0.98\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"rust-multipart-rfc7578_2\"\nversion = \"0.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bc4bb9e7c9abe5fa5f30c2d8f8fefb9e0080a2c1e3c2e567318d2907054b35d3\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"mime\",\n \"mime_guess\",\n \"rand 0.9.2\",\n \"thiserror 2.0.11\",\n]\n\n[[package]]\nname = \"rust_decimal\"\nversion = \"1.36.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555\"\ndependencies = [\n \"arrayvec\",\n \"borsh\",\n \"bytes\",\n \"num-traits\",\n \"rand 0.8.5\",\n \"rkyv\",\n \"serde\",\n \"serde_json\",\n]\n\n[[package]]\nname = \"rustc-demangle\"\nversion = \"0.1.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f\"\n\n[[package]]\nname = \"rustc_version\"\nversion = \"0.4.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92\"\ndependencies = [\n \"semver\",\n]\n\n[[package]]\nname = \"rustix\"\nversion = \"0.38.44\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154\"\ndependencies = [\n \"bitflags\",\n \"errno\",\n \"libc\",\n \"linux-raw-sys\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"rustls\"\nversion = \"0.23.22\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7\"\ndependencies = [\n \"log\",\n \"once_cell\",\n \"ring\",\n \"rustls-pki-types\",\n \"rustls-webpki\",\n \"subtle\",\n \"zeroize\",\n]\n\n[[package]]\nname = \"rustls-pemfile\"\nversion = \"2.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50\"\ndependencies = [\n \"rustls-pki-types\",\n]\n\n[[package]]\nname = \"rustls-pki-types\"\nversion = \"1.11.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c\"\n\n[[package]]\nname = \"rustls-webpki\"\nversion = \"0.102.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9\"\ndependencies = [\n \"ring\",\n \"rustls-pki-types\",\n \"untrusted\",\n]\n\n[[package]]\nname = \"rustversion\"\nversion = \"1.0.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4\"\n\n[[package]]\nname = \"ryu\"\nversion = \"1.0.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd\"\n\n[[package]]\nname = \"same-file\"\nversion = \"1.0.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502\"\ndependencies = [\n \"winapi-util\",\n]\n\n[[package]]\nname = \"scoped-tls\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294\"\n\n[[package]]\nname = \"scopeguard\"\nversion = \"1.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49\"\n\n[[package]]\nname = \"scraper\"\nversion = \"0.21.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b0e749d29b2064585327af5038a5a8eb73aeebad4a3472e83531a436563f7208\"\ndependencies = [\n \"ahash 0.8.11\",\n \"cssparser\",\n \"ego-tree\",\n \"getopts\",\n \"html5ever\",\n \"indexmap\",\n \"precomputed-hash\",\n \"selectors\",\n \"tendril\",\n]\n\n[[package]]\nname = \"sea-bae\"\nversion = \"0.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f694a6ab48f14bc063cfadff30ab551d3c7e46d8f81836c51989d548f44a2a25\"\ndependencies = [\n \"heck 0.4.1\",\n \"proc-macro-error2\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"sea-orm\"\nversion = \"2.0.0-rc.1\"\nsource = \"git+https://github.com/SeaQL/sea-orm?branch=master#4d29a8a841fc17fe7ad19cfadf497f90113e2bc6\"\ndependencies = [\n \"async-stream\",\n \"async-trait\",\n \"bigdecimal\",\n \"chrono\",\n \"futures-util\",\n \"log\",\n \"ouroboros\",\n \"pgvector\",\n \"rust_decimal\",\n \"sea-orm-macros\",\n \"sea-query\",\n \"sea-query-sqlx\",\n \"serde\",\n \"serde_json\",\n \"sqlx\",\n \"strum 0.27.2\",\n \"thiserror 2.0.11\",\n \"time\",\n \"tracing\",\n \"url\",\n \"uuid\",\n]\n\n[[package]]\nname = \"sea-orm-cli\"\nversion = \"2.0.0-rc.1\"\nsource = \"git+https://github.com/SeaQL/sea-orm?branch=master#4d29a8a841fc17fe7ad19cfadf497f90113e2bc6\"\ndependencies = [\n \"chrono\",\n \"clap\",\n \"dotenvy\",\n \"glob\",\n \"regex\",\n \"sea-schema\",\n \"sqlx\",\n \"tracing\",\n \"tracing-subscriber\",\n \"url\",\n]\n\n[[package]]\nname = \"sea-orm-macros\"\nversion = \"2.0.0-rc.1\"\nsource = \"git+https://github.com/SeaQL/sea-orm?branch=master#4d29a8a841fc17fe7ad19cfadf497f90113e2bc6\"\ndependencies = [\n \"heck 0.5.0\",\n \"proc-macro-crate\",\n \"proc-macro2\",\n \"quote\",\n \"sea-bae\",\n \"syn 2.0.98\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"sea-orm-migration\"\nversion = \"2.0.0-rc.1\"\nsource = \"git+https://github.com/SeaQL/sea-orm?branch=master#4d29a8a841fc17fe7ad19cfadf497f90113e2bc6\"\ndependencies = [\n \"async-trait\",\n \"clap\",\n \"dotenvy\",\n \"sea-orm\",\n \"sea-orm-cli\",\n \"sea-schema\",\n \"tracing\",\n \"tracing-subscriber\",\n]\n\n[[package]]\nname = \"sea-query\"\nversion = \"1.0.0-rc.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b2a95b5b42aa664f4ee19707b63194ba28f82165bf52468450968d530e5c462c\"\ndependencies = [\n \"bigdecimal\",\n \"chrono\",\n \"inherent\",\n \"ordered-float\",\n \"rust_decimal\",\n \"sea-query-derive\",\n \"serde_json\",\n \"time\",\n \"uuid\",\n]\n\n[[package]]\nname = \"sea-query-binder\"\nversion = \"0.8.0-rc.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"04db61539fefbddb68409949d73d51f73e62eb7306fe1d8478a867ff3be8c9dd\"\ndependencies = [\n \"sea-query\",\n \"sqlx\",\n]\n\n[[package]]\nname = \"sea-query-derive\"\nversion = \"1.0.0-rc.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4cd199905d6c50267689c4625ee390b365b4bbac2230e8f180767c6511a13d7f\"\ndependencies = [\n \"darling\",\n \"heck 0.4.1\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n \"thiserror 2.0.11\",\n]\n\n[[package]]\nname = \"sea-query-sqlx\"\nversion = \"0.8.0-rc.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed5eb19495858d8ae3663387a4f5298516c6f0171a7ca5681055450f190236b8\"\ndependencies = [\n \"bigdecimal\",\n \"chrono\",\n \"rust_decimal\",\n \"sea-query\",\n \"serde_json\",\n \"sqlx\",\n \"time\",\n \"uuid\",\n]\n\n[[package]]\nname = \"sea-schema\"\nversion = \"0.17.0-rc.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0ff014f61e9db0aeb1ce1fd7c3be630e4d3d87bc9ba37beaee8c899d14cb3ab8\"\ndependencies = [\n \"futures\",\n \"sea-query\",\n \"sea-query-binder\",\n \"sea-schema-derive\",\n \"sqlx\",\n]\n\n[[package]]\nname = \"sea-schema-derive\"\nversion = \"0.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"debdc8729c37fdbf88472f97fd470393089f997a909e535ff67c544d18cfccf0\"\ndependencies = [\n \"heck 0.4.1\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"seahash\"\nversion = \"4.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b\"\n\n[[package]]\nname = \"seaography\"\nversion = \"2.0.0-rc.1\"\nsource = \"git+https://github.com/SeaQL/seaography.git?branch=main#82c023a607fd235bfb822b2cf48a790caea618ed\"\ndependencies = [\n \"async-graphql\",\n \"fnv\",\n \"heck 0.4.1\",\n \"itertools\",\n \"lazy_static\",\n \"sea-orm\",\n \"serde_json\",\n \"thiserror 1.0.69\",\n]\n\n[[package]]\nname = \"selectors\"\nversion = \"0.26.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fd568a4c9bb598e291a08244a5c1f5a8a6650bee243b5b0f8dbb3d9cc1d87fe8\"\ndependencies = [\n \"bitflags\",\n \"cssparser\",\n \"derive_more\",\n \"fxhash\",\n \"log\",\n \"new_debug_unreachable\",\n \"phf\",\n \"phf_codegen\",\n \"precomputed-hash\",\n \"servo_arc\",\n \"smallvec\",\n]\n\n[[package]]\nname = \"semver\"\nversion = \"1.0.25\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03\"\n\n[[package]]\nname = \"serde\"\nversion = \"1.0.217\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70\"\ndependencies = [\n \"serde_derive\",\n]\n\n[[package]]\nname = \"serde_derive\"\nversion = \"1.0.217\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"serde_json\"\nversion = \"1.0.138\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949\"\ndependencies = [\n \"itoa\",\n \"memchr\",\n \"ryu\",\n \"serde\",\n]\n\n[[package]]\nname = \"serde_path_to_error\"\nversion = \"0.1.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6\"\ndependencies = [\n \"itoa\",\n \"serde\",\n]\n\n[[package]]\nname = \"serde_regex\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf\"\ndependencies = [\n \"regex\",\n \"serde\",\n]\n\n[[package]]\nname = \"serde_spanned\"\nversion = \"0.6.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"serde_urlencoded\"\nversion = \"0.7.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd\"\ndependencies = [\n \"form_urlencoded\",\n \"itoa\",\n \"ryu\",\n \"serde\",\n]\n\n[[package]]\nname = \"serde_variant\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0a0068df419f9d9b6488fdded3f1c818522cdea328e02ce9d9f147380265a432\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"serde_yaml\"\nversion = \"0.9.34+deprecated\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47\"\ndependencies = [\n \"indexmap\",\n \"itoa\",\n \"ryu\",\n \"serde\",\n \"unsafe-libyaml\",\n]\n\n[[package]]\nname = \"serial_test\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d\"\ndependencies = [\n \"dashmap 5.5.3\",\n \"futures\",\n \"lazy_static\",\n \"log\",\n \"parking_lot\",\n \"serial_test_derive\",\n]\n\n[[package]]\nname = \"serial_test_derive\"\nversion = \"2.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"servo_arc\"\nversion = \"0.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ae65c4249478a2647db249fb43e23cec56a2c8974a427e7bd8cb5a1d0964921a\"\ndependencies = [\n \"stable_deref_trait\",\n]\n\n[[package]]\nname = \"sha1\"\nversion = \"0.10.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba\"\ndependencies = [\n \"cfg-if\",\n \"cpufeatures\",\n \"digest\",\n]\n\n[[package]]\nname = \"sha1_smol\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d\"\n\n[[package]]\nname = \"sha2\"\nversion = \"0.10.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8\"\ndependencies = [\n \"cfg-if\",\n \"cpufeatures\",\n \"digest\",\n]\n\n[[package]]\nname = \"sharded-slab\"\nversion = \"0.1.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6\"\ndependencies = [\n \"lazy_static\",\n]\n\n[[package]]\nname = \"shared_child\"\nversion = \"1.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e362d9935bc50f019969e2f9ecd66786612daae13e8f277be7bfb66e8bed3f7\"\ndependencies = [\n \"libc\",\n \"sigchld\",\n \"windows-sys 0.60.2\",\n]\n\n[[package]]\nname = \"shared_thread\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"52b86057fcb5423f5018e331ac04623e32d6b5ce85e33300f92c79a1973928b0\"\n\n[[package]]\nname = \"shlex\"\nversion = \"1.3.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64\"\n\n[[package]]\nname = \"sigchld\"\nversion = \"0.2.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"47106eded3c154e70176fc83df9737335c94ce22f821c32d17ed1db1f83badb1\"\ndependencies = [\n \"libc\",\n \"os_pipe\",\n \"signal-hook\",\n]\n\n[[package]]\nname = \"signal-hook\"\nversion = \"0.3.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2\"\ndependencies = [\n \"libc\",\n \"signal-hook-registry\",\n]\n\n[[package]]\nname = \"signal-hook-registry\"\nversion = \"1.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1\"\ndependencies = [\n \"libc\",\n]\n\n[[package]]\nname = \"signature\"\nversion = \"2.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de\"\ndependencies = [\n \"digest\",\n \"rand_core 0.6.4\",\n]\n\n[[package]]\nname = \"simdutf8\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e\"\n\n[[package]]\nname = \"similar\"\nversion = \"2.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa\"\n\n[[package]]\nname = \"simple_asn1\"\nversion = \"0.6.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb\"\ndependencies = [\n \"num-bigint\",\n \"num-traits\",\n \"thiserror 2.0.11\",\n \"time\",\n]\n\n[[package]]\nname = \"siphasher\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d\"\n\n[[package]]\nname = \"slab\"\nversion = \"0.4.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67\"\ndependencies = [\n \"autocfg\",\n]\n\n[[package]]\nname = \"slug\"\nversion = \"0.1.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"882a80f72ee45de3cc9a5afeb2da0331d58df69e4e7d8eeb5d3c7784ae67e724\"\ndependencies = [\n \"deunicode\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"smallvec\"\nversion = \"1.13.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"socket2\"\nversion = \"0.5.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.52.0\",\n]\n\n[[package]]\nname = \"socket2\"\nversion = \"0.6.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807\"\ndependencies = [\n \"libc\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"spin\"\nversion = \"0.9.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67\"\ndependencies = [\n \"lock_api\",\n]\n\n[[package]]\nname = \"spki\"\nversion = \"0.7.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d\"\ndependencies = [\n \"base64ct\",\n \"der\",\n]\n\n[[package]]\nname = \"sqlx\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc\"\ndependencies = [\n \"sqlx-core\",\n \"sqlx-macros\",\n \"sqlx-mysql\",\n \"sqlx-postgres\",\n \"sqlx-sqlite\",\n]\n\n[[package]]\nname = \"sqlx-core\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6\"\ndependencies = [\n \"base64 0.22.1\",\n \"bigdecimal\",\n \"bytes\",\n \"chrono\",\n \"crc\",\n \"crossbeam-queue\",\n \"either\",\n \"event-listener 5.4.0\",\n \"futures-core\",\n \"futures-intrusive\",\n \"futures-io\",\n \"futures-util\",\n \"hashbrown 0.15.2\",\n \"hashlink\",\n \"indexmap\",\n \"log\",\n \"memchr\",\n \"once_cell\",\n \"percent-encoding\",\n \"rust_decimal\",\n \"rustls\",\n \"serde\",\n \"serde_json\",\n \"sha2\",\n \"smallvec\",\n \"thiserror 2.0.11\",\n \"time\",\n \"tokio\",\n \"tokio-stream\",\n \"tracing\",\n \"url\",\n \"uuid\",\n \"webpki-roots\",\n]\n\n[[package]]\nname = \"sqlx-macros\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"sqlx-core\",\n \"sqlx-macros-core\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"sqlx-macros-core\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b\"\ndependencies = [\n \"dotenvy\",\n \"either\",\n \"heck 0.5.0\",\n \"hex\",\n \"once_cell\",\n \"proc-macro2\",\n \"quote\",\n \"serde\",\n \"serde_json\",\n \"sha2\",\n \"sqlx-core\",\n \"sqlx-mysql\",\n \"sqlx-postgres\",\n \"sqlx-sqlite\",\n \"syn 2.0.98\",\n \"tokio\",\n \"url\",\n]\n\n[[package]]\nname = \"sqlx-mysql\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526\"\ndependencies = [\n \"atoi\",\n \"base64 0.22.1\",\n \"bigdecimal\",\n \"bitflags\",\n \"byteorder\",\n \"bytes\",\n \"chrono\",\n \"crc\",\n \"digest\",\n \"dotenvy\",\n \"either\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-io\",\n \"futures-util\",\n \"generic-array\",\n \"hex\",\n \"hkdf\",\n \"hmac\",\n \"itoa\",\n \"log\",\n \"md-5\",\n \"memchr\",\n \"once_cell\",\n \"percent-encoding\",\n \"rand 0.8.5\",\n \"rsa\",\n \"rust_decimal\",\n \"serde\",\n \"sha1\",\n \"sha2\",\n \"smallvec\",\n \"sqlx-core\",\n \"stringprep\",\n \"thiserror 2.0.11\",\n \"time\",\n \"tracing\",\n \"uuid\",\n \"whoami\",\n]\n\n[[package]]\nname = \"sqlx-postgres\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46\"\ndependencies = [\n \"atoi\",\n \"base64 0.22.1\",\n \"bigdecimal\",\n \"bitflags\",\n \"byteorder\",\n \"chrono\",\n \"crc\",\n \"dotenvy\",\n \"etcetera\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-util\",\n \"hex\",\n \"hkdf\",\n \"hmac\",\n \"home\",\n \"itoa\",\n \"log\",\n \"md-5\",\n \"memchr\",\n \"num-bigint\",\n \"once_cell\",\n \"rand 0.8.5\",\n \"rust_decimal\",\n \"serde\",\n \"serde_json\",\n \"sha2\",\n \"smallvec\",\n \"sqlx-core\",\n \"stringprep\",\n \"thiserror 2.0.11\",\n \"time\",\n \"tracing\",\n \"uuid\",\n \"whoami\",\n]\n\n[[package]]\nname = \"sqlx-sqlite\"\nversion = \"0.8.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea\"\ndependencies = [\n \"atoi\",\n \"chrono\",\n \"flume\",\n \"futures-channel\",\n \"futures-core\",\n \"futures-executor\",\n \"futures-intrusive\",\n \"futures-util\",\n \"libsqlite3-sys\",\n \"log\",\n \"percent-encoding\",\n \"serde\",\n \"serde_urlencoded\",\n \"sqlx-core\",\n \"thiserror 2.0.11\",\n \"time\",\n \"tracing\",\n \"url\",\n \"uuid\",\n]\n\n[[package]]\nname = \"stable_deref_trait\"\nversion = \"1.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3\"\n\n[[package]]\nname = \"stacker\"\nversion = \"0.1.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b\"\ndependencies = [\n \"cc\",\n \"cfg-if\",\n \"libc\",\n \"psm\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"static_assertions\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f\"\n\n[[package]]\nname = \"static_assertions_next\"\nversion = \"1.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d7beae5182595e9a8b683fa98c4317f956c9a2dec3b9716990d20023cc60c766\"\n\n[[package]]\nname = \"string_cache\"\nversion = \"0.8.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"938d512196766101d333398efde81bc1f37b00cb42c2f8350e5df639f040bbbe\"\ndependencies = [\n \"new_debug_unreachable\",\n \"parking_lot\",\n \"phf_shared\",\n \"precomputed-hash\",\n \"serde\",\n]\n\n[[package]]\nname = \"string_cache_codegen\"\nversion = \"0.5.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"244292f3441c89febe5b5bdfbb6863aeaf4f64da810ea3050fd927b27b8d92ce\"\ndependencies = [\n \"phf_generator\",\n \"phf_shared\",\n \"proc-macro2\",\n \"quote\",\n]\n\n[[package]]\nname = \"stringprep\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1\"\ndependencies = [\n \"unicode-bidi\",\n \"unicode-normalization\",\n \"unicode-properties\",\n]\n\n[[package]]\nname = \"strsim\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f\"\n\n[[package]]\nname = \"strum\"\nversion = \"0.26.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06\"\ndependencies = [\n \"strum_macros\",\n]\n\n[[package]]\nname = \"strum\"\nversion = \"0.27.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf\"\n\n[[package]]\nname = \"strum_macros\"\nversion = \"0.26.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be\"\ndependencies = [\n \"heck 0.5.0\",\n \"proc-macro2\",\n \"quote\",\n \"rustversion\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"subtle\"\nversion = \"2.6.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292\"\n\n[[package]]\nname = \"syn\"\nversion = \"1.0.109\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"syn\"\nversion = \"2.0.98\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"sync_wrapper\"\nversion = \"1.0.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263\"\ndependencies = [\n \"futures-core\",\n]\n\n[[package]]\nname = \"synstructure\"\nversion = \"0.13.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"tagptr\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417\"\n\n[[package]]\nname = \"tap\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369\"\n\n[[package]]\nname = \"tempfile\"\nversion = \"3.16.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91\"\ndependencies = [\n \"cfg-if\",\n \"fastrand\",\n \"getrandom 0.3.1\",\n \"once_cell\",\n \"rustix\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"tendril\"\nversion = \"0.4.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0\"\ndependencies = [\n \"futf\",\n \"mac\",\n \"utf-8\",\n]\n\n[[package]]\nname = \"tera\"\nversion = \"1.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ab9d851b45e865f178319da0abdbfe6acbc4328759ff18dafc3a41c16b4cd2ee\"\ndependencies = [\n \"chrono\",\n \"chrono-tz\",\n \"globwalk\",\n \"humansize\",\n \"lazy_static\",\n \"percent-encoding\",\n \"pest\",\n \"pest_derive\",\n \"rand 0.8.5\",\n \"regex\",\n \"serde\",\n \"serde_json\",\n \"slug\",\n \"unic-segment\",\n]\n\n[[package]]\nname = \"thiserror\"\nversion = \"1.0.69\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52\"\ndependencies = [\n \"thiserror-impl 1.0.69\",\n]\n\n[[package]]\nname = \"thiserror\"\nversion = \"2.0.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc\"\ndependencies = [\n \"thiserror-impl 2.0.11\",\n]\n\n[[package]]\nname = \"thiserror-impl\"\nversion = \"1.0.69\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"thiserror-impl\"\nversion = \"2.0.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"thread_local\"\nversion = \"1.1.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c\"\ndependencies = [\n \"cfg-if\",\n \"once_cell\",\n]\n\n[[package]]\nname = \"time\"\nversion = \"0.3.37\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21\"\ndependencies = [\n \"deranged\",\n \"itoa\",\n \"num-conv\",\n \"powerfmt\",\n \"serde\",\n \"time-core\",\n \"time-macros\",\n]\n\n[[package]]\nname = \"time-core\"\nversion = \"0.1.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3\"\n\n[[package]]\nname = \"time-macros\"\nversion = \"0.2.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de\"\ndependencies = [\n \"num-conv\",\n \"time-core\",\n]\n\n[[package]]\nname = \"tinystr\"\nversion = \"0.7.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f\"\ndependencies = [\n \"displaydoc\",\n \"zerovec\",\n]\n\n[[package]]\nname = \"tinyvec\"\nversion = \"1.8.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8\"\ndependencies = [\n \"tinyvec_macros\",\n]\n\n[[package]]\nname = \"tinyvec_macros\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20\"\n\n[[package]]\nname = \"tokio\"\nversion = \"1.47.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038\"\ndependencies = [\n \"backtrace\",\n \"bytes\",\n \"io-uring\",\n \"libc\",\n \"mio\",\n \"pin-project-lite\",\n \"signal-hook-registry\",\n \"slab\",\n \"socket2 0.6.0\",\n \"tokio-macros\",\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"tokio-cron-scheduler\"\nversion = \"0.11.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f2594dd7c2abbbafbb1c78d167fd10860dc7bd75f814cb051a1e0d3e796b9702\"\ndependencies = [\n \"chrono\",\n \"cron\",\n \"num-derive\",\n \"num-traits\",\n \"tokio\",\n \"tracing\",\n \"uuid\",\n]\n\n[[package]]\nname = \"tokio-macros\"\nversion = \"2.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"tokio-rustls\"\nversion = \"0.26.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37\"\ndependencies = [\n \"rustls\",\n \"tokio\",\n]\n\n[[package]]\nname = \"tokio-stream\"\nversion = \"0.1.17\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047\"\ndependencies = [\n \"futures-core\",\n \"pin-project-lite\",\n \"tokio\",\n]\n\n[[package]]\nname = \"tokio-tungstenite\"\nversion = \"0.26.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"be4bf6fecd69fcdede0ec680aaf474cdab988f9de6bc73d3758f0160e3b7025a\"\ndependencies = [\n \"futures-util\",\n \"log\",\n \"tokio\",\n \"tungstenite\",\n]\n\n[[package]]\nname = \"tokio-util\"\nversion = \"0.7.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078\"\ndependencies = [\n \"bytes\",\n \"futures-core\",\n \"futures-io\",\n \"futures-sink\",\n \"pin-project-lite\",\n \"tokio\",\n]\n\n[[package]]\nname = \"toml\"\nversion = \"0.8.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e\"\ndependencies = [\n \"serde\",\n \"serde_spanned\",\n \"toml_datetime\",\n \"toml_edit\",\n]\n\n[[package]]\nname = \"toml_datetime\"\nversion = \"0.6.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41\"\ndependencies = [\n \"serde\",\n]\n\n[[package]]\nname = \"toml_edit\"\nversion = \"0.22.23\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"02a8b472d1a3d7c18e2d61a489aee3453fd9031c33e4f55bd533f4a7adca1bee\"\ndependencies = [\n \"indexmap\",\n \"serde\",\n \"serde_spanned\",\n \"toml_datetime\",\n \"winnow\",\n]\n\n[[package]]\nname = \"tower\"\nversion = \"0.4.13\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c\"\ndependencies = [\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"tower\"\nversion = \"0.5.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9\"\ndependencies = [\n \"futures-core\",\n \"futures-util\",\n \"pin-project-lite\",\n \"sync_wrapper\",\n \"tokio\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"tower-http\"\nversion = \"0.6.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"403fa3b783d4b626a8ad51d766ab03cb6d2dbfc46b1c5d4448395e6628dc9697\"\ndependencies = [\n \"async-compression\",\n \"bitflags\",\n \"bytes\",\n \"futures-core\",\n \"futures-util\",\n \"http\",\n \"http-body\",\n \"http-body-util\",\n \"http-range-header\",\n \"httpdate\",\n \"mime\",\n \"mime_guess\",\n \"percent-encoding\",\n \"pin-project-lite\",\n \"tokio\",\n \"tokio-util\",\n \"tower-layer\",\n \"tower-service\",\n \"tracing\",\n]\n\n[[package]]\nname = \"tower-layer\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e\"\n\n[[package]]\nname = \"tower-service\"\nversion = \"0.3.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3\"\n\n[[package]]\nname = \"tracing\"\nversion = \"0.1.41\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0\"\ndependencies = [\n \"log\",\n \"pin-project-lite\",\n \"tracing-attributes\",\n \"tracing-core\",\n]\n\n[[package]]\nname = \"tracing-appender\"\nversion = \"0.2.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf\"\ndependencies = [\n \"crossbeam-channel\",\n \"thiserror 1.0.69\",\n \"time\",\n \"tracing-subscriber\",\n]\n\n[[package]]\nname = \"tracing-attributes\"\nversion = \"0.1.28\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"tracing-core\"\nversion = \"0.1.33\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c\"\ndependencies = [\n \"once_cell\",\n \"valuable\",\n]\n\n[[package]]\nname = \"tracing-log\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3\"\ndependencies = [\n \"log\",\n \"once_cell\",\n \"tracing-core\",\n]\n\n[[package]]\nname = \"tracing-serde\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1\"\ndependencies = [\n \"serde\",\n \"tracing-core\",\n]\n\n[[package]]\nname = \"tracing-subscriber\"\nversion = \"0.3.19\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008\"\ndependencies = [\n \"matchers\",\n \"nu-ansi-term\",\n \"once_cell\",\n \"regex\",\n \"serde\",\n \"serde_json\",\n \"sharded-slab\",\n \"smallvec\",\n \"thread_local\",\n \"tracing\",\n \"tracing-core\",\n \"tracing-log\",\n \"tracing-serde\",\n]\n\n[[package]]\nname = \"tree-fs\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5c6115680fa5fdb99b4ff19c9c3217e75116d2bb0eae82458c4e1818be6a10c7\"\ndependencies = [\n \"rand 0.9.2\",\n \"serde\",\n]\n\n[[package]]\nname = \"try-lock\"\nversion = \"0.2.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b\"\n\n[[package]]\nname = \"tungstenite\"\nversion = \"0.26.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"413083a99c579593656008130e29255e54dcaae495be556cc26888f211648c24\"\ndependencies = [\n \"byteorder\",\n \"bytes\",\n \"data-encoding\",\n \"http\",\n \"httparse\",\n \"log\",\n \"rand 0.8.5\",\n \"sha1\",\n \"thiserror 2.0.11\",\n \"utf-8\",\n]\n\n[[package]]\nname = \"typenum\"\nversion = \"1.17.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825\"\n\n[[package]]\nname = \"ucd-trie\"\nversion = \"0.1.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971\"\n\n[[package]]\nname = \"ulid\"\nversion = \"1.1.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f294bff79170ed1c5633812aff1e565c35d993a36e757f9bc0accf5eec4e6045\"\ndependencies = [\n \"rand 0.8.5\",\n \"web-time\",\n]\n\n[[package]]\nname = \"unic-char-property\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221\"\ndependencies = [\n \"unic-char-range\",\n]\n\n[[package]]\nname = \"unic-char-range\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc\"\n\n[[package]]\nname = \"unic-common\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc\"\n\n[[package]]\nname = \"unic-segment\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23\"\ndependencies = [\n \"unic-ucd-segment\",\n]\n\n[[package]]\nname = \"unic-ucd-segment\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700\"\ndependencies = [\n \"unic-char-property\",\n \"unic-char-range\",\n \"unic-ucd-version\",\n]\n\n[[package]]\nname = \"unic-ucd-version\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4\"\ndependencies = [\n \"unic-common\",\n]\n\n[[package]]\nname = \"unicase\"\nversion = \"2.8.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539\"\n\n[[package]]\nname = \"unicode-bidi\"\nversion = \"0.3.18\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5\"\n\n[[package]]\nname = \"unicode-ident\"\nversion = \"1.0.16\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034\"\n\n[[package]]\nname = \"unicode-normalization\"\nversion = \"0.1.24\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956\"\ndependencies = [\n \"tinyvec\",\n]\n\n[[package]]\nname = \"unicode-properties\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0\"\n\n[[package]]\nname = \"unicode-width\"\nversion = \"0.1.14\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af\"\n\n[[package]]\nname = \"unsafe-libyaml\"\nversion = \"0.2.11\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861\"\n\n[[package]]\nname = \"untrusted\"\nversion = \"0.9.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1\"\n\n[[package]]\nname = \"url\"\nversion = \"2.5.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60\"\ndependencies = [\n \"form_urlencoded\",\n \"idna\",\n \"percent-encoding\",\n]\n\n[[package]]\nname = \"utf-8\"\nversion = \"0.7.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9\"\n\n[[package]]\nname = \"utf16_iter\"\nversion = \"1.0.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246\"\n\n[[package]]\nname = \"utf8-width\"\nversion = \"0.1.7\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3\"\n\n[[package]]\nname = \"utf8_iter\"\nversion = \"1.0.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be\"\n\n[[package]]\nname = \"utf8parse\"\nversion = \"0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821\"\n\n[[package]]\nname = \"uuid\"\nversion = \"1.12.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b\"\ndependencies = [\n \"getrandom 0.2.15\",\n \"rand 0.8.5\",\n \"serde\",\n]\n\n[[package]]\nname = \"validator\"\nversion = \"0.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"43fb22e1a008ece370ce08a3e9e4447a910e92621bb49b85d6e48a45397e7cfa\"\ndependencies = [\n \"idna\",\n \"once_cell\",\n \"regex\",\n \"serde\",\n \"serde_derive\",\n \"serde_json\",\n \"url\",\n \"validator_derive\",\n]\n\n[[package]]\nname = \"validator_derive\"\nversion = \"0.20.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b7df16e474ef958526d1205f6dda359fdfab79d9aa6d54bafcb92dcd07673dca\"\ndependencies = [\n \"darling\",\n \"once_cell\",\n \"proc-macro-error2\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"valuable\"\nversion = \"0.1.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65\"\n\n[[package]]\nname = \"value-bag\"\nversion = \"1.10.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2\"\n\n[[package]]\nname = \"vcpkg\"\nversion = \"0.2.15\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426\"\n\n[[package]]\nname = \"version_check\"\nversion = \"0.9.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a\"\n\n[[package]]\nname = \"walkdir\"\nversion = \"2.5.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b\"\ndependencies = [\n \"same-file\",\n \"winapi-util\",\n]\n\n[[package]]\nname = \"want\"\nversion = \"0.3.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e\"\ndependencies = [\n \"try-lock\",\n]\n\n[[package]]\nname = \"wasi\"\nversion = \"0.11.0+wasi-snapshot-preview1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423\"\n\n[[package]]\nname = \"wasi\"\nversion = \"0.13.3+wasi-0.2.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2\"\ndependencies = [\n \"wit-bindgen-rt\",\n]\n\n[[package]]\nname = \"wasite\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b\"\n\n[[package]]\nname = \"wasm-bindgen\"\nversion = \"0.2.100\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5\"\ndependencies = [\n \"cfg-if\",\n \"once_cell\",\n \"rustversion\",\n \"wasm-bindgen-macro\",\n]\n\n[[package]]\nname = \"wasm-bindgen-backend\"\nversion = \"0.2.100\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6\"\ndependencies = [\n \"bumpalo\",\n \"log\",\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n \"wasm-bindgen-shared\",\n]\n\n[[package]]\nname = \"wasm-bindgen-futures\"\nversion = \"0.4.50\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61\"\ndependencies = [\n \"cfg-if\",\n \"js-sys\",\n \"once_cell\",\n \"wasm-bindgen\",\n \"web-sys\",\n]\n\n[[package]]\nname = \"wasm-bindgen-macro\"\nversion = \"0.2.100\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407\"\ndependencies = [\n \"quote\",\n \"wasm-bindgen-macro-support\",\n]\n\n[[package]]\nname = \"wasm-bindgen-macro-support\"\nversion = \"0.2.100\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n \"wasm-bindgen-backend\",\n \"wasm-bindgen-shared\",\n]\n\n[[package]]\nname = \"wasm-bindgen-shared\"\nversion = \"0.2.100\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d\"\ndependencies = [\n \"unicode-ident\",\n]\n\n[[package]]\nname = \"wasm-streams\"\nversion = \"0.4.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65\"\ndependencies = [\n \"futures-util\",\n \"js-sys\",\n \"wasm-bindgen\",\n \"wasm-bindgen-futures\",\n \"web-sys\",\n]\n\n[[package]]\nname = \"web-sys\"\nversion = \"0.3.77\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2\"\ndependencies = [\n \"js-sys\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"web-time\"\nversion = \"1.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb\"\ndependencies = [\n \"js-sys\",\n \"wasm-bindgen\",\n]\n\n[[package]]\nname = \"webpki-roots\"\nversion = \"0.26.8\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9\"\ndependencies = [\n \"rustls-pki-types\",\n]\n\n[[package]]\nname = \"whoami\"\nversion = \"1.5.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d\"\ndependencies = [\n \"redox_syscall\",\n \"wasite\",\n]\n\n[[package]]\nname = \"winapi\"\nversion = \"0.3.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419\"\ndependencies = [\n \"winapi-i686-pc-windows-gnu\",\n \"winapi-x86_64-pc-windows-gnu\",\n]\n\n[[package]]\nname = \"winapi-i686-pc-windows-gnu\"\nversion = \"0.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6\"\n\n[[package]]\nname = \"winapi-util\"\nversion = \"0.1.9\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb\"\ndependencies = [\n \"windows-sys 0.59.0\",\n]\n\n[[package]]\nname = \"winapi-x86_64-pc-windows-gnu\"\nversion = \"0.4.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f\"\n\n[[package]]\nname = \"windows\"\nversion = \"0.52.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be\"\ndependencies = [\n \"windows-core 0.52.0\",\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows\"\nversion = \"0.58.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6\"\ndependencies = [\n \"windows-core 0.58.0\",\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-core\"\nversion = \"0.52.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9\"\ndependencies = [\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-core\"\nversion = \"0.58.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99\"\ndependencies = [\n \"windows-implement\",\n \"windows-interface\",\n \"windows-result\",\n \"windows-strings\",\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-implement\"\nversion = \"0.58.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"windows-interface\"\nversion = \"0.58.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"windows-link\"\nversion = \"0.1.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a\"\n\n[[package]]\nname = \"windows-registry\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0\"\ndependencies = [\n \"windows-result\",\n \"windows-strings\",\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-result\"\nversion = \"0.2.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e\"\ndependencies = [\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-strings\"\nversion = \"0.1.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10\"\ndependencies = [\n \"windows-result\",\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.48.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9\"\ndependencies = [\n \"windows-targets 0.48.5\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.52.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d\"\ndependencies = [\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.59.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b\"\ndependencies = [\n \"windows-targets 0.52.6\",\n]\n\n[[package]]\nname = \"windows-sys\"\nversion = \"0.60.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb\"\ndependencies = [\n \"windows-targets 0.53.3\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c\"\ndependencies = [\n \"windows_aarch64_gnullvm 0.48.5\",\n \"windows_aarch64_msvc 0.48.5\",\n \"windows_i686_gnu 0.48.5\",\n \"windows_i686_msvc 0.48.5\",\n \"windows_x86_64_gnu 0.48.5\",\n \"windows_x86_64_gnullvm 0.48.5\",\n \"windows_x86_64_msvc 0.48.5\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973\"\ndependencies = [\n \"windows_aarch64_gnullvm 0.52.6\",\n \"windows_aarch64_msvc 0.52.6\",\n \"windows_i686_gnu 0.52.6\",\n \"windows_i686_gnullvm 0.52.6\",\n \"windows_i686_msvc 0.52.6\",\n \"windows_x86_64_gnu 0.52.6\",\n \"windows_x86_64_gnullvm 0.52.6\",\n \"windows_x86_64_msvc 0.52.6\",\n]\n\n[[package]]\nname = \"windows-targets\"\nversion = \"0.53.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91\"\ndependencies = [\n \"windows-link\",\n \"windows_aarch64_gnullvm 0.53.0\",\n \"windows_aarch64_msvc 0.53.0\",\n \"windows_i686_gnu 0.53.0\",\n \"windows_i686_gnullvm 0.53.0\",\n \"windows_i686_msvc 0.53.0\",\n \"windows_x86_64_gnu 0.53.0\",\n \"windows_x86_64_gnullvm 0.53.0\",\n \"windows_x86_64_msvc 0.53.0\",\n]\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8\"\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3\"\n\n[[package]]\nname = \"windows_aarch64_gnullvm\"\nversion = \"0.53.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469\"\n\n[[package]]\nname = \"windows_aarch64_msvc\"\nversion = \"0.53.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b\"\n\n[[package]]\nname = \"windows_i686_gnu\"\nversion = \"0.53.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3\"\n\n[[package]]\nname = \"windows_i686_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66\"\n\n[[package]]\nname = \"windows_i686_gnullvm\"\nversion = \"0.53.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66\"\n\n[[package]]\nname = \"windows_i686_msvc\"\nversion = \"0.53.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78\"\n\n[[package]]\nname = \"windows_x86_64_gnu\"\nversion = \"0.53.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d\"\n\n[[package]]\nname = \"windows_x86_64_gnullvm\"\nversion = \"0.53.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.48.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.52.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec\"\n\n[[package]]\nname = \"windows_x86_64_msvc\"\nversion = \"0.53.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486\"\n\n[[package]]\nname = \"winnow\"\nversion = \"0.7.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"7e49d2d35d3fad69b39b94139037ecfb4f359f08958b9c11e7315ce770462419\"\ndependencies = [\n \"memchr\",\n]\n\n[[package]]\nname = \"wit-bindgen-rt\"\nversion = \"0.33.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c\"\ndependencies = [\n \"bitflags\",\n]\n\n[[package]]\nname = \"write16\"\nversion = \"1.0.0\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936\"\n\n[[package]]\nname = \"writeable\"\nversion = \"0.5.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51\"\n\n[[package]]\nname = \"wyz\"\nversion = \"0.5.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed\"\ndependencies = [\n \"tap\",\n]\n\n[[package]]\nname = \"yansi\"\nversion = \"1.0.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049\"\n\n[[package]]\nname = \"yoke\"\nversion = \"0.7.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40\"\ndependencies = [\n \"serde\",\n \"stable_deref_trait\",\n \"yoke-derive\",\n \"zerofrom\",\n]\n\n[[package]]\nname = \"yoke-derive\"\nversion = \"0.7.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n \"synstructure\",\n]\n\n[[package]]\nname = \"zerocopy\"\nversion = \"0.7.35\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0\"\ndependencies = [\n \"byteorder\",\n \"zerocopy-derive 0.7.35\",\n]\n\n[[package]]\nname = \"zerocopy\"\nversion = \"0.8.14\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468\"\ndependencies = [\n \"zerocopy-derive 0.8.14\",\n]\n\n[[package]]\nname = \"zerocopy-derive\"\nversion = \"0.7.35\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"zerocopy-derive\"\nversion = \"0.8.14\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"zerofrom\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e\"\ndependencies = [\n \"zerofrom-derive\",\n]\n\n[[package]]\nname = \"zerofrom-derive\"\nversion = \"0.1.5\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n \"synstructure\",\n]\n\n[[package]]\nname = \"zeroize\"\nversion = \"1.8.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde\"\n\n[[package]]\nname = \"zerovec\"\nversion = \"0.10.4\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079\"\ndependencies = [\n \"yoke\",\n \"zerofrom\",\n \"zerovec-derive\",\n]\n\n[[package]]\nname = \"zerovec-derive\"\nversion = \"0.10.3\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6\"\ndependencies = [\n \"proc-macro2\",\n \"quote\",\n \"syn 2.0.98\",\n]\n\n[[package]]\nname = \"zstd\"\nversion = \"0.13.2\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9\"\ndependencies = [\n \"zstd-safe\",\n]\n\n[[package]]\nname = \"zstd-safe\"\nversion = \"7.2.1\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059\"\ndependencies = [\n \"zstd-sys\",\n]\n\n[[package]]\nname = \"zstd-sys\"\nversion = \"2.0.13+zstd.1.5.6\"\nsource = \"registry+https://github.com/rust-lang/crates.io-index\"\nchecksum = \"38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa\"\ndependencies = [\n \"cc\",\n \"pkg-config\",\n]\n"
  },
  {
    "path": "examples/react_admin/backend/Cargo.toml",
    "content": "[workspace]\n\n[package]\nedition      = \"2024\"\nname         = \"loco_seaography\"\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\n\nloco-rs   = { version = \"0.16\" }\nmigration = { path = \"migration\" }\n\nasync-trait        = \"0.1.74\"\naxum               = { version = \"0.8\", features = [\"multipart\"] }\nchrono             = \"0.4\"\neyre               = \"0.6\"\ninclude_dir        = \"0.7\"\nserde              = { version = \"1\", features = [\"derive\"] }\nserde_json         = \"1\"\ntokio              = { version = \"1.33.0\", default-features = false }\ntokio-util         = \"0.7.11\"\ntracing            = \"0.1.40\"\ntracing-subscriber = { version = \"0.3.17\", features = [\"env-filter\", \"json\"] }\nuuid               = { version = \"1.6.0\", features = [\"v4\"] }\nvalidator          = { version = \"0.20\" }\n\nasync-graphql = { version = \"7.0.17\", features = [\n    \"decimal\",\n    \"chrono\",\n    \"dataloader\",\n    \"dynamic-schema\",\n] }\nasync-graphql-axum = { version = \"7.0\" }\nlazy_static = { version = \"1.4\" }\ntower-service = { version = \"0.3\" }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"sqlx-sqlite\",\n    \"sqlx-postgres\",\n    \"runtime-tokio-rustls\",\n    \"macros\",\n]\nversion = \"~2.0.0-rc.37\" # sea-orm version\n\n[dependencies.seaography]\nbranch   = \"main\"\nfeatures = [\"with-decimal\", \"with-chrono\"]\ngit      = \"https://github.com/SeaQL/seaography.git\"\nversion  = \"~2.0.0-rc.1\"                             # seaography version\n\n[[bin]]\nname              = \"loco_seaography-cli\"\npath              = \"src/bin/main.rs\"\nrequired-features = []\n\n[dev-dependencies]\ninsta       = { version = \"1.34.0\", features = [\"redactions\", \"yaml\", \"filters\"] }\nloco-rs     = { version = \"0.16\", features = [\"testing\"] }\nrstest      = \"0.18.2\"\nserial_test = \"2.0.0\"\n\n[patch.crates-io]\nloco-rs = { git = \"https://github.com/SeaQL/loco\", branch = \"master\" }\n"
  },
  {
    "path": "examples/react_admin/backend/config/development.yaml",
    "content": "# Loco configuration file documentation\n\n# Application logging configuration\nlogger:\n  # Enable or disable logging.\n  enable: true\n  # Enable pretty backtrace (sets RUST_BACKTRACE=1)\n  pretty_backtrace: true\n  # Log level, options: trace, debug, info, warn or error.\n  level: debug\n  # Define the logging format. options: compact, pretty or Json\n  format: compact\n  # By default the logger has filtering only logs that came from your code or logs that came from `loco` framework. to see all third party libraries\n  # Uncomment the line below to override to see all third party libraries you can enable this config and override the logger filters.\n  # override_filter: trace\n\n# Web server configuration\nserver:\n  # Port on which the server will listen. the server binding is 0.0.0.0:{PORT}\n  port: 3000\n  # The UI hostname or IP address that mailers will point to.\n  host: http://localhost\n  # Out of the box middleware configuration. to disable middleware you can changed the `enable` field to `false` of comment the middleware block\n  middlewares:\n    # Enable Etag cache header middleware\n    etag:\n      enable: true\n    # Allows to limit the payload size request. payload that bigger than this file will blocked the request.\n    limit_payload:\n      # Enable/Disable the middleware.\n      enable: true\n      # the limit size. can be b,kb,kib,mb,mib,gb,gib\n      body_limit: 5mb\n    # Generating a unique request ID and enhancing logging with additional information such as the start and completion of request processing, latency, status code, and other request details.\n    logger:\n      # Enable/Disable the middleware.\n      enable: true\n    # when your code is panicked, the request still returns 500 status code.\n    catch_panic:\n      # Enable/Disable the middleware.\n      enable: true\n    # Timeout for incoming requests middleware. requests that take more time from the configuration will cute and 408 status code will returned.\n    timeout_request:\n      # Enable/Disable the middleware.\n      enable: false\n      # Duration time in milliseconds.\n      timeout: 5000\n    cors:\n      enable: true\n      # Set the value of the [`Access-Control-Allow-Origin`][mdn] header\n      # allow_origins:\n      #   - https://loco.rs\n      # Set the value of the [`Access-Control-Allow-Headers`][mdn] header\n      # allow_headers:\n      # - Content-Type\n      # Set the value of the [`Access-Control-Allow-Methods`][mdn] header\n      # allow_methods:\n      #   - POST\n      # Set the value of the [`Access-Control-Max-Age`][mdn] header in seconds\n      # max_age: 3600\n\n# Worker Configuration\nworkers:\n  # specifies the worker mode. Options:\n  #   - BackgroundQueue - Workers operate asynchronously in the background, processing queued.\n  #   - ForegroundBlocking - Workers operate in the foreground and block until tasks are completed.\n  #   - BackgroundAsync - Workers operate asynchronously in the background, processing tasks with async capabilities.\n  mode: BackgroundQueue\n\n# Mailer Configuration.\nmailer:\n  # SMTP mailer configuration.\n  smtp:\n    # Enable/Disable smtp mailer.\n    enable: true\n    # SMTP server host. e.x localhost, smtp.gmail.com\n    host: {{ get_env(name=\"MAILER_HOST\", default=\"localhost\") }}\n    # SMTP server port\n    port: 1025\n    # Use secure connection (SSL/TLS).\n    secure: false\n    # auth:\n    #   user:\n    #   password:\n\n# Initializers Configuration\n# initializers:\n#  oauth2:\n#    authorization_code: # Authorization code grant type\n#      - client_identifier: google # Identifier for the OAuth2 provider. Replace 'google' with your provider's name if different, must be unique within the oauth2 config.\n#        ... other fields\n\n# Database Configuration\ndatabase:\n  # Database connection URI\n  uri: {{ get_env(name=\"DATABASE_URL\", default=\"postgres://loco:loco@localhost:5432/loco_seaography_development\") }}\n  # When enabled, the sql query will be logged.\n  enable_logging: false\n  # Set the timeout duration when acquiring a connection.\n  connect_timeout: 500\n  # Set the idle duration before closing a connection.\n  idle_timeout: 500\n  # Minimum number of connections for a pool.\n  min_connections: 1\n  # Maximum number of connections for a pool.\n  max_connections: 1\n  # Run migration up when application loaded\n  auto_migrate: true\n  # Truncate database when application loaded. This is a dangerous operation, make sure that you using this flag only on dev environments or test mode\n  dangerously_truncate: false\n  # Recreating schema when application loaded.  This is a dangerous operation, make sure that you using this flag only on dev environments or test mode\n  dangerously_recreate: false\n\n# Redis Configuration\nredis:\n  # Redis connection URI\n  uri: {{ get_env(name=\"REDIS_URL\", default=\"redis://127.0.0.1\") }}\n  # Dangerously flush all data in Redis on startup. dangerous operation, make sure that you using this flag only on dev environments or test mode\n  dangerously_flush: false\n\n# Authentication Configuration\nauth:\n  # JWT authentication\n  jwt:\n    # Secret key for token generation and verification\n    secret: pByQUgg4GmXKAqQQvAGo\n    # Token expiration time in seconds\n    expiration: 604800 # 7 days\n\n"
  },
  {
    "path": "examples/react_admin/backend/examples/playground.rs",
    "content": "use eyre::Context;\n#[allow(unused_imports)]\nuse loco_rs::{cli::playground, prelude::*};\nuse loco_seaography::app::App;\n\n#[tokio::main]\nasync fn main() -> eyre::Result<()> {\n    let _ctx = playground::<App>().await.context(\"playground\")?;\n\n    // let active_model: articles::ActiveModel = ActiveModel {\n    //     title: Set(Some(\"how to build apps in 3 steps\".to_string())),\n    //     content: Set(Some(\"use Loco: https://loco.rs\".to_string())),\n    //     ..Default::default()\n    // };\n    // active_model.insert(&ctx.db).await.unwrap();\n\n    // let res = articles::Entity::find().all(&ctx.db).await.unwrap();\n    // println!(\"{:?}\", res);\n    println!(\"welcome to playground. edit me at `examples/playground.rs`\");\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/react_admin/backend/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nloco-rs = { version = \"0.16\" }\ntokio   = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.\n    # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.\n    # e.g.\n    \"runtime-tokio-rustls\", # `ASYNC_RUNTIME` feature\n]\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/react_admin/backend/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Generate a new migration file\n    ```sh\n    cargo run -- migrate generate MIGRATION_NAME\n    ```\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/react_admin/backend/migration/src/lib.rs",
    "content": "#![allow(elided_lifetimes_in_paths)]\n#![allow(clippy::wildcard_imports)]\npub use sea_orm_migration::prelude::*;\n\nmod m20220101_000001_users;\nmod m20231103_114510_notes;\nmod m20240520_173001_files;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220101_000001_users::Migration),\n            Box::new(m20231103_114510_notes::Migration),\n            Box::new(m20240520_173001_files::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "examples/react_admin/backend/migration/src/m20220101_000001_users.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let table = table_auto(\"users\")\n            .col(pk_auto(\"id\"))\n            .col(uuid(\"pid\"))\n            .col(string_uniq(\"email\"))\n            .col(string(\"password\"))\n            .col(string(\"api_key\").unique_key())\n            .col(string(\"name\"))\n            .col(string_null(\"reset_token\"))\n            .col(timestamp_null(\"reset_sent_at\"))\n            .col(string_null(\"email_verification_token\"))\n            .col(timestamp_null(\"email_verification_sent_at\"))\n            .col(timestamp_null(\"email_verified_at\"))\n            .to_owned();\n        manager.create_table(table).await?;\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"users\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/react_admin/backend/migration/src/m20231103_114510_notes.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                table_auto(\"notes\")\n                    .col(pk_auto(\"id\"))\n                    .col(string_null(\"title\"))\n                    .col(string_null(\"content\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"notes\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/react_admin/backend/migration/src/m20240520_173001_files.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                table_auto(\"files\")\n                    .col(pk_auto(\"id\"))\n                    .col(integer(\"notes_id\"))\n                    .col(string(\"file_path\"))\n                    .foreign_key(\n                        ForeignKey::create()\n                            .name(\"FK_files_notes_id\")\n                            .from(\"files\", \"notes_id\")\n                            .to(\"notes\", \"id\"),\n                    )\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"files\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/react_admin/backend/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/app.rs",
    "content": "use std::path::Path;\n\nuse async_trait::async_trait;\nuse loco_rs::{\n    Result,\n    app::{AppContext, Hooks},\n    bgworker::{BackgroundWorker, Queue},\n    boot::{BootResult, StartMode, create_app},\n    config::Config,\n    controller::AppRoutes,\n    db::{self, truncate_table},\n    environment::Environment,\n    task::Tasks,\n};\nuse migration::Migrator;\n\nuse crate::{\n    controllers,\n    models::_entities::{notes, users},\n    tasks,\n    workers::downloader::DownloadWorker,\n};\n\npub struct App;\n#[async_trait]\nimpl Hooks for App {\n    fn app_name() -> &'static str {\n        env!(\"CARGO_CRATE_NAME\")\n    }\n\n    fn app_version() -> String {\n        format!(\n            \"{} ({})\",\n            env!(\"CARGO_PKG_VERSION\"),\n            option_env!(\"BUILD_SHA\")\n                .or(option_env!(\"GITHUB_SHA\"))\n                .unwrap_or(\"dev\")\n        )\n    }\n\n    async fn boot(\n        mode: StartMode,\n        environment: &Environment,\n        config: Config,\n    ) -> Result<BootResult> {\n        create_app::<Self, Migrator>(mode, environment, config).await\n    }\n\n    fn routes(_ctx: &AppContext) -> AppRoutes {\n        AppRoutes::with_default_routes()\n            .prefix(\"/api\")\n            .add_route(controllers::notes::routes())\n            .add_route(controllers::auth::routes())\n            .add_route(controllers::user::routes())\n            .add_route(controllers::files::routes())\n            .add_route(controllers::graphql::routes())\n    }\n\n    async fn connect_workers(ctx: &AppContext, queue: &Queue) -> Result<()> {\n        queue.register(DownloadWorker::build(ctx)).await?;\n        Ok(())\n    }\n\n    fn register_tasks(tasks: &mut Tasks) {\n        tasks.register(tasks::seed::SeedData);\n    }\n\n    async fn truncate(ctx: &AppContext) -> Result<()> {\n        let db = &ctx.db;\n        truncate_table(db, users::Entity).await?;\n        truncate_table(db, notes::Entity).await?;\n        Ok(())\n    }\n\n    async fn seed(ctx: &AppContext, base: &Path) -> Result<()> {\n        let db = &ctx.db;\n        db::seed::<users::ActiveModel>(db, &base.join(\"users.yaml\").display().to_string()).await?;\n        db::seed::<notes::ActiveModel>(db, &base.join(\"notes.yaml\").display().to_string()).await?;\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/bin/main.rs",
    "content": "use loco_rs::cli;\nuse loco_seaography::app::App;\nuse migration::Migrator;\n\n#[tokio::main]\nasync fn main() -> eyre::Result<()> {\n    cli::main::<App, Migrator>().await?;\n    Ok(())\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/controllers/auth.rs",
    "content": "use axum::debug_handler;\nuse loco_rs::prelude::*;\nuse serde::{Deserialize, Serialize};\n\nuse crate::{\n    mailers::auth::AuthMailer,\n    models::{\n        _entities::users,\n        users::{LoginParams, RegisterParams},\n    },\n    views::auth::LoginResponse,\n};\n#[derive(Debug, Deserialize, Serialize)]\npub struct VerifyParams {\n    pub token: String,\n}\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct ForgotParams {\n    pub email: String,\n}\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct ResetParams {\n    pub token: String,\n    pub password: String,\n}\n\n/// Register function creates a new user with the given parameters and sends a\n/// welcome email to the user\n#[debug_handler]\nasync fn register(\n    State(ctx): State<AppContext>,\n    Json(params): Json<RegisterParams>,\n) -> Result<Response> {\n    let res = users::Model::create_with_password(&ctx.db, &params).await;\n\n    let user = match res {\n        Ok(user) => user,\n        Err(err) => {\n            tracing::info!(\n                message = err.to_string(),\n                user_email = &params.email,\n                \"could not register user\",\n            );\n            return format::json(());\n        }\n    };\n\n    // Skip email verification, all new registrations are considered verified\n    let _user = user.into_active_model().verified(&ctx.db).await?;\n\n    // Skip sending verification email as we don't have a mail server\n    /*\n    let user = user\n        .into_active_model()\n        .set_email_verification_sent(&ctx.db)\n        .await?;\n\n    AuthMailer::send_welcome(&ctx, &user).await?;\n    */\n\n    format::json(())\n}\n\n/// Verify register user. if the user not verified his email, he can't login to\n/// the system.\n#[debug_handler]\nasync fn verify(\n    State(ctx): State<AppContext>,\n    Json(params): Json<VerifyParams>,\n) -> Result<Response> {\n    let user = users::Model::find_by_verification_token(&ctx.db, &params.token).await?;\n\n    if user.email_verified_at.is_some() {\n        tracing::info!(pid = user.pid.to_string(), \"user already verified\");\n    } else {\n        let active_model = user.into_active_model();\n        let user = active_model.verified(&ctx.db).await?;\n        tracing::info!(pid = user.pid.to_string(), \"user verified\");\n    }\n\n    format::json(())\n}\n\n/// In case the user forgot his password  this endpoints generate a forgot token\n/// and send email to the user. In case the email not found in our DB, we are\n/// returning a valid request for for security reasons (not exposing users DB\n/// list).\n#[debug_handler]\nasync fn forgot(\n    State(ctx): State<AppContext>,\n    Json(params): Json<ForgotParams>,\n) -> Result<Response> {\n    let Ok(user) = users::Model::find_by_email(&ctx.db, &params.email).await else {\n        // we don't want to expose our users email. if the email is invalid we still\n        // returning success to the caller\n        return format::json(());\n    };\n\n    let user = user\n        .into_active_model()\n        .set_forgot_password_sent(&ctx.db)\n        .await?;\n\n    AuthMailer::forgot_password(&ctx, &user).await?;\n\n    format::json(())\n}\n\n/// reset user password by the given parameters\n#[debug_handler]\nasync fn reset(State(ctx): State<AppContext>, Json(params): Json<ResetParams>) -> Result<Response> {\n    let Ok(user) = users::Model::find_by_reset_token(&ctx.db, &params.token).await else {\n        // we don't want to expose our users email. if the email is invalid we still\n        // returning success to the caller\n        tracing::info!(\"reset token not found\");\n\n        return format::json(());\n    };\n    user.into_active_model()\n        .reset_password(&ctx.db, &params.password)\n        .await?;\n\n    format::json(())\n}\n\n/// Creates a user login and returns a token\n#[debug_handler]\nasync fn login(State(ctx): State<AppContext>, Json(params): Json<LoginParams>) -> Result<Response> {\n    let user = users::Model::find_by_email(&ctx.db, &params.email).await?;\n\n    let valid = user.verify_password(&params.password);\n\n    if !valid {\n        return unauthorized(\"unauthorized!\");\n    }\n\n    let jwt_secret = ctx.config.get_jwt_config()?;\n\n    let token = user\n        .generate_jwt(&jwt_secret.secret, &jwt_secret.expiration)\n        .or_else(|_| unauthorized(\"unauthorized!\"))?;\n\n    format::json(LoginResponse::new(&user, &token))\n}\n\npub fn routes() -> Routes {\n    Routes::new()\n        .prefix(\"auth\")\n        .add(\"/register\", post(register))\n        .add(\"/verify\", post(verify))\n        .add(\"/login\", post(login))\n        .add(\"/forgot\", post(forgot))\n        .add(\"/reset\", post(reset))\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/controllers/files.rs",
    "content": "#![allow(clippy::missing_errors_doc)]\n#![allow(clippy::unnecessary_struct_initialization)]\n#![allow(clippy::unused_async)]\nuse std::path::PathBuf;\n\nuse axum::{body::Body, debug_handler, extract::Multipart};\nuse loco_rs::prelude::*;\nuse sea_orm::QueryOrder;\nuse tokio::{fs, io::AsyncWriteExt};\nuse tokio_util::io::ReaderStream;\n\nuse crate::models::_entities::files;\n\nconst UPLOAD_DIR: &str = \"./uploads\";\n\n#[debug_handler]\npub async fn upload(\n    _auth: auth::JWT,\n    Path(notes_id): Path<i32>,\n    State(ctx): State<AppContext>,\n    mut multipart: Multipart,\n) -> Result<Response> {\n    // Collect all uploaded files\n    let mut files = Vec::new();\n\n    // Iterate all files in the POST body\n    while let Some(field) = multipart.next_field().await.map_err(|err| {\n        tracing::error!(error = ?err,\"could not readd multipart\");\n        Error::BadRequest(\"could not readd multipart\".into())\n    })? {\n        // Get the file name\n        let file_name = match field.file_name() {\n            Some(file_name) => file_name.to_string(),\n            _ => return Err(Error::BadRequest(\"file name not found\".into())),\n        };\n\n        // Get the file content as bytes\n        let content = field.bytes().await.map_err(|err| {\n            tracing::error!(error = ?err,\"could not readd bytes\");\n            Error::BadRequest(\"could not readd bytes\".into())\n        })?;\n\n        // Create a folder to store the uploaded file\n        let now = chrono::offset::Local::now()\n            .format(\"%Y%m%d_%H%M%S\")\n            .to_string();\n        let uuid = uuid::Uuid::new_v4().to_string();\n        let folder = format!(\"{now}_{uuid}\");\n        let upload_folder = PathBuf::from(UPLOAD_DIR).join(&folder);\n        fs::create_dir_all(&upload_folder).await?;\n\n        // Write the file into the newly created folder\n        let path = upload_folder.join(file_name);\n        let mut f = fs::OpenOptions::new()\n            .create_new(true)\n            .write(true)\n            .open(&path)\n            .await?;\n        f.write_all(&content).await?;\n        f.flush().await?;\n\n        // Record the file upload in database\n        let file = files::ActiveModel {\n            notes_id: ActiveValue::Set(notes_id),\n            file_path: ActiveValue::Set(\n                path.strip_prefix(UPLOAD_DIR)\n                    .unwrap()\n                    .to_str()\n                    .unwrap()\n                    .to_string(),\n            ),\n            ..Default::default()\n        }\n        .insert(&ctx.db)\n        .await?;\n\n        files.push(file);\n    }\n\n    format::json(files)\n}\n\n#[debug_handler]\npub async fn list(\n    _auth: auth::JWT,\n    Path(notes_id): Path<i32>,\n    State(ctx): State<AppContext>,\n) -> Result<Response> {\n    // Fetch all files uploaded for a specific notes\n    let files = files::Entity::find()\n        .filter(files::Column::NotesId.eq(notes_id))\n        .order_by_asc(files::Column::Id)\n        .all(&ctx.db)\n        .await?;\n\n    format::json(files)\n}\n\n#[debug_handler]\npub async fn view(\n    _auth: auth::JWT,\n    Path(files_id): Path<i32>,\n    State(ctx): State<AppContext>,\n) -> Result<Response> {\n    // Fetch the file info from database\n    let file = files::Entity::find_by_id(files_id)\n        .one(&ctx.db)\n        .await?\n        .expect(\"File not found\");\n\n    // Stream the file\n    let file = fs::File::open(format!(\"{UPLOAD_DIR}/{}\", file.file_path)).await?;\n    let stream = ReaderStream::new(file);\n    let body = Body::from_stream(stream);\n\n    Ok(format::render().response().body(body)?)\n}\n\npub fn routes() -> Routes {\n    // Bind the routes\n    Routes::new()\n        .prefix(\"files\")\n        .add(\"/upload/{notes_id}\", post(upload))\n        .add(\"/list/{notes_id}\", get(list))\n        .add(\"/view/{files_id}\", get(view))\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/controllers/graphql.rs",
    "content": "use async_graphql::http::{GraphQLPlaygroundConfig, playground_source};\nuse axum::{body::Body, extract::Request};\nuse loco_rs::prelude::*;\nuse tower_service::Service;\n\nuse crate::graphql::query_root;\n\n// GraphQL playground UI\nasync fn graphql_playground() -> Result<Response> {\n    // The `GraphQLPlaygroundConfig` take one parameter\n    // which is the URL of the GraphQL handler: `/api/graphql`\n    let res = playground_source(GraphQLPlaygroundConfig::new(\"/api/graphql\"));\n\n    Ok(Response::new(res.into()))\n}\n\nasync fn graphql_handler(State(ctx): State<AppContext>, req: Request<Body>) -> Result<Response> {\n    const DEPTH: usize = 1_000;\n    const COMPLEXITY: usize = 1_000;\n    // Construct the the GraphQL query root\n    let schema = query_root::schema(ctx.db.clone(), DEPTH, COMPLEXITY).unwrap();\n    // GraphQL handler\n    let mut graphql_handler = async_graphql_axum::GraphQL::new(schema);\n    // Execute GraphQL request and fetch the results\n    let res = graphql_handler.call(req).await.unwrap();\n\n    Ok(res)\n}\n\npub fn routes() -> Routes {\n    // Define route\n    Routes::new()\n        // We put all GraphQL route behind `graphql` prefix\n        .prefix(\"graphql\")\n        // GraphQL playground page is a GET request\n        .add(\"/\", get(graphql_playground))\n        // GraphQL handler is a POST request\n        .add(\"/\", post(graphql_handler))\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/controllers/mod.rs",
    "content": "pub mod auth;\npub mod files;\npub mod graphql;\npub mod notes;\npub mod user;\n"
  },
  {
    "path": "examples/react_admin/backend/src/controllers/notes.rs",
    "content": "#![allow(clippy::missing_errors_doc)]\n#![allow(clippy::unnecessary_struct_initialization)]\n#![allow(clippy::unused_async)]\nuse axum::debug_handler;\nuse loco_rs::prelude::*;\nuse serde::{Deserialize, Serialize};\n\nuse crate::models::_entities::notes::{ActiveModel, Entity, Model};\n\n#[derive(Clone, Debug, Serialize, Deserialize)]\npub struct Params {\n    pub title: Option<String>,\n    pub content: Option<String>,\n}\n\nimpl Params {\n    fn update(&self, item: &mut ActiveModel) {\n        item.title = Set(self.title.clone());\n        item.content = Set(self.content.clone());\n    }\n}\n\nasync fn load_item(ctx: &AppContext, id: i32) -> Result<Model> {\n    let item = Entity::find_by_id(id).one(&ctx.db).await?;\n    item.ok_or_else(|| Error::NotFound)\n}\n\n#[debug_handler]\npub async fn list(State(ctx): State<AppContext>) -> Result<Response> {\n    format::json(Entity::find().all(&ctx.db).await?)\n}\n\n#[debug_handler]\npub async fn add(State(ctx): State<AppContext>, Json(params): Json<Params>) -> Result<Response> {\n    let mut item = ActiveModel {\n        ..Default::default()\n    };\n    params.update(&mut item);\n    let item = item.insert(&ctx.db).await?;\n    format::json(item)\n}\n\n#[debug_handler]\npub async fn update(\n    Path(id): Path<i32>,\n    State(ctx): State<AppContext>,\n    Json(params): Json<Params>,\n) -> Result<Response> {\n    let item = load_item(&ctx, id).await?;\n    let mut item = item.into_active_model();\n    params.update(&mut item);\n    let item = item.update(&ctx.db).await?;\n    format::json(item)\n}\n\n#[debug_handler]\npub async fn remove(Path(id): Path<i32>, State(ctx): State<AppContext>) -> Result<Response> {\n    load_item(&ctx, id).await?.delete(&ctx.db).await?;\n    format::empty()\n}\n\n#[debug_handler]\npub async fn get_one(Path(id): Path<i32>, State(ctx): State<AppContext>) -> Result<Response> {\n    format::json(load_item(&ctx, id).await?)\n}\n\npub fn routes() -> Routes {\n    Routes::new()\n        .prefix(\"notes\")\n        .add(\"/\", get(list))\n        .add(\"/\", post(add))\n        .add(\"/{id}\", get(get_one))\n        .add(\"/{id}\", delete(remove))\n        .add(\"/{id}\", post(update))\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/controllers/user.rs",
    "content": "use axum::debug_handler;\nuse loco_rs::prelude::*;\n\nuse crate::{models::_entities::users, views::user::CurrentResponse};\n\n#[debug_handler]\nasync fn current(auth: auth::JWT, State(ctx): State<AppContext>) -> Result<Response> {\n    let user = users::Model::find_by_pid(&ctx.db, &auth.claims.pid).await?;\n    format::json(CurrentResponse::new(&user))\n}\n\npub fn routes() -> Routes {\n    Routes::new().prefix(\"user\").add(\"/current\", get(current))\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/fixtures/notes.yaml",
    "content": "---\n- id: 1\n  title: Loco note 1\n  content: Loco note 1 content\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n- id: 2\n  title: Loco note 2\n  content: Loco note 2 content\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n"
  },
  {
    "path": "examples/react_admin/backend/src/fixtures/users.yaml",
    "content": "---\n- id: 1\n  pid: 11111111-1111-1111-1111-111111111111\n  email: user1@example.com\n  password: \"$argon2id$v=19$m=19456,t=2,p=1$ETQBx4rTgNAZhSaeYZKOZg$eYTdH26CRT6nUJtacLDEboP0li6xUwUF/q5nSlQ8uuc\"\n  api_key: lo-95ec80d7-cb60-4b70-9b4b-9ef74cb88758\n  name: user1\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n- id: 2\n  pid: 22222222-2222-2222-2222-222222222222\n  email: user2@example.com\n  password: \"$argon2id$v=19$m=19456,t=2,p=1$ETQBx4rTgNAZhSaeYZKOZg$eYTdH26CRT6nUJtacLDEboP0li6xUwUF/q5nSlQ8uuc\"\n  api_key: lo-153561ca-fa84-4e1b-813a-c62526d0a77e\n  name: user2\n  created_at: \"2023-11-12T12:34:56.789\"\n  updated_at: \"2023-11-12T12:34:56.789\"\n"
  },
  {
    "path": "examples/react_admin/backend/src/graphql/mod.rs",
    "content": "pub mod query_root;\n"
  },
  {
    "path": "examples/react_admin/backend/src/graphql/query_root.rs",
    "content": "use async_graphql::dynamic::*;\nuse sea_orm::DatabaseConnection;\nuse seaography::{Builder, BuilderContext};\n\nlazy_static::lazy_static! { static ref CONTEXT: BuilderContext = BuilderContext::default(); }\n\npub fn schema(\n    database: DatabaseConnection,\n    depth: usize,\n    complexity: usize,\n) -> Result<Schema, SchemaError> {\n    // Builder of Seaography query root\n    let builder = Builder::new(&CONTEXT, database.clone());\n    // Register SeaORM entities\n    let builder = crate::models::_entities::register_entity_modules(builder);\n    // Configure async GraphQL limits\n    let schema = builder\n        .schema_builder()\n        // The depth is the number of nesting levels of the field\n        .limit_depth(depth)\n        // The complexity is the number of fields in the query\n        .limit_complexity(complexity);\n    // Finish up with including SeaORM database connection\n    schema.data(database).finish()\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/lib.rs",
    "content": "pub mod app;\npub mod controllers;\npub mod graphql;\npub mod mailers;\npub mod models;\npub mod tasks;\npub mod views;\npub mod workers;\n"
  },
  {
    "path": "examples/react_admin/backend/src/mailers/auth/forgot/html.t",
    "content": ";<html>\n\n<body>\n  Hey {{name}},\n  Forgot your password? No worries! You can reset it by clicking the link below:\n  <a href=\"http://{{domain}}/reset#{{resetToken}}\">Reset Your Password</a>\n  If you didn't request a password reset, please ignore this email.\n  Best regards,<br>The Loco Team</br>\n</body>\n\n</html>\n"
  },
  {
    "path": "examples/react_admin/backend/src/mailers/auth/forgot/subject.t",
    "content": "Your reset password link\n"
  },
  {
    "path": "examples/react_admin/backend/src/mailers/auth/forgot/text.t",
    "content": "Reset your password with this link:\n\nhttp://localhost/reset#{{resetToken}}\n"
  },
  {
    "path": "examples/react_admin/backend/src/mailers/auth/welcome/html.t",
    "content": ";<html>\n\n<body>\n  Dear {{name}},\n  Welcome to Loco! You can now log in to your account.\n  Before you get started, please verify your account by clicking the link below:\n  <a href=\"http://{{domain}}/verify#{{verifyToken}}\">\n    Verify Your Account\n  </a>\n  <p>Best regards,<br>The Loco Team</p>\n</body>\n\n</html>\n"
  },
  {
    "path": "examples/react_admin/backend/src/mailers/auth/welcome/subject.t",
    "content": "Welcome {{name}}\n"
  },
  {
    "path": "examples/react_admin/backend/src/mailers/auth/welcome/text.t",
    "content": "Welcome {{name}}, you can now log in.\n  Verify your account with the link below:\n\n  http://localhost/verify#{{verifyToken}}\n"
  },
  {
    "path": "examples/react_admin/backend/src/mailers/auth.rs",
    "content": "// auth mailer\n#![allow(non_upper_case_globals)]\n\nuse loco_rs::prelude::*;\nuse serde_json::json;\n\nuse crate::models::users;\n\nstatic welcome: Dir<'_> = include_dir!(\"src/mailers/auth/welcome\");\nstatic forgot: Dir<'_> = include_dir!(\"src/mailers/auth/forgot\");\n// #[derive(Mailer)] // -- disabled for faster build speed. it works. but lets\n// move on for now.\n\n#[allow(clippy::module_name_repetitions)]\npub struct AuthMailer {}\nimpl Mailer for AuthMailer {}\nimpl AuthMailer {\n    /// Sending welcome email the the given user\n    ///\n    /// # Errors\n    ///\n    /// When email sending is failed\n    pub async fn send_welcome(ctx: &AppContext, user: &users::Model) -> Result<()> {\n        Self::mail_template(\n            ctx,\n            &welcome,\n            mailer::Args {\n                to: user.email.to_string(),\n                locals: json!({\n                  \"name\": user.name,\n                  \"verifyToken\": user.email_verification_token,\n                  \"domain\": ctx.config.server.full_url()\n                }),\n                ..Default::default()\n            },\n        )\n        .await?;\n\n        Ok(())\n    }\n\n    /// Sending forgot password email\n    ///\n    /// # Errors\n    ///\n    /// When email sending is failed\n    pub async fn forgot_password(ctx: &AppContext, user: &users::Model) -> Result<()> {\n        Self::mail_template(\n            ctx,\n            &forgot,\n            mailer::Args {\n                to: user.email.to_string(),\n                locals: json!({\n                  \"name\": user.name,\n                  \"resetToken\": user.reset_token,\n                  \"domain\": ctx.config.server.full_url()\n                }),\n                ..Default::default()\n            },\n        )\n        .await?;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/mailers/mod.rs",
    "content": "pub mod auth;\n"
  },
  {
    "path": "examples/react_admin/backend/src/models/_entities/files.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.10\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"files\")]\npub struct Model {\n    pub created_at: DateTime,\n    pub updated_at: DateTime,\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub notes_id: i32,\n    pub file_path: String,\n    #[sea_orm(belongs_to, from = \"notes_id\", to = \"id\")]\n    pub notes: HasOne<super::notes::Entity>,\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/models/_entities/mod.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.0-rc.5\n\npub mod prelude;\n\npub mod files;\npub mod notes;\npub mod users;\n\nseaography::register_entity_modules!([files, notes, users]);\n"
  },
  {
    "path": "examples/react_admin/backend/src/models/_entities/notes.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.10\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"notes\")]\npub struct Model {\n    pub created_at: DateTime,\n    pub updated_at: DateTime,\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub title: Option<String>,\n    pub content: Option<String>,\n    #[sea_orm(has_many)]\n    pub files: HasMany<super::files::Entity>,\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/models/_entities/prelude.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.0-rc.5\n\npub use super::{files::Entity as Files, notes::Entity as Notes, users::Entity as Users};\n"
  },
  {
    "path": "examples/react_admin/backend/src/models/_entities/users.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 1.0.0-rc.5\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"users\")]\npub struct Model {\n    pub created_at: DateTime,\n    pub updated_at: DateTime,\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub pid: Uuid,\n    #[sea_orm(unique)]\n    pub email: String,\n    pub password: String,\n    #[sea_orm(unique)]\n    pub api_key: String,\n    pub name: String,\n    pub reset_token: Option<String>,\n    pub reset_sent_at: Option<DateTime>,\n    pub email_verification_token: Option<String>,\n    pub email_verification_sent_at: Option<DateTime>,\n    pub email_verified_at: Option<DateTime>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]\npub enum RelatedEntity {}\n"
  },
  {
    "path": "examples/react_admin/backend/src/models/files.rs",
    "content": "use sea_orm::entity::prelude::*;\n\nuse super::_entities::files::ActiveModel;\n\nimpl ActiveModelBehavior for ActiveModel {\n    // extend activemodel below (keep comment for generators)\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/models/mod.rs",
    "content": "pub mod _entities;\npub mod files;\npub mod notes;\npub mod users;\n"
  },
  {
    "path": "examples/react_admin/backend/src/models/notes.rs",
    "content": "use sea_orm::entity::prelude::*;\n\nuse super::_entities::notes::ActiveModel;\n\nimpl ActiveModelBehavior for ActiveModel {\n    // extend activemodel below (keep comment for generators)\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/models/users.rs",
    "content": "use async_trait::async_trait;\nuse chrono::offset::Local;\nuse loco_rs::{auth::jwt, hash, prelude::*};\nuse serde::{Deserialize, Serialize};\nuse uuid::Uuid;\n\npub use super::_entities::users::{self, ActiveModel, Entity, Model};\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct LoginParams {\n    pub email: String,\n    pub password: String,\n}\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct RegisterParams {\n    pub email: String,\n    pub password: String,\n    pub name: String,\n}\n\n#[derive(Debug, Validate, Deserialize)]\npub struct Validator {\n    #[validate(length(min = 2, message = \"Name must be at least 2 characters long.\"))]\n    pub name: String,\n    #[validate(email(message = \"invalid email\"))]\n    pub email: String,\n}\n\nimpl Validatable for super::_entities::users::ActiveModel {\n    fn validator(&self) -> Box<dyn Validate> {\n        Box::new(Validator {\n            name: self.name.as_ref().to_owned(),\n            email: self.email.as_ref().to_owned(),\n        })\n    }\n}\n\n#[async_trait::async_trait]\nimpl ActiveModelBehavior for super::_entities::users::ActiveModel {\n    async fn before_save<C>(self, _db: &C, insert: bool) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.validate()?;\n        if insert {\n            let mut this = self;\n            this.pid = ActiveValue::Set(Uuid::new_v4());\n            this.api_key = ActiveValue::Set(format!(\"lo-{}\", Uuid::new_v4()));\n            Ok(this)\n        } else {\n            Ok(self)\n        }\n    }\n}\n\n#[async_trait]\nimpl Authenticable for super::_entities::users::Model {\n    async fn find_by_api_key(db: &DatabaseConnection, api_key: &str) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::ApiKey.eq(api_key))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    async fn find_by_claims_key(db: &DatabaseConnection, claims_key: &str) -> ModelResult<Self> {\n        Self::find_by_pid(db, claims_key).await\n    }\n}\n\nimpl super::_entities::users::Model {\n    /// finds a user by the provided email\n    ///\n    /// # Errors\n    ///\n    /// When could not find user by the given token or DB query error\n    pub async fn find_by_email(db: &DatabaseConnection, email: &str) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::Email.eq(email))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// finds a user by the provided verification token\n    ///\n    /// # Errors\n    ///\n    /// When could not find user by the given token or DB query error\n    pub async fn find_by_verification_token(\n        db: &DatabaseConnection,\n        token: &str,\n    ) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::EmailVerificationToken.eq(token))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// /// finds a user by the provided reset token\n    ///\n    /// # Errors\n    ///\n    /// When could not find user by the given token or DB query error\n    pub async fn find_by_reset_token(db: &DatabaseConnection, token: &str) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::ResetToken.eq(token))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// finds a user by the provided pid\n    ///\n    /// # Errors\n    ///\n    /// When could not find user  or DB query error\n    pub async fn find_by_pid(db: &DatabaseConnection, pid: &str) -> ModelResult<Self> {\n        let parse_uuid = Uuid::parse_str(pid).map_err(|e| ModelError::Any(e.into()))?;\n        let user = users::Entity::find()\n            .filter(users::Column::Pid.eq(parse_uuid))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// finds a user by the provided api key\n    ///\n    /// # Errors\n    ///\n    /// When could not find user by the given token or DB query error\n    pub async fn find_by_api_key(db: &DatabaseConnection, api_key: &str) -> ModelResult<Self> {\n        let user = users::Entity::find()\n            .filter(users::Column::ApiKey.eq(api_key))\n            .one(db)\n            .await?;\n        user.ok_or_else(|| ModelError::EntityNotFound)\n    }\n\n    /// Verifies whether the provided plain password matches the hashed password\n    ///\n    /// # Errors\n    ///\n    /// when could not verify password\n    #[must_use]\n    pub fn verify_password(&self, password: &str) -> bool {\n        hash::verify_password(password, &self.password)\n    }\n\n    /// Asynchronously creates a user with a password and saves it to the\n    /// database.\n    ///\n    /// # Errors\n    ///\n    /// When could not save the user into the DB\n    pub async fn create_with_password(\n        db: &DatabaseConnection,\n        params: &RegisterParams,\n    ) -> ModelResult<Self> {\n        let txn = db.begin().await?;\n\n        if users::Entity::find()\n            .filter(users::Column::Email.eq(&params.email))\n            .one(&txn)\n            .await?\n            .is_some()\n        {\n            return Err(ModelError::EntityAlreadyExists {});\n        }\n\n        let password_hash =\n            hash::hash_password(&params.password).map_err(|e| ModelError::Any(e.into()))?;\n        let user = users::ActiveModel {\n            email: ActiveValue::set(params.email.to_string()),\n            password: ActiveValue::set(password_hash),\n            name: ActiveValue::set(params.name.to_string()),\n            ..Default::default()\n        }\n        .insert(&txn)\n        .await?;\n\n        txn.commit().await?;\n\n        Ok(user)\n    }\n\n    /// Creates a JWT\n    ///\n    /// # Errors\n    ///\n    /// when could not convert user claims to jwt token\n    pub fn generate_jwt(&self, secret: &str, expiration: &u64) -> ModelResult<String> {\n        Ok(jwt::JWT::new(secret).generate_token(\n            *expiration,\n            self.pid.to_string(),\n            Default::default(),\n        )?)\n    }\n}\n\nimpl super::_entities::users::ActiveModel {\n    /// Sets the email verification information for the user and\n    /// updates it in the database.\n    ///\n    /// This method is used to record the timestamp when the email verification\n    /// was sent and generate a unique verification token for the user.\n    ///\n    /// # Errors\n    ///\n    /// when has DB query error\n    pub async fn set_email_verification_sent(\n        mut self,\n        db: &DatabaseConnection,\n    ) -> ModelResult<Model> {\n        self.email_verification_sent_at = ActiveValue::set(Some(Local::now().naive_local()));\n        self.email_verification_token = ActiveValue::Set(Some(Uuid::new_v4().to_string()));\n        Ok(self.update(db).await?)\n    }\n\n    /// Sets the information for a reset password request,\n    /// generates a unique reset password token, and updates it in the\n    /// database.\n    ///\n    /// This method records the timestamp when the reset password token is sent\n    /// and generates a unique token for the user.\n    ///\n    /// # Arguments\n    ///\n    /// # Errors\n    ///\n    /// when has DB query error\n    pub async fn set_forgot_password_sent(mut self, db: &DatabaseConnection) -> ModelResult<Model> {\n        self.reset_sent_at = ActiveValue::set(Some(Local::now().naive_local()));\n        self.reset_token = ActiveValue::Set(Some(Uuid::new_v4().to_string()));\n        Ok(self.update(db).await?)\n    }\n\n    /// Records the verification time when a user verifies their\n    /// email and updates it in the database.\n    ///\n    /// This method sets the timestamp when the user successfully verifies their\n    /// email.\n    ///\n    /// # Errors\n    ///\n    /// when has DB query error\n    pub async fn verified(mut self, db: &DatabaseConnection) -> ModelResult<Model> {\n        self.email_verified_at = ActiveValue::set(Some(Local::now().naive_local()));\n        Ok(self.update(db).await?)\n    }\n\n    /// Resets the current user password with a new password and\n    /// updates it in the database.\n    ///\n    /// This method hashes the provided password and sets it as the new password\n    /// for the user.    \n    /// # Errors\n    ///\n    /// when has DB query error or could not hashed the given password\n    pub async fn reset_password(\n        mut self,\n        db: &DatabaseConnection,\n        password: &str,\n    ) -> ModelResult<Model> {\n        self.password =\n            ActiveValue::set(hash::hash_password(password).map_err(|e| ModelError::Any(e.into()))?);\n        Ok(self.update(db).await?)\n    }\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/tasks/mod.rs",
    "content": "pub mod seed;\n"
  },
  {
    "path": "examples/react_admin/backend/src/tasks/seed.rs",
    "content": "//! This task implements data seeding functionality for initializing new\n//! development/demo environments.\n//!\n//! # Example\n//!\n//! Run the task with the following command:\n//! ```sh\n//! cargo run task\n//! ```\n//!\n//! To override existing data and reset the data structure, use the following\n//! command with the `refresh:true` argument:\n//! ```sh\n//! cargo run task seed_data refresh:true\n//! ```\n\nuse loco_rs::{db, prelude::*};\nuse migration::Migrator;\n\nuse crate::app::App;\n\n#[allow(clippy::module_name_repetitions)]\npub struct SeedData;\n#[async_trait]\nimpl Task for SeedData {\n    fn task(&self) -> TaskInfo {\n        TaskInfo {\n            name: \"seed_data\".to_string(),\n            detail: \"Task for seeding data\".to_string(),\n        }\n    }\n\n    async fn run(&self, app_context: &AppContext, vars: &task::Vars) -> Result<()> {\n        let refresh = vars\n            .cli_arg(\"refresh\")\n            .is_ok_and(|refresh| refresh == \"true\");\n\n        if refresh {\n            db::reset::<Migrator>(&app_context.db).await?;\n        }\n        let path = std::path::Path::new(\"src/fixtures\");\n        db::run_app_seed::<App>(app_context, path).await?;\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/views/auth.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::models::_entities::users;\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct LoginResponse {\n    pub token: String,\n    pub pid: String,\n    pub name: String,\n    pub is_verified: bool,\n}\n\nimpl LoginResponse {\n    #[must_use]\n    pub fn new(user: &users::Model, token: &String) -> Self {\n        Self {\n            token: token.to_string(),\n            pid: user.pid.to_string(),\n            name: user.name.clone(),\n            is_verified: user.email_verified_at.is_some(),\n        }\n    }\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/views/mod.rs",
    "content": "pub mod auth;\npub mod user;\n"
  },
  {
    "path": "examples/react_admin/backend/src/views/user.rs",
    "content": "use serde::{Deserialize, Serialize};\n\nuse crate::models::_entities::users;\n\n#[derive(Debug, Deserialize, Serialize)]\npub struct CurrentResponse {\n    pub pid: String,\n    pub name: String,\n    pub email: String,\n}\n\nimpl CurrentResponse {\n    #[must_use]\n    pub fn new(user: &users::Model) -> Self {\n        Self {\n            pid: user.pid.to_string(),\n            name: user.name.clone(),\n            email: user.email.clone(),\n        }\n    }\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/workers/downloader.rs",
    "content": "use std::time::Duration;\n\nuse loco_rs::prelude::*;\nuse serde::{Deserialize, Serialize};\nuse tokio::time::sleep;\n\nuse crate::models::users;\n\npub struct DownloadWorker {\n    pub ctx: AppContext,\n}\n\n#[derive(Deserialize, Debug, Serialize)]\npub struct DownloadWorkerArgs {\n    pub user_guid: String,\n}\n\n#[async_trait]\nimpl BackgroundWorker<DownloadWorkerArgs> for DownloadWorker {\n    fn build(ctx: &AppContext) -> Self {\n        Self { ctx: ctx.clone() }\n    }\n\n    async fn perform(&self, args: DownloadWorkerArgs) -> Result<()> {\n        // TODO: Some actual work goes here...\n        println!(\"================================================\");\n        println!(\"Sending payment report to user {}\", args.user_guid);\n\n        sleep(Duration::from_millis(2000)).await;\n\n        let all = users::Entity::find()\n            .all(&self.ctx.db)\n            .await\n            .map_err(Box::from)?;\n        for user in &all {\n            println!(\"user: {}\", user.id);\n        }\n        println!(\"================================================\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/react_admin/backend/src/workers/mod.rs",
    "content": "pub mod downloader;\n"
  },
  {
    "path": "examples/react_admin/frontend/.eslintrc.js",
    "content": "export default {\n    \"extends\": [\n        \"eslint:recommended\",\n        \"plugin:react/recommended\",\n        \"plugin:react/jsx-runtime\",\n        \"plugin:react-hooks/recommended\",\n        \"prettier\"\n    ],\n    \"parser\": \"@typescript-eslint/parser\",\n    \"plugins\": [\"@typescript-eslint\"],\n    \"env\": {\n        \"browser\": true,\n        \"es2021\": true,\n        \"node\": true\n    },\n    \"settings\": {\n        \"react\": {\n            \"version\": \"detect\"\n        }\n    }\n}\n"
  },
  {
    "path": "examples/react_admin/frontend/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\ndist\ndist-ssr\n*.local\n\n# Editor directories and files\n.vscode/*\n!.vscode/extensions.json\n.idea\n.DS_Store\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n"
  },
  {
    "path": "examples/react_admin/frontend/README.md",
    "content": "# react-admin\n\n## Installation\n\nInstall the application dependencies by running:\n\n```sh\nnpm install\n```\n\n## Development\n\nStart the application in development mode by running:\n\n```sh\nnpm run dev\n```\n\n## Production\n\nBuild the application in production mode by running:\n\n```sh\nnpm run build\n```\n\n## Authentication\n\nThe included auth provider should only be used for development and test purposes.\nYou'll find a `users.json` file in the `src` directory that includes the users you can use.\n\nYou can sign in to the application with the following usernames and password:\n- janedoe / password\n- johndoe / password\n\n"
  },
  {
    "path": "examples/react_admin/frontend/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"utf-8\" />\n        <meta\n            name=\"viewport\"\n            content=\"minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no\"\n        />\n        <meta name=\"theme-color\" content=\"#000000\" />\n        <link rel=\"manifest\" href=\"./manifest.json\" />\n        <link rel=\"shortcut icon\" href=\"./favicon.ico\" />\n        <title>react-admin</title>\n        <style>\n            body {\n                margin: 0;\n                padding: 0;\n                font-family: sans-serif;\n            }\n\n            .loader-container {\n                display: flex;\n                align-items: center;\n                justify-content: center;\n                flex-direction: column;\n                position: absolute;\n                top: 0;\n                bottom: 0;\n                left: 0;\n                right: 0;\n                background-color: #fafafa;\n            }\n\n            /* CSS Spinner from https://projects.lukehaas.me/css-loaders/ */\n\n            .loader,\n            .loader:before,\n            .loader:after {\n                border-radius: 50%;\n            }\n\n            .loader {\n                color: #283593;\n                font-size: 11px;\n                text-indent: -99999em;\n                margin: 55px auto;\n                position: relative;\n                width: 10em;\n                height: 10em;\n                box-shadow: inset 0 0 0 1em;\n                -webkit-transform: translateZ(0);\n                -ms-transform: translateZ(0);\n                transform: translateZ(0);\n            }\n\n            .loader:before,\n            .loader:after {\n                position: absolute;\n                content: '';\n            }\n\n            .loader:before {\n                width: 5.2em;\n                height: 10.2em;\n                background: #fafafa;\n                border-radius: 10.2em 0 0 10.2em;\n                top: -0.1em;\n                left: -0.1em;\n                -webkit-transform-origin: 5.2em 5.1em;\n                transform-origin: 5.2em 5.1em;\n                -webkit-animation: load2 2s infinite ease 1.5s;\n                animation: load2 2s infinite ease 1.5s;\n            }\n\n            .loader:after {\n                width: 5.2em;\n                height: 10.2em;\n                background: #fafafa;\n                border-radius: 0 10.2em 10.2em 0;\n                top: -0.1em;\n                left: 5.1em;\n                -webkit-transform-origin: 0px 5.1em;\n                transform-origin: 0px 5.1em;\n                -webkit-animation: load2 2s infinite ease;\n                animation: load2 2s infinite ease;\n            }\n\n            @-webkit-keyframes load2 {\n                0% {\n                    -webkit-transform: rotate(0deg);\n                    transform: rotate(0deg);\n                }\n                100% {\n                    -webkit-transform: rotate(360deg);\n                    transform: rotate(360deg);\n                }\n            }\n\n            @keyframes load2 {\n                0% {\n                    -webkit-transform: rotate(0deg);\n                    transform: rotate(0deg);\n                }\n                100% {\n                    -webkit-transform: rotate(360deg);\n                    transform: rotate(360deg);\n                }\n            }\n        </style>\n        <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" />\n        <link\n            href=\"https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap\"\n            rel=\"stylesheet\"\n        />\n    </head>\n\n    <body>\n        <noscript> You need to enable JavaScript to run this app. </noscript>\n        <div id=\"root\">\n            <div class=\"loader-container\">\n                <div class=\"loader\">Loading...</div>\n            </div>\n        </div>\n    </body>\n    <script type=\"module\" src=\"/src/index.tsx\"></script>\n</html>\n"
  },
  {
    "path": "examples/react_admin/frontend/package.json",
    "content": "{\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"serve\": \"vite preview\",\n    \"type-check\": \"tsc --noEmit\",\n    \"lint\": \"eslint --fix --ext .js,.jsx,.ts,.tsx ./src\",\n    \"format\": \"prettier --write ./src\"\n  },\n  \"dependencies\": {\n    \"axios\": \"^1.7.2\",\n    \"ra-data-json-server\": \"^5.0.5\",\n    \"react\": \"^18.3.0\",\n    \"react-admin\": \"^5.0.0\",\n    \"react-dom\": \"^18.3.0\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^20.10.7\",\n    \"@types/react\": \"^18.3.3\",\n    \"@types/react-dom\": \"^18.3.0\",\n    \"@typescript-eslint/eslint-plugin\": \"^5.60.1\",\n    \"@typescript-eslint/parser\": \"^5.60.1\",\n    \"@vitejs/plugin-react\": \"^4.0.1\",\n    \"eslint\": \"^8.43.0\",\n    \"eslint-config-prettier\": \"^8.8.0\",\n    \"eslint-plugin-react\": \"^7.32.2\",\n    \"eslint-plugin-react-hooks\": \"^4.6.0\",\n    \"prettier\": \"^2.8.8\",\n    \"typescript\": \"^5.1.6\",\n    \"vite\": \"^4.3.9\"\n  },\n  \"name\": \"react-admin\"\n}\n"
  },
  {
    "path": "examples/react_admin/frontend/prettier.config.js",
    "content": "module.exports = {}"
  },
  {
    "path": "examples/react_admin/frontend/public/manifest.json",
    "content": "{\n    \"short_name\": \"react-admin\",\n    \"name\": \"{{name}}\",\n    \"icons\": [\n        {\n            \"src\": \"favicon.ico\",\n            \"sizes\": \"64x64 32x32 24x24 16x16\",\n            \"type\": \"image/x-icon\"\n        }\n    ],\n    \"start_url\": \"./index.html\",\n    \"display\": \"standalone\",\n    \"theme_color\": \"#000000\",\n    \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "examples/react_admin/frontend/src/App.tsx",
    "content": "import { Admin } from 'react-admin';\nimport { Layout } from './Layout';\nimport { authProvider } from './authProvider';\n\n\nexport const App = () => (\n    <Admin\n        layout={Layout}\n        \tauthProvider={authProvider}\n\t>\n        \n    </Admin>\n);\n\n    "
  },
  {
    "path": "examples/react_admin/frontend/src/Layout.tsx",
    "content": "import type { ReactNode } from 'react';\nimport {\n  Layout as RALayout,\n  CheckForApplicationUpdate,\n} from \"react-admin\";\n\nexport const Layout = ({ children }: { children: ReactNode }) => (\n  <RALayout>\n    {children}\n    <CheckForApplicationUpdate />\n  </RALayout>\n);\n"
  },
  {
    "path": "examples/react_admin/frontend/src/authProvider.ts",
    "content": "import { AuthProvider, HttpError } from 'react-admin';\nimport data from './users.json';\n\n/**\n * This authProvider is only for test purposes. Don't use it in production.\n */\nexport const authProvider: AuthProvider = {\n    login: ({ username, password }) => {\n        const user = data.users.find(\n            u => u.username === username && u.password === password\n        );\n\n        if (user) {\n            // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars\n            let { password, ...userToPersist } = user;\n            localStorage.setItem('user', JSON.stringify(userToPersist));\n            return Promise.resolve();\n        }\n\n        return Promise.reject(\n            new HttpError('Unauthorized', 401, {\n                message: 'Invalid username or password',\n            })\n        );\n    },\n    logout: () => {\n        localStorage.removeItem('user');\n        return Promise.resolve();\n    },\n    checkError: () => Promise.resolve(),\n    checkAuth: () =>\n        localStorage.getItem('user') ? Promise.resolve() : Promise.reject(),\n    getPermissions: () => {\n        return Promise.resolve(undefined);\n    },\n    getIdentity: () => {\n        const persistedUser = localStorage.getItem('user');\n        const user = persistedUser ? JSON.parse(persistedUser) : null;\n\n        return Promise.resolve(user);\n    },\n};\n\nexport default authProvider;\n"
  },
  {
    "path": "examples/react_admin/frontend/src/dataProvider.ts",
    "content": "import { DataProvider } from \"react-admin\";\nimport axios from 'axios';\n\nconst apiUrl = 'http://localhost:3000/api/graphql';\n\nexport const dataProvider: DataProvider = {\n    // Fetch data for post listing\n    getList: (resource, params) => {\n        // Paginator status\n        const { page, perPage } = params.pagination;\n        // Sorter status\n        const { field, order } = params.sort;\n\n        // POST request to GraphQL endpoint\n        return axios.post(apiUrl, {\n            query: `\n            query {\n              notes (\n                orderBy: { ${field}: ${order} },\n                pagination: { page: { limit: ${perPage}, page: ${page - 1} }}\n              ) {\n                nodes {\n                  id\n                  title\n                  createdAt\n                  updatedAt\n                }\n                paginationInfo {\n                  pages\n                  current\n                  offset\n                  total\n                }\n              }\n            }\n            `\n        })\n            .then((response) => {\n                // Unwrap the response\n                const { nodes, paginationInfo } = response.data.data.notes;\n                // Return the data array and total number of pages\n                return {\n                    data: nodes,\n                    total: paginationInfo.total,\n                };\n            });\n    },\n\n    // Fetch data for a single post\n    getOne: (resource, params) => {\n        // POST request to GraphQL endpoint\n        return axios.post(apiUrl, {\n            query: `\n            query {\n              notes(filters: {id: {eq: ${params.id}}}) {\n                nodes {\n                  id\n                  title\n                  content\n                  createdAt\n                  updatedAt\n                }\n              }\n            }\n            `\n        })\n            .then((response) => {\n                // Unwrap the response\n                const { nodes } = response.data.data.notes;\n                // Return the one and only data\n                return {\n                    data: nodes[0],\n                };\n            });\n    },\n\n    getMany: (resource, params) => { },\n\n    getManyReference: (resource, params) => { },\n\n    update: (resource, params) => { },\n\n    updateMany: (resource, params) => { },\n\n    create: (resource, params) => { },\n\n    delete: (resource, params) => { },\n\n    deleteMany: (resource, params) => { },\n};\n"
  },
  {
    "path": "examples/react_admin/frontend/src/index.tsx",
    "content": "import ReactDOM from 'react-dom/client';\nimport { Admin, Resource, List, Datagrid, TextField, Show, SimpleShowLayout } from 'react-admin';\nimport { dataProvider } from './dataProvider';\n\nconst PostList = () => (\n    <List>\n        <Datagrid bulkActionButtons={false}>\n            <TextField source=\"id\" />\n            <TextField source=\"title\" />\n            <TextField source=\"createdAt\" />\n            <TextField source=\"updatedAt\" />\n\n        </Datagrid>\n    </List>\n);\n\nconst PostShow = () => (\n    <Show>\n        <SimpleShowLayout>\n            <TextField source=\"id\" />\n            <TextField source=\"title\" />\n            <TextField source=\"content\" />\n            <TextField source=\"createdAt\" />\n            <TextField source=\"updatedAt\" />\n        </SimpleShowLayout>\n    </Show>\n);\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n    <Admin dataProvider={dataProvider}>\n        <Resource name=\"posts\" list={PostList} show={PostShow} />\n    </Admin>\n);\n"
  },
  {
    "path": "examples/react_admin/frontend/src/users.json",
    "content": "{\n    \"users\": [\n        {\n            \"id\": 1,\n            \"username\": \"janedoe\",\n            \"password\": \"password\",\n            \"fullName\": \"Jane Doe\",\n            \"avatar\": \"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4gKgSUNDX1BST0ZJTEUAAQEAAAKQbGNtcwQwAABtbnRyUkdCIFhZWiAH3wAIABMAEgAWADFhY3NwQVBQTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWxjbXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkZXNjAAABCAAAADhjcHJ0AAABQAAAAE53dHB0AAABkAAAABRjaGFkAAABpAAAACxyWFlaAAAB0AAAABRiWFlaAAAB5AAAABRnWFlaAAAB+AAAABRyVFJDAAACDAAAACBnVFJDAAACLAAAACBiVFJDAAACTAAAACBjaHJtAAACbAAAACRtbHVjAAAAAAAAAAEAAAAMZW5VUwAAABwAAAAcAHMAUgBHAEIAIABiAHUAaQBsAHQALQBpAG4AAG1sdWMAAAAAAAAAAQAAAAxlblVTAAAAMgAAABwATgBvACAAYwBvAHAAeQByAGkAZwBoAHQALAAgAHUAcwBlACAAZgByAGUAZQBsAHkAAAAAWFlaIAAAAAAAAPbWAAEAAAAA0y1zZjMyAAAAAAABDEoAAAXj///zKgAAB5sAAP2H///7ov///aMAAAPYAADAlFhZWiAAAAAAAABvlAAAOO4AAAOQWFlaIAAAAAAAACSdAAAPgwAAtr5YWVogAAAAAAAAYqUAALeQAAAY3nBhcmEAAAAAAAMAAAACZmYAAPKnAAANWQAAE9AAAApbcGFyYQAAAAAAAwAAAAJmZgAA8qcAAA1ZAAAT0AAACltwYXJhAAAAAAADAAAAAmZmAADypwAADVkAABPQAAAKW2Nocm0AAAAAAAMAAAAAo9cAAFR7AABMzQAAmZoAACZmAAAPXP/bAEMACAYGBwYFCAcHBwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicgIiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/bAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMv/AABEIAIAAgAMBIgACEQEDEQH/xAAcAAABBAMBAAAAAAAAAAAAAAABAAUGBwIDBAj/xAA2EAABAwMBBgMHAwQDAQAAAAABAAIDBAUREgYTITFBUSJxgRQyYZGxwdEHQqEkUmLhFRYjkv/EABoBAAIDAQEAAAAAAAAAAAAAAAIDAAEEBQb/xAAkEQACAgIDAAEEAwAAAAAAAAAAAQIRAyEEEjETBSJRcTJBYf/aAAwDAQACEQMRAD8AuIIoIogAooIqygorB72xsc97g1rRkk9FFrlfnVD3Rwu0Qj5uQyko+hRi5eEjlr6aEkOlBI6N4rSbpCG6j4R0zzPoFEIpZpn+Ahv+TuJ9E9Qtipodc0haD15ud5BI+Vsb8aXoq/a6GgJ1UsrgBknTj6rgp/1JtEkgjnbNTk9Xxkt/+m5Cbrvbam9sc2XeU9G0jTFry6Q9M/hddk/T6kpId7UwNmqJCOBOGxjoD3KLvIroiX0VxprhCJaeVr2njlpyutR+k2dlttQZ4KwMZpwIGjwD5lbI785leaSppZWHmJG+JpHfKYppgOLQ9pIAhwBHIpIwBJFJBQhgiEAiFRYQkgmzaCuNDaZHsOJHeBvmVG6VkSt0Me0l93spoqY5Y0+N3Qn8JgjdrcA3xOPU9f8AS485Jy4c8ucep/CzirNBIh4D9zz1WGU7dmyMElRIIXspeBw+fGeJ4N8/wtsEstTUtHFzz1Pb7BNVHvJQA0EAnOo83fH/AGpBR7qniw14yfekz9+qFMNxHiljYwjhqc3kTxPxwnaIZA+6ZoJWDGhjnZ68gnaEvewftHw4BOixTVGc2GsOdI4c3KFXmSuq75Rw0kQ3EWZKieQaQG8g0D4n7KauaGgiNu8eeJJPBN89JLUN8btWg5HDAL++OwUZSMbTWxV9vZNFqxyIcMEELuTdTBtNUbiP3A0D5BOC0QdozzVMWUksoIwTBFBIKEMlFdtJSIKaMHHEuKlKg+3Ly6rgizhugl3wHVLyv7WMxK5Ih8k2+IAJEecNGeLvj5LvoossDsZHl9E2x6ZZNTvDGPp2WFde45P6WlqI4tPAZIGT6rAb0vwSiOox4RgA+84nn6ruiuAhLdA1n+5x5Kt6SsrYagtqqkyuJ8Jxj+FLpIql9qM0b9GW8Ceioaoa2TigrXStDsMb8SOKeYtUgGpxLe5+wVQ2eouftIabs52T7ugHPqrOtNNX7gb+r3zSPE1zNJPljknQaehGSFDo6piax5Em7iZ78h+gXJV1OId7lzIgzIYOePyue4QvxGGs8OsAN6D/ACPfH1QinirgZmODoi4Mb5BFYlqjfSsc58kjxgkN4dua61wWWqFbb2VGCDM4uAPMN6LsJ4p+LwRlM8pZWGUU0UBFYhFUWFV/t0S67xR8muhGT8MqwFDNvKJz4IqxgyWjQ49uyXl3EbidSKxrp31VWaKnJaxoySO6aX7INZG9swlcHuD3OyMkjlxKdLWA2uqJH/3NH8KRVNWz2XJ7LCm1tHSUIyWyL0NvdC6CnBeQHjRqOSB2VwVdnd/1YwRt/wDQx8Pkq4sX9XdoXubpZrGCeo7q7i3eW0OjbqLW8B3RRjdkm+tJHn6usdbV1JY6rnpmBww5jT4QPLn6q09jLdcKBsRgv0lZSFgaaaoYXBuBza4kuB7g5HwCa6y50tRWvi3ZjeHYc1wwQVMdm42NaC3lhXBu6JkikuzHS4QuNuqCPf3biPPCqj9OdonubHa6txLyXkPJ65JH1x6K27tKYrXVPAyRE/A7nBVE7OUEtJtDSs0k6JwHO8zghMemZ6bjZcdqjZT0jo2DAY4tC68rVBHuosY4klx81sWnGqiYcjuRkllAIhGCBFBFUWFc9dSR11FLTyDLXtI8l0BJUXZRt4tNRZ7hPFI3Trw5p6HHBcEk0jgwO93l6q3tsrJ/y1oL4WZqYTqZ8R1H0VRVEDKqikgkaQRkdiCsOWHWR0+Pk7RFRzVNHXQmNwc1pHAHBVq2m+19QIzTgMhaMFsjclx+ap2wW6gn3dNXvqIpA7G+DstcB9CrVtVqsVDa4Zpa2eUmPIDS4knIzgD4FUou9Dvtqpe/oZ9qrfUR1Elw3ZDy7UeGAVKtibgKi3skzwPDj0KiV7ornc6xk8EtdTW+QhraSZ+S49SW8cAeamWzlsFupBG39ztXkotSKl/CmO21N3pbLs7U3GtL/Z4tOsMGScuAwB6qK7JUrbs1t6ex+5kOuESBoceJ4uDeGfJP+1NpO0NLSWyRgNE6cS1Rzza3iGjzOPknKCnipadkEEbY4o2hrWtGAAFojj7O2YJ5eq6oyKCywlhaTIBEJJKEMQigEVRYUViioQJAIIPVVrtzYW0FY2507cQVLtMoH7X9/X6hWVlcl0pKWvtlRTVuPZ3sOs5xpxx1A9COaDJDtGhuKbhKyjW2uT2newSuZq544g+in2ytGYpGzTPMj28WgNAwofRV0cFU6F7w5oOGudw1DoVPbRdKCBrdU0eojg1pyT6BYbr+zsd5dKRIvZN6/ey4yPhyXRTx+PDeXfssaZz6wBzssj6N6nzTiyJrAABgI1vaMrdaZp06SQTniktkvv5WtbIO4o5+RVJgwkikjAAkigVCGsJZWuSaOGMySvaxg5uccAJiqtqqeNxbSxOmP9x8I/KCU4x9DjCUvESIJuvG0Fp2fp2zXWvhpWPzo3h4uxzwBxKi1XtTcJGnS5sDe7Bx+ZVD7WX+p2gvs1TNM+VkZ3cOp2fCD9+amOayPReTG4LZaF2/XVjKmRlotTZIG5DZal5Bce+kch5lcLNqL5erSJrhXPd7SNRiYA2No6AAKocHGOqs21NJs1K3HERgfwg5T6xSQzixTk2zAtEziCn6wwbmoa4DHHoE1tgO9BA9FJLfTua0ODeK5sjpw0WFaagua0Ek+akAcC3KiNnbI0AkKTsfiLJTsb0IyrZue3U3yULuW39stV+fbKlkmmMAPmZ4sPPTCeNoL9HZbPUVbiCWN8I7novPE9TLVVktTM4ukkLnuJ6kldPg4fkk2/DncyfSKr09C2zaizXZzI6SvidM/lE7wv8AkU7rznsdUvG1Nvbk5FWz6r0O2XuPkj5EYYpJJ+isPfIm6NqCQcDySSk0/A2mvStrpepLtWu0kimYcRt+5+K1sZlqa6LmMp13ga1cuUnJ2zrQioqkM21VULfs7VzA4foLWeZ4fdUnjAHmrI/Uiv8A6OmpQffeXkfAD8lVyBlkY75K6XDhWO/yc7ly++vwGMZljGM5I+qvWlpab2eMNiDQGjgAqNb4J2EftwR6cV6Et0Daihp5WjwyRtcPUIebGkhnCabZjTWykmOHsHDkU7U9BHF7ucLXFTljuSc4W8srnUb26OmmeI2Dgt7qzIw44C1BgwmLaq7w2a0S1Dj4sYYM8S7oEyKb0hcmvWRD9S9pI6qaCz0rsiM7ydw79B6c/kq/Mni7cM/RYmd9XUyVEpJe4l7s9StD3nWT105+y9NxsXw4lE8/nyfLkch32Lk07X21zjw3+r5L0HHUa25yvPWxzc7YW9nYk/wVdrKgsAHRcn6lKpx/R0+BG4N/6P8AFL4hxTg2IvZkc1HqSoy8EqUUUgfGFjxt3o0ZUq2f/9k=\"\n        },\n        {\n            \"id\": 2,\n            \"username\": \"johndoe\",\n            \"password\": \"password\",\n            \"fullName\": \"John Doe\",\n            \"avatar\": \"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRyUkdCIFhZWiAHzgACAAkABgAxAABhY3NwTVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLUhQICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFjcHJ0AAABUAAAADNkZXNjAAABhAAAAGx3dHB0AAAB8AAAABRia3B0AAACBAAAABRyWFlaAAACGAAAABRnWFlaAAACLAAAABRiWFlaAAACQAAAABRkbW5kAAACVAAAAHBkbWRkAAACxAAAAIh2dWVkAAADTAAAAIZ2aWV3AAAD1AAAACRsdW1pAAAD+AAAABRtZWFzAAAEDAAAACR0ZWNoAAAEMAAAAAxyVFJDAAAEPAAACAxnVFJDAAAEPAAACAxiVFJDAAAEPAAACAx0ZXh0AAAAAENvcHlyaWdodCAoYykgMTk5OCBIZXdsZXR0LVBhY2thcmQgQ29tcGFueQAAZGVzYwAAAAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAABJzUkdCIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFlaIAAAAAAAAPNRAAEAAAABFsxYWVogAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQWFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z2Rlc2MAAAAAAAAAFklFQyBodHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAFklFQyBodHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZXNjAAAAAAAAAC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAAAAAAAAAAAC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAAAAAAAAAsUmVmZXJlbmNlIFZpZXdpbmcgQ29uZGl0aW9uIGluIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBpbiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZpZXcAAAAAABOk/gAUXy4AEM8UAAPtzAAEEwsAA1yeAAAAAVhZWiAAAAAAAEwJVgBQAAAAVx/nbWVhcwAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAo8AAAACc2lnIAAAAABDUlQgY3VydgAAAAAAAAQAAAAABQAKAA8AFAAZAB4AIwAoAC0AMgA3ADsAQABFAEoATwBUAFkAXgBjAGgAbQByAHcAfACBAIYAiwCQAJUAmgCfAKQAqQCuALIAtwC8AMEAxgDLANAA1QDbAOAA5QDrAPAA9gD7AQEBBwENARMBGQEfASUBKwEyATgBPgFFAUwBUgFZAWABZwFuAXUBfAGDAYsBkgGaAaEBqQGxAbkBwQHJAdEB2QHhAekB8gH6AgMCDAIUAh0CJgIvAjgCQQJLAlQCXQJnAnECegKEAo4CmAKiAqwCtgLBAssC1QLgAusC9QMAAwsDFgMhAy0DOANDA08DWgNmA3IDfgOKA5YDogOuA7oDxwPTA+AD7AP5BAYEEwQgBC0EOwRIBFUEYwRxBH4EjASaBKgEtgTEBNME4QTwBP4FDQUcBSsFOgVJBVgFZwV3BYYFlgWmBbUFxQXVBeUF9gYGBhYGJwY3BkgGWQZqBnsGjAadBq8GwAbRBuMG9QcHBxkHKwc9B08HYQd0B4YHmQesB78H0gflB/gICwgfCDIIRghaCG4IggiWCKoIvgjSCOcI+wkQCSUJOglPCWQJeQmPCaQJugnPCeUJ+woRCicKPQpUCmoKgQqYCq4KxQrcCvMLCwsiCzkLUQtpC4ALmAuwC8gL4Qv5DBIMKgxDDFwMdQyODKcMwAzZDPMNDQ0mDUANWg10DY4NqQ3DDd4N+A4TDi4OSQ5kDn8Omw62DtIO7g8JDyUPQQ9eD3oPlg+zD88P7BAJECYQQxBhEH4QmxC5ENcQ9RETETERTxFtEYwRqhHJEegSBxImEkUSZBKEEqMSwxLjEwMTIxNDE2MTgxOkE8UT5RQGFCcUSRRqFIsUrRTOFPAVEhU0FVYVeBWbFb0V4BYDFiYWSRZsFo8WshbWFvoXHRdBF2UXiReuF9IX9xgbGEAYZRiKGK8Y1Rj6GSAZRRlrGZEZtxndGgQaKhpRGncanhrFGuwbFBs7G2MbihuyG9ocAhwqHFIcexyjHMwc9R0eHUcdcB2ZHcMd7B4WHkAeah6UHr4e6R8THz4faR+UH78f6iAVIEEgbCCYIMQg8CEcIUghdSGhIc4h+yInIlUigiKvIt0jCiM4I2YjlCPCI/AkHyRNJHwkqyTaJQklOCVoJZclxyX3JicmVyaHJrcm6CcYJ0kneierJ9woDSg/KHEooijUKQYpOClrKZ0p0CoCKjUqaCqbKs8rAis2K2krnSvRLAUsOSxuLKIs1y0MLUEtdi2rLeEuFi5MLoIuty7uLyQvWi+RL8cv/jA1MGwwpDDbMRIxSjGCMbox8jIqMmMymzLUMw0zRjN/M7gz8TQrNGU0njTYNRM1TTWHNcI1/TY3NnI2rjbpNyQ3YDecN9c4FDhQOIw4yDkFOUI5fzm8Ofk6Njp0OrI67zstO2s7qjvoPCc8ZTykPOM9Ij1hPaE94D4gPmA+oD7gPyE/YT+iP+JAI0BkQKZA50EpQWpBrEHuQjBCckK1QvdDOkN9Q8BEA0RHRIpEzkUSRVVFmkXeRiJGZ0arRvBHNUd7R8BIBUhLSJFI10kdSWNJqUnwSjdKfUrESwxLU0uaS+JMKkxyTLpNAk1KTZNN3E4lTm5Ot08AT0lPk0/dUCdQcVC7UQZRUFGbUeZSMVJ8UsdTE1NfU6pT9lRCVI9U21UoVXVVwlYPVlxWqVb3V0RXklfgWC9YfVjLWRpZaVm4WgdaVlqmWvVbRVuVW+VcNVyGXNZdJ114XcleGl5sXr1fD19hX7NgBWBXYKpg/GFPYaJh9WJJYpxi8GNDY5dj62RAZJRk6WU9ZZJl52Y9ZpJm6Gc9Z5Nn6Wg/aJZo7GlDaZpp8WpIap9q92tPa6dr/2xXbK9tCG1gbbluEm5rbsRvHm94b9FwK3CGcOBxOnGVcfByS3KmcwFzXXO4dBR0cHTMdSh1hXXhdj52m3b4d1Z3s3gReG54zHkqeYl553pGeqV7BHtje8J8IXyBfOF9QX2hfgF+Yn7CfyN/hH/lgEeAqIEKgWuBzYIwgpKC9INXg7qEHYSAhOOFR4Wrhg6GcobXhzuHn4gEiGmIzokziZmJ/opkisqLMIuWi/yMY4zKjTGNmI3/jmaOzo82j56QBpBukNaRP5GokhGSepLjk02TtpQglIqU9JVflcmWNJaflwqXdZfgmEyYuJkkmZCZ/JpomtWbQpuvnByciZz3nWSd0p5Anq6fHZ+Ln/qgaaDYoUehtqImopajBqN2o+akVqTHpTilqaYapoum/adup+CoUqjEqTepqaocqo+rAqt1q+msXKzQrUStuK4trqGvFq+LsACwdbDqsWCx1rJLssKzOLOutCW0nLUTtYq2AbZ5tvC3aLfguFm40blKucK6O7q1uy67p7whvJu9Fb2Pvgq+hL7/v3q/9cBwwOzBZ8Hjwl/C28NYw9TEUcTOxUvFyMZGxsPHQce/yD3IvMk6ybnKOMq3yzbLtsw1zLXNNc21zjbOts83z7jQOdC60TzRvtI/0sHTRNPG1EnUy9VO1dHWVdbY11zX4Nhk2OjZbNnx2nba+9uA3AXcit0Q3ZbeHN6i3ynfr+A24L3hROHM4lPi2+Nj4+vkc+T85YTmDeaW5x/nqegy6LzpRunQ6lvq5etw6/vshu0R7ZzuKO6070DvzPBY8OXxcvH/8ozzGfOn9DT0wvVQ9d72bfb794r4Gfio+Tj5x/pX+uf7d/wH/Jj9Kf26/kv+3P9t////2wCEAAIDAwMEAwQFBQQGBgYGBggIBwcICA0JCgkKCQ0TDA4MDA4MExEUEQ8RFBEeGBUVGB4jHRwdIyolJSo1MjVFRVwBAgMDAwQDBAUFBAYGBgYGCAgHBwgIDQkKCQoJDRMMDgwMDgwTERQRDxEUER4YFRUYHiMdHB0jKiUlKjUyNUVFXP/CABEIAMgAyAMBIgACEQEDEQH/xAAeAAAABwEBAQEAAAAAAAAAAAACAwQFBgcICQEACv/aAAgBAQAAAADX6pYoNMMEMQvRe+eB+D4EASSyFak00wYxC+b86V6li1h6xe/ghAUWWpUGmDGKO5qp3BTO6zOKQy5O1ct+8AWAB5xpgxQDkw+xsqAXM4QKo2OX9s7MF8Arw84Znv3MzFNrkP8AnHRLBUzSgY9dbbUageywnHGC+h3COtrbrVDNrLiyWIIUBPTCz73tiorePGZ77z55KntLoGw5+4qq4Y08L6XaFu6N4a2od99H3Xmnk5Jc2wWnSVjZnzTDIi61ruyXT6vaL3TmjT1fZc2dlmhdrdM5S/rfsY4BjVnveRbXediVlgXvIuWYDDoq1cR6QtGfu7kKvK9Xkn8pM/P+pFeVun+FdU0tDOnFh5FsWTXTIz/CTE7QXkTnpJrpIqrrtHkda0pVWh6Csywc3pJLrHQUwRs1Ut+WRzWPQLROT4toepGy94vzV6PT/n3ojfGkBs5aCIZh9d1rVL46iuoml5WsyXrDZUah83WoG5gm2aa7PbgjkCdwWnEqRZq6ETiJrVLYpj8DQSGdoGQ5XQ4I4rkTf8pYbnhdokWEfD6jbrwoaUv57o+Q2JVlL7Nhb3Im7jTrqz/tgHZkrC3tJxFc5LlBTT8rWrPTlXuG+du4rImJFT5P6xSB8k3oiyUKk44Y/ffE/EBd1KaMp4t0d0vT1rO594WQ+fBF8X8UTzD5GdB9sZ/yHc/VactaPiTYG/tL+J/Bm/ehhPFTA31i35a2ibu01YTS5R782Ee171cspT8MY+fXKKrGn65+hdo7alYJOTKpxxw5QEG/pSNOHRPI6o/E9bsct/TZbbarZ1rvOl8W/M9TRH6TVKblDgqRoXVC0JD/ANV9mEtrU1zByLKwtwCS/o/a+H9HKZfFXAI2j3uF0rMH7594EJPBDCH/xAAbAQACAwEBAQAAAAAAAAAAAAAEBQECAwYAB//aAAgBAhAAAAD7PjSlfZYkXm1hs6V51HkM46smbD51V81FIMOLcbc9lGQq1fVuWz9vyCpc/wCJaHrjDHIXVcGvGe8u2wIupayPqSrG6kLDYcVHnM4xt1URULr0MHyJqQQkW3JYstIJ9PrruQch27bGtZk1t7hubMN7M4FZu43rKXnxnJnQ5890cTFFGXvea4//xAAbAQABBQEBAAAAAAAAAAAAAAAEAAIDBQYBB//aAAgBAxAAAADwyeR7+yzjxJrSJXP1OgmKo8YMmESPuNUnyBV+cGi0syIMt7PlIHmF3WFcM9Goay2BBxNpkvRHgzeq5x1fFpfMSxbaBti60lqj+1j+Hu5G4tMPzA7BXkRQN9OEHErM8xQcSj1Ooop+YORySCqH+m31WFjawywhqY+N0t0XSBU8N7nHu6ribqQMf//EACUQAAAHAAIDAAIDAQAAAAAAAAECAwQFBgcSEwAIERAUFRYXGP/aAAgBAQABAgAqZUipAl19fX19fDhw6+vhwEgkEnWKYpimKYplSKkCfWBATBPrAnDg/eON8/6WH2ZZe0Fb9g42T4cOsSdYpimVMqYJgQCAThwm56U3+7bdJPwjYuCPW35TNM70au2ICcBIKYk4FIUgEAgE4cLnaLRPQLGThywrpSMQm2DpB1JnQzq/0W5D4HgkEgkAgEAnACceO9Wdu8ippq5lp9KRoaMxYE1khcuBJgV0mNMhNEjXwkEgEAgEAgF42uct08zCQtLuYWkoNjKRr1mBFEAaLCh5HoNazWGKyktcgEB5Afnz9n7W9EHXaqxMFeeup1nT5+SWRFqo2VLljuCtEe/ttkeSH9sUvCF0Pcj6KF13qbWL+rXs0Jh6PrNWvU+QwGzZZKwzt8qkdg+SZ1yGPCy9ydO3kwwuaWfUq5xhiRbXWaDVqfQ8Xj2iaSQpmWHUHL+vjnjPJnmcS0K5spZXIJHZ137ljXArL9adm1qzVqvZatHwzN0z8QMVNMpxmK4hmS9PY150w1ZNo6dusSca2c8bfJdlqNbC4QrCSrHiUPORhq7DuI9UqpVVQKPxYnF3EWqnvaUlVMwi9QTNFFjgqxHdwAxUr1XNI1PVajrku+iNOX3KEs8AjFvgBfxDy02K/Z5aISOgq9G3iAXgZuQslvqBnUbK11jXmMDZ6M9jMEJaM3n84qWGVXKkWCgrHaGn4GXcIOgeoKuTD4qLmIaQsYnMokYNwMlq6vr1CHM/jC1lqkZdRVY8Yo2Rvi6NZVhhXM7L4dXmmAKiINgbGHU42hQyvkjIoOxVMsU8i4iZKLvEIANHEYSvDXU6/wDx6rQ0g3cFaKeF8FCVjaVfpTcmhmzVPwyEg+l5ehrmZG8QlkpQH6TpN4urILfxUTGuEVWsU1kWEXHad5TqyzX/ANGr8vJO7FYJm0Yyi8FaCSgCQpIn9EWoRYQ5IgsaLYGJWQNgab7mlRpsFk3+AQ538zOS5FavHPDRQdHUJBIJAaFa/r9AI9YF+fVyXRagScJD2WNs87ZrRjlJYkceaFbKVfhX7zLir3i5/aByLj9oXAuDL7l7SwEtWtQgNmsu4Sc/mWYx7VApiyTLSM7p/tLTd7+iIOBWBUFe0VBUtNy1/wBnfoDDSEZXY2kQ0LCtYhqUqAdOhZlLRSw5f7BU/UwW7e0FOZ19Q9obPMP2HgeZYtI0it1muVVSGQbFFsm2bgX2wyUDgimcEyh4BtD2W/bRDNHyqhHMcZKruqjQ29KO1BJ0ikZig1Q8nIbV6IUwj2kPJSuo+yxUY1FBRZQBcAJEwz+eAVURj3UYhCtmf59lsxfMxADzE7quvoopHQJ9bEMRM6iHz02uwG+8vvn38qF9jssg47//xAA/EAACAQMCBAQDBQYFAgcAAAABAgMABBEFIQYSMUETIlFhFDJxBxBCUoEjMFNigpEgJKGxwRWyNEBDcqLD0f/aAAgBAQADPwD2ofvhQH/kR99lYWzz3dxHBEgJZ5WCKB9TX2XRSSoNXaQpneOCRlYj0OK4TGrTwGzuGtV5BHdJuGJ65TY1wwJLrGl3johIiIwGfA2znZc14s/LJww/JnqlxuE+jCuGNS1KeO9AsY+YiIyNk8vYEAHLVp+o24mtZhJGejYI/en79D0SzN1qWoQWkI/HK/Ln2A6muF0mSLTLO6v+Z+UShfDT+nm3ate+FeGyUWTMDl1YSSgfy/hX61rOqSNLdXE83OdvFkaRnP8AVTjBZs5GcCrm/eXkISKADxZOy57D1Y1Etkk7xsFkGYE6ZUHHNjqebsa5IxDAMLv4kijdyNsKfSpBOsKoTJJ8qgZ9q4g4L1yBjPK9lz8tzaFwysvflG4DCtF1/To7zTryO4hcAhkYEjPZh1DDuD9wofu7ThrQLm/mAYphIkP45H2Va1TXLmDUb29iuLlsmGPAZIFyfPJ2B/KtSWuny3CIwjkID3cqhpJC3RY1PT2AFeFA17qUiwRsQILXPNLKTuCwG5J9KaOCWe6TwGVA7oVyY0b5QR/FbsOwp3kWxtYB8VcEc/rGn5N+nqx6k1ZWtpY6Rb+HK6I094cll5mbdpCOwAAx+LoKnMlpbIzLNcN5S48ybZLEey9B2yK0ZDKsPhg28jq5LcwRIV83132HqavLe8uJbacWqTKijHnkbC4IX/8Aaj+CxDpzlc5aSRcPk9ixI/sBVzwXxCt1Ekj28mEu7dScSJ6r6OvVTWjcV6Il9YT86hikgI5XVuoDr2JFKOpFKeh/dGvj9fj00TFbKwTmmZepkfY/r2FKW55SIoQfKvQCtT1NxLGn+XtkJ52B5UQ7Zb2PYdWqBb06nqErSP5vBMm5X3x606aSGhQm4dyyhhkQAjJmmJ2Mp7D8Io28cgh3eZiDKd2Pq2TUWm2z39wQ6Kwc87BA8g+UEn8AqwvNQur/AOIubl90VIE5UGW5zzStgZZvSlmR40VYA3znmLN6+c9BUETElM425+bdqjZWwhiUn5FJwf1bJJoDDFjv03oaFxRNaz3gS2voCgRzgeKp5kpYZnSJHkOe1NPOiTRPHn1qK6iUg/4Tj/BbaHw/f38rACGI8v8AM7bKo9yamvdTuGkZSfEZ3brlj/uFq41K9jQABATyqTtgdWb2HUmrW2sI9PsSWgUh3cjlM0ndz6IOwqaVg7y7qMA9lA9B7dhV7qCRW6F0hBPKmc5zuSfVid2NWpvrZEVLufvzE+Ch9yPmx6DarvUyzvcOLG2AMk7+UNj8ESbBR6mtLtiGuf2ZbzR2zMQ5VvxnPyj/AFNSSQGFIJI4kw7KVKIue5+vvuaOQyg8pJ834mP/ABWeZ2ZQR6/8etMBkMPMcep/02FFJo3ByUdWOAMgg5qG/toLhAD4kaNsNskU80asBhquraNFkbJFCKLmara1YjnApB3pPWk9aT1qP1qPHWo7XT9H0pd2mlFy49oztTOVUk5PzH6bmmhiMKeXnA8Qj8vZfp607u2e9TcscjghXOI1x1x3p+UoCFGwY9z7HH+1C0Y7BlA86nuPQ4riLUZbcW0It4o2/wAtGAMI38Ug7F/Q9Fq1hZ7q+vGknzzTXDEkJ7KTks59asBbRQRW3gwqfJboSHlb+JO+Tj2Ub+tM6AsoHYKBgD6AbAU6ly7F8dcDAx+gNINgSS24HrTK+ASF/KajtOCLOWW6SRGVjGuMMm+4J71ZXBHIahJG+1R2tmx5+1G7vDJK5wzf2FRCTHK1WMK+ckfU1bXKlogWH1qBFOQR+tWCNgn260DEH8NuWpNW4ytJMgRQ2aIB+pY0PiN8/Mc/qalNy45cksK4i1S7gVLOQK7ABipxWp6lPp8Aj8NbW1YEkVxNdTeHbWzci/8AqtsG96t7OFHv7oyuCDyJgLWmLbP8PZM8jDZnlK1fWKtJcSGBY+gEmd/0FQ2vNyO4Xl3YrvVvJbRgRsAqnnbO59SRUg5uR2IzgMM7igsQYxhwvYHB33zkdPUUGO0fmw2fqN6bRuHtOsjIGcQRmT052UZxRsVJUDFcRX9xL4EWYU2yK1cSrHcKyjqB60QcZoxvEUlQsQc1qUsqRQOSxI6CrkaBC8rsHKb8wq5tryUJP5QemKvF1RGaR+RZFJB9M1a3VlnxcgocL65qSy0cak7nBAUAg718eY3ljLAjKA9cVp0t9baheRq0SOD4Z/FWmRW6JFbRqqgABVAwKiXcRgZ64FAAVsctk0ChzUiwyr4fNkEFa+MdJVjZImAYqTjGTiryG4jSNCVkkZA5GAAKjmjPIckYLe6mpVicRxEKA8fKfmr4W/VJYlyJMt/fGaku7tmLbFsADsBUawS56gCtMuNI5UC8w+f61bfFQ8gGQDTeMuM9RWk+AheME471w+JObwI8/QVp1nZsF5VAFafqWsSqFK8r4znqK0Wcx83ffZq020ELiPcDvWka9w3dWMsSMrgEKduhzitJ0fjrUbL4UrDC2IY/mwuAVrWQ6xwaIFj6rI7Ba1HlUzXUKn8ibgfrTFMZzTlRmtutA4FWl/zMQobp9RVgtskTtlVYlQO2TmrMlRLErlOhqG0duRQANh9DUDKxZAah0/iVliU8w53yRkDmNHxV+tOUOCRtXlvEycls1zXdsvoKMhDcpriex0yJ7GYBsHqCa+0+5vJYDc4KuQcIa4o1rTEe9uHOeYEcpFXOl380kQdQAD8ta9I0bq7hQ4OeWo57WJmkySoqNl8szjPvUVh9pc4lmZFeCN0b2I3q2mBdtQuWU7gLJy7VZWgWFIJQNyruS4JHvReMkEHAp2xivPymRQ2Omd6Yd6bI2o0SooOSAvU0GjzJKsKAFmY9gK+xniG/eKe8u4b+cLDFd5cIW/DgHykVNpWs3dlOoMlrM0bEdDynqPY0k0JIWhZXV3Hy9TQe6tVxuDWIkfHQVYT2kayIpHuK4dgZpFtogx3zgVpdvJ4aNGuO2RWn3ERLhCD/ALVpENs2DGEANavYyBLWUgb4rV3tl8fBI6mrO04vspZY3BSyTzcuVYMxyAa4f1FreLKqDtvXw1nMIJcLLC/gsp2WROn+hr7T9JmcR6et3H1y2cj6GvtQecg6e0S7jypy/wDca421O6hl+IdZlO4MihmzXGaxBp7ieQls8xk7dxUk45ZEZXA3zWwpcCsXBPXArh9NZsNI1s3UcV2S4MQIjYofKkrDcA1o+p6NA2lgW8wkjKOCSCOYU2p8T6rdIfK8uAfXkAXP64oxZBFLb3chK/Oa+NeLkG4Oc1N8KFA6VrkVlCbebFcdxGaNbphvsQla5eXplvLiVjk7nIq8uIlRVkbC1rKStmCQITUks8ZZelKsAHLWkatYlb2wFz4YYx/hYEjsa4s0TV3jGm/CxByU5Yy2V7HLHerrjLStUt78SI1rKgU+7LXFmnJILe38aMEkPF6VxBq2tKtwJ3RT58q2QCf9K4OZ7eGeW5Zw4aRTIUG3staBpgSSxvtTtTknlivZCmD+Eo5YUkSKOcsQOp6msbVzNSeN1BA3rSddtHS4thKyAGMjZ0cdCpFJpPC8iCUFok5Ac5w77AfUdagRMYpA5wK8wIFF9yKiKEctKyBD0FWsysWVTk71aQybIuM1ZqozyjarF4SPKTioVkLBe9IFxikJAxSQ6lFHyDEluhBx3yRUFjwdFOsWJL6eSaRu+AeRaUnbatMuseLAjb5Bx3FaZHKZEiUk9yASKSFQBsewrfrWc0FRmPYU3j3ChuZR09jSxF1EeARuCc5/Wnv76OztVIgt2JJHRpDUxALE14G+DXIOUCm2BU0WOcGiaz1FKOpoDvSv1akNInekA61JcxWU6LkgmH9WOVqPTOH9PtE3EFsiZ9wN6YNtS2ssayjAbYNmk9iKUUS2DWAKVYm33IqaOPUFGC8cReP32yK1nXnSGK3ECRKDcSZyT7L9as7gMTgkEg/pVrjYCrWQbqDWn5P7Ja08naNash0jWrhTipYxmlU4p5zhRV0BmrpW2q+l+WrqIZepr/TbhVXLIPEX/wB0fmFaZdabGyTqXWMB07itHg1XwbTT7u+cAoDCmxYnoM9an1uzWe/txbMyn/KswZkB/PjYN7Vd6bMqFzNbsf2bHcr/ACmkkUUgHTpQht2dGBKkgj/ipU8Ns7S25KqT3P4TTXF5dgksoIxtsParO1jKwQJEGOWCjGTVxYarcLExCl2JH13q8IGWqUjd6lY/Mal75rbcmoMghRUTRsoQ5NPPJkhgPYU8U+6HFfsRyoSauGOfCYGpA/mjNPLFgRjNTwA5TNcSWn2karY6bPc2UAmJREkKZVvMSSK13Qo45JOIraW0urKPxJVlDZlc9B3PKKvbf42S34gtpZ+dTGjyhWfm6g59gK1O0uWtpWyYgCoZwWBA3yPxA1FqVhDOIzGWQEqTTOGEUrIwXIxv+hq5t7TUw/OghClwPyucZB9vSreW0lSaVTEYFdG6cpjqebSb/UWJ5by8keHP8MbVlUpLi8lm/Ngf2qNe1RjqtIv4aUdq6DlpKhY7qKgXooqEHOAKX0pPSlHah6UD2pr+z/6zY25a4t0JnA6yJXG2rXpl02aI2SENI11LyooP/wAqh1RzHq2qQeAQpZreDlnc9eUSOWIWvs33mtLaaO4G6SNM7kH1OTT6BBHYXDr4YyqNnt2zmkMR8OXmZd25SedQP9cZq0FqXnkGHi5hK2CF7Mp9VPcVdarqjafCXAmeWB4QcqCcHKGodO0ays4gAkEKR/2Fftox6mlZ5lPsRSVGKSo6i+4ChS+lJSCk9KWlFQSxOkiqysCGB6EGm4Y+0PWtD0zURlQZORG5lUvuUf8AmAO9fahxBrAs7e5l+FQ4eVVCqMduarm1tIxJJlgu7Fs1zoSxicqpIVupxvtVhYacjSRRqUm5Ww2CF9QOuKn1bU2tLeR5ELFYyTnIk9xTyXUF7IsoSLDhz+N8+UD2A606oebOc0Wu0rVOFOHbnWrO1W6+DaJ7mBtvEg5sScp7MAcg1oPF+hRalpVx4kTbSRnaWB+6Sr2YU3rTU3rRpaWloGgO/wBw9fuNJoVxc6Jws8U98mUn1HIeK3b0i7O4qZtfF1d3EsjvMZJZC+XcvuxJPc0NLtY5LZjsA/hAnAA2rSbu2ieSYLmDLKTgBm7CoYp5xzlkXK8udz6Fa13ibVDIbWRw4OOoHm7invr2NtQYoGfcA+YotWdraQwW8SoqjZVGwrCk4A2rNznHSre8tJ4Jo1kilRkdGGQysMEH61xX9lms213p+oXEVjfSS/BXMMrI48M58J8dWUGuNtKEaavDFq9uNi7YiuB/Wuxr7O+JnjhS/awum6W96BCSfRX+VqH3H1/xNXD3C+kSajrGoxWlsnRnO7t+VFG7N7CuJuK3uNP0R5tL0k5RsHFzcj+dh8q/yD7sEGr65ZoTI+yDJX0B71eTW+PjnCnzLgnrWmeOZZS7kgfMckfr71bwRr4cSYFXDSr4SNkEYbPT61KqhpGy1ARmszMaLsNq03jjgh9HuiEfnE9tN3imXoavdJ1i+sLqIxT2k8kMyEbgxkr/AGNGML5vI2wJ35T6N7VxPwm8VnfmS/01Nmt3bMkS+sLt/wBprgviuNTpmqRvMRlraT9nOv1Q0KHr/gSON3dlVVBZmJwAB3JPQVpGjmax4aSLUbwZDXbf+FiPt3kNcT8V6g2o6zq1xeT74Z/kjH5Y16AfSntfCJbmEicwOMffEnHGmRyorxXBeCRGGQyuvQ1NonLPADLYOchurQ5/C/t6GptQK+DGSG6ntWnafZqjwo8hUB2Izk1ahcxxKv02oxEb0TCa8oNc7KMdTQArwtTs+JrCHa5d4rwAdHbcMfZqjdWVhld1dTQRVVmyB8kncexqa2kjYOUIbKOrEFD7EbitutY+4VwXwTbst3c/EXxXKWMBDS/19kH1rjjjqc2s0wtLBjlbC3JVMesrdXq1eTzAMwzjPQU3xEqEdByrUbqInUFVKggjPasZ5EA5SQR9KkU7qakseI9Jugp/Y3cLkeoDDNSzWoa9AETLtHswZT61pGnQ8un2yQqOiD/ipYnOVIpmTpUqmv8AJnJ3rKKaCDmI3P3afrGlXdhdxCSGdCrD69CPcVf8HcXX1lMh5RO+DjZlbdXFA+X8wGM9KXlwclOhB6qfQ0R92laXp9xe311FbW0CF5ZpG5VUVqmqNPYcMmSxs91a8IxcTD+T+GtTTzM8khLOeZmY8zMT3JNKruwG2eWniuJGQ/KTSXM0DDYj5q5pZwdsv1opKHwfN1z+YdaVs5UUBuoGcbVb67wRw7qkLKVu9Pt5Djs3IFcfow+6KQYdQaQfKf0NSupwmau/ACPyg533qOFVHUj7t68x+lJxJwudUtoS15py5cDq8Hf9Vp7S5kjbYA7U5PMoBOMOPzCkrStG0u6v7+6SC2t4y8sjHoB/uT2Fatx1qrBTJBpdu5Ntaf8A2SermsouPmLCmWVhQVUA9zQWWT6mmVwfUGi3xYHXIxS3EMbY5uceYd8+1FD6qTsa22o6jwfqnD8z5l0qcSwevgXP/CvXmIoj9wrKykAgjBB3BFHh3iW4ltocWV4DLbnGy+qf0mr/AFDVoLCDkNxO4jhV3CB3Y7LltgTX/8QALxEAAgIBAgQFAgYDAQAAAAAAAQIAAxEEEgUhMVETIkFhcRQyEBUgQpGxIzNDUv/aAAgBAgEBPwA2Q2TfN83zdDdUP+i/zG1enXrasS1HGVYETdN8DzfC8LzfC/c4mr4qa+VYB+Y2uuswXcn+o97hfcxLmOM85Vc6MGBxKdSLF7H1E3mbzN8LTfN811p8MIP3dfgS2vJAxk/1Pp+YJloDcs4B6xQqj1ikdZXYVIIMFXEPE3eMCO3pAxwMjnPlgIeI0+8/MqfefmVPYx7d7Bu45R7aqxliBF4jQfWXa0BiRUx98SrVCwjJOe0Sw/EqfMNuorYAkYAlfE6TYU6vCpJzmU8RAqwahn5h4j4V3JQc9Y/Ene5SFlvECKGbbzAzLNXdY+WyZRacchNx2xC6McDOTPH1BHXE0V7mwqTPGsLHdNKVXXEnuYNbpu8retCS1KtnuY2NzMFHxK3zbkVjlDemorapFO7b0xGoZGwVwYiYGNw9/MI96jI6n2OZXtYZBhbAhuvDO1JQbfuBJ3fxDrSR93OJcC+4nrNw55aV6upc5RTK9VXaxHJRLnFb4DAwXKpDBiCPURyt9FZasDOPNEpNBJqIB7kQDUWnFrbhDsUYE3DdLkUKbMAOQRNjrzniN3m8954V0ZbBMWHqDPDcftM0Woxp61forGX2Fh/jzn45Su5mBBGCIxK9ZklpwfRafU1602P56qw657DrPqaHyNkU6foKhFr0+PsEbTlhBw/zA5j6EOfui6RQm3rKKBTkgAjHQy+jbdzuXJ7CO4qsXzlgesFociFQmB6maG569Q4B/wBiFD8dYNJV/wCRPAQdAJ4Mws5TImREBc4AnENIFHKsMzAc8T6UsCiIxPvK9NVpU32HL9puNj7jEJSwN1wYtW+sOhyCMj0MKkHBBmBNom0TAlelLc25CKiKMKMQ1iwhe55GcQOqotZHysNbt5sykYESotNIcAV/xHRWGCIdL2aZlVbWHkPkyuhK/c9/xDEEGaxzqmzYPj2h0RB5HIn09ofkpPKU1bFGesBIOREIsqDj4P4KBkCABVAAwIf0WjFjfp4ex8fb6MDmazUPVaAoHSf/xAAwEQACAgIBAwMBBwMFAAAAAAABAgADBBESEyFBBTFRYRAUICIycZEVQrFSYoGS0f/aAAgBAwEBPwBaoK4EnCcJwgx7j7Vv/wBTFwclvalv41HodG0ykGcJ05wnCCuBJxgQkgATD9HWwbtYj5AiYNFfZEA/zEoQt9BLKlAIHaW0VurKRuX4zVPr3HgzhOBnCBIFnAz0+odRnI/T7fuZXb2J3of5hyPcASklfza2fAh2T4jbl1QdSp8zeKBrgdzj7zfwpg9Ms+RP6XZ8if0yz5Erq6aFfr3ldF1rAKpMb0rIXx/J1Mf0/koDXIP+ZfhmrYAGvn33HrA+stTtOmlnJgO5MbCu47I0vzAyr2lvprNYGFpEuxwaVBJB8SnEtUMCQRML09WyEUntFwaaqvyaEvrBPcwr+aP0nRdsBoToY4JmfTWtHMDWogCr2l7FsCdGz4llbsBxtZZbQGrALHYHuZyNCkFy25g2rVkpYzaXcrtFtew3Jf3lyAsTxbX1QxcI9m5aGv7hqW8kbRE6ZPeY+FhstVeWLdW/oYAcP5MOERa4HdQxAMNB+78dQ43+2Pju2tORGxyieSZXiq3czoV61oTENtDWFLG0Ae3iNmjJ0L0JXt2U6Eusx0QdBOB+girYzbaFd1mfeXWk1c2KKdoD4OoCJsTtD0vBgRDOmnzAib950Gau0J3btMfH4EG4ALrvo99y+itSCp5KfMXT6AnECueqOQ1ArXSsxEOLav8AdDXYB+qHqfJi3KDDm9taiZnHxGyWL8o2QzkbYjuN6Mxqi+HzGNYFAB5EjX/sesOrAAbB8QVdMGG0udj2WZq7xg3+lg0OTb8zrP8AM6p/C7qg2TPSPVcg1BGyrErTekDHUbI4t1GtULLci3JbjWp4b94QK6wojgPWU3ra6jv07GRxog67dxAQR2P4bMlRsL3Md2Y7Yyq0owPjyJ6dVjXVqwAP7z7xUh46l52dgx7QuzMleZLeYGZT2MGT8r9llqIO8e57PoPj7CAZwmO70j8jEb9/rBnBgNjRgyaTWNsAQRL7uZOvaGWrxb7GOlJ+BCxZiTB9olRJrX8OQAaifiY1K2ISSfef/9k=\"\n        }\n    ]\n}\n"
  },
  {
    "path": "examples/react_admin/frontend/src/vite-env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\n"
  },
  {
    "path": "examples/react_admin/frontend/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"lib\": [\n      \"dom\",\n      \"dom.iterable\",\n      \"esnext\"\n    ],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true,\n    \"jsx\": \"react-jsx\"\n  },\n  \"include\": [\n    \"src\"\n  ]\n}\n"
  },
  {
    "path": "examples/react_admin/frontend/vite.config.ts",
    "content": "import { defineConfig } from 'vite';\nimport react from '@vitejs/plugin-react';\n\n// https://vitejs.dev/config/\nexport default defineConfig({\n    plugins: [react()],\n    define: {\n        'process.env': process.env,\n    },\n    server: {\n        host: true,\n    },\n    base: './',\n});\n"
  },
  {
    "path": "examples/rocket_example/Cargo.toml",
    "content": "[package]\nauthors      = [\"Sam Samai <sam@studio2pi.com.au>\"]\nedition      = \"2024\"\nname         = \"sea-orm-rocket-example\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[workspace]\nmembers = [\".\", \"api\", \"entity\", \"migration\"]\n\n[dependencies]\nrocket-example-api = { path = \"api\" }\n"
  },
  {
    "path": "examples/rocket_example/README.md",
    "content": "![screenshot](Screenshot.png)\n\n# Rocket with SeaORM example app\n\n1. Modify the `url` var in `api/Rocket.toml` to point to your chosen database\n\n1. Turn on the appropriate database feature for your chosen db in `api/Cargo.toml` (the `\"sqlx-postgres\",` line)\n\n1. Execute `cargo run` to start the server\n\n1. Visit [localhost:8000](http://localhost:8000) in browser after seeing the `🚀 Rocket has launched from http://localhost:8000` line\n\nRun tests:\n\n```bash\ncd api\ncargo test\n```"
  },
  {
    "path": "examples/rocket_example/Rocket.toml",
    "content": "[default]\ntemplate_dir = \"api/templates/\"\n\n[default.databases.sea_orm]\n# Mysql\n# make sure to enable \"sqlx-mysql\" feature in Cargo.toml, i.e default = [\"sqlx-mysql\"]\n# url = \"mysql://root:@localhost/rocket_example\"\n\n# Postgres\n# make sure to enable \"sqlx-postgres\" feature in Cargo.toml, i.e default = [\"sqlx-postgres\"]\n# url = \"postgres://root:root@localhost/rocket_example\"\n\n# SQLite\n# make sure to enable \"sqlx-sqlite\" feature in Cargo.toml, i.e default = [\"sqlx-sqlite\"]\nurl = \"sqlite::memory:\"\n"
  },
  {
    "path": "examples/rocket_example/api/Cargo.toml",
    "content": "[package]\nauthors      = [\"Sam Samai <sam@studio2pi.com.au>\"]\nedition      = \"2024\"\nname         = \"rocket-example-api\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nasync-stream         = { version = \"0.3\" }\nasync-trait          = { version = \"0.1\" }\nentity               = { path = \"../entity\" }\nfutures              = { version = \"0.3\" }\nfutures-util         = { version = \"0.3\" }\nmigration            = { path = \"../migration\" }\nrocket               = { version = \"0.5\", features = [\"json\"] }\nrocket_db_pools      = \"0.2\"\nrocket_dyn_templates = { version = \"0.2\", features = [\"tera\"] }\nserde_json           = { version = \"1\" }\ntokio                = \"1.41\"\n\n[dependencies.sea-orm-rocket]\npath    = \"../../../sea-orm-rocket/lib\" # remove this line in your own project\nversion = \"0.6\"\n\n[dependencies.sea-orm]\nfeatures = [\n    \"debug-print\",\n    \"runtime-tokio-native-tls\",\n    \"sqlx-postgres\",\n    # \"sqlx-mysql\",\n    # \"sqlx-sqlite\",\n]\npath = \"../../../\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n\n[dev-dependencies]\nrocket-example-api = { path = \".\", features = [\"sqlite\"] }\n\n[features]\nsqlite = [\"sea-orm/sqlx-sqlite\"]\n"
  },
  {
    "path": "examples/rocket_example/api/src/lib.rs",
    "content": "#[macro_use]\nextern crate rocket;\n\nuse rocket::fairing::{self, AdHoc};\nuse rocket::form::{Context, Form};\nuse rocket::fs::{FileServer, relative};\nuse rocket::request::FlashMessage;\nuse rocket::response::{Flash, Redirect};\nuse rocket::{Build, Request, Rocket};\nuse rocket_dyn_templates::Template;\nuse serde_json::json;\n\nuse migration::MigratorTrait;\nuse rocket_db_pools::{Connection, Database};\nuse service::{Mutation, Query};\n\nmod pool;\npub mod service;\nuse pool::Db;\n\npub use entity::post;\npub use entity::post::Entity as Post;\n\nconst DEFAULT_POSTS_PER_PAGE: u64 = 5;\n\n#[get(\"/new\")]\nasync fn new() -> Template {\n    Template::render(\"new\", &Context::default())\n}\n\n#[post(\"/\", data = \"<post_form>\")]\nasync fn create(conn: Connection<Db>, post_form: Form<post::Model>) -> Flash<Redirect> {\n    let db = conn.into_inner();\n\n    let form = post_form.into_inner();\n\n    Mutation::create_post(&db, form)\n        .await\n        .expect(\"could not insert post\");\n\n    Flash::success(Redirect::to(\"/\"), \"Post successfully added.\")\n}\n\n#[post(\"/<id>\", data = \"<post_form>\")]\nasync fn update(conn: Connection<Db>, id: i32, post_form: Form<post::Model>) -> Flash<Redirect> {\n    let db = conn.into_inner();\n\n    let form = post_form.into_inner();\n\n    Mutation::update_post_by_id(&db, id, form)\n        .await\n        .expect(\"could not update post\");\n\n    Flash::success(Redirect::to(\"/\"), \"Post successfully edited.\")\n}\n\n#[get(\"/?<page>&<posts_per_page>\")]\nasync fn list(\n    conn: Connection<Db>,\n    page: Option<u64>,\n    posts_per_page: Option<u64>,\n    flash: Option<FlashMessage<'_>>,\n) -> Template {\n    let db = conn.into_inner();\n\n    // Set page number and items per page\n    let page = page.unwrap_or(1);\n    let posts_per_page = posts_per_page.unwrap_or(DEFAULT_POSTS_PER_PAGE);\n    if page == 0 {\n        panic!(\"Page number cannot be zero\");\n    }\n\n    let (posts, num_pages) = Query::find_posts_in_page(&db, page, posts_per_page)\n        .await\n        .expect(\"Cannot find posts in page\");\n\n    Template::render(\n        \"index\",\n        json! ({\n            \"page\": page,\n            \"posts_per_page\": posts_per_page,\n            \"num_pages\": num_pages,\n            \"posts\": posts,\n            \"flash\": flash.map(FlashMessage::into_inner),\n        }),\n    )\n}\n\n#[get(\"/<id>\")]\nasync fn edit(conn: Connection<Db>, id: i32) -> Template {\n    let db = conn.into_inner();\n\n    let post: Option<post::Model> = Query::find_post_by_id(&db, id)\n        .await\n        .expect(\"could not find post\");\n\n    Template::render(\n        \"edit\",\n        json! ({\n            \"post\": post,\n        }),\n    )\n}\n\n#[delete(\"/<id>\")]\nasync fn delete(conn: Connection<Db>, id: i32) -> Flash<Redirect> {\n    let db = conn.into_inner();\n\n    Mutation::delete_post(&db, id)\n        .await\n        .expect(\"could not delete post\");\n\n    Flash::success(Redirect::to(\"/\"), \"Post successfully deleted.\")\n}\n\n#[delete(\"/\")]\nasync fn destroy(conn: Connection<Db>) -> Result<(), rocket::response::Debug<String>> {\n    let db = conn.into_inner();\n\n    Mutation::delete_all_posts(&db)\n        .await\n        .map_err(|e| e.to_string())?;\n\n    Ok(())\n}\n\n#[catch(404)]\npub fn not_found(req: &Request<'_>) -> Template {\n    Template::render(\n        \"error/404\",\n        json! ({\n            \"uri\": req.uri()\n        }),\n    )\n}\n\nasync fn run_migrations(rocket: Rocket<Build>) -> fairing::Result {\n    let conn = &Db::fetch(&rocket).unwrap().conn;\n    let _ = migration::Migrator::up(conn, None).await;\n    Ok(rocket)\n}\n\n#[tokio::main]\nasync fn start() -> Result<(), rocket::Error> {\n    rocket::build()\n        .attach(Db::init())\n        .attach(AdHoc::try_on_ignite(\"Migrations\", run_migrations))\n        .mount(\"/\", FileServer::from(relative!(\"/static\")))\n        .mount(\n            \"/\",\n            routes![new, create, delete, destroy, list, edit, update],\n        )\n        .register(\"/\", catchers![not_found])\n        .attach(Template::fairing())\n        .launch()\n        .await\n        .map(|_| ())\n}\n\npub fn main() {\n    let result = start();\n\n    println!(\"Rocket: deorbit.\");\n\n    if let Some(err) = result.err() {\n        println!(\"Error: {err}\");\n    }\n}\n"
  },
  {
    "path": "examples/rocket_example/api/src/pool.rs",
    "content": "use async_trait::async_trait;\nuse rocket_db_pools::Database;\nuse sea_orm::ConnectOptions;\nuse sea_orm_rocket::{Config, rocket::figment::Figment};\nuse std::time::Duration;\n\n#[derive(Database, Debug)]\n#[database(\"sea_orm\")]\npub struct Db(SeaOrmPool);\n\n#[derive(Debug, Clone)]\npub struct SeaOrmPool {\n    pub conn: sea_orm::DatabaseConnection,\n}\n\n#[async_trait]\nimpl rocket_db_pools::Pool for SeaOrmPool {\n    type Error = sea_orm::DbErr;\n\n    type Connection = sea_orm::DatabaseConnection;\n\n    async fn init(figment: &Figment) -> Result<Self, Self::Error> {\n        let config = figment.extract::<Config>().unwrap();\n        let mut options: ConnectOptions = config.url.into();\n        options\n            .max_connections(config.max_connections as u32)\n            .min_connections(config.min_connections.unwrap_or_default())\n            .connect_timeout(Duration::from_secs(config.connect_timeout))\n            .sqlx_logging(config.sqlx_logging);\n        if let Some(idle_timeout) = config.idle_timeout {\n            options.idle_timeout(Duration::from_secs(idle_timeout));\n        }\n        let conn = sea_orm::Database::connect(options).await?;\n\n        Ok(SeaOrmPool { conn })\n    }\n\n    async fn get(&self) -> Result<Self::Connection, Self::Error> {\n        Ok(self.conn.clone())\n    }\n\n    // DatabaseConnection automatically closes on drop\n    async fn close(&self) {}\n}\n"
  },
  {
    "path": "examples/rocket_example/api/src/service/mod.rs",
    "content": "mod mutation;\nmod query;\n\npub use mutation::*;\npub use query::*;\n"
  },
  {
    "path": "examples/rocket_example/api/src/service/mutation.rs",
    "content": "use entity::{post, post::Entity as Post};\nuse sea_orm::{DbConn, DbErr, DeleteResult, entity::*};\n\npub struct Mutation;\n\nimpl Mutation {\n    pub async fn create_post(\n        db: &DbConn,\n        form_data: post::Model,\n    ) -> Result<post::ActiveModel, DbErr> {\n        post::ActiveModel {\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n            ..Default::default()\n        }\n        .save(db)\n        .await\n    }\n\n    pub async fn update_post_by_id(\n        db: &DbConn,\n        id: i32,\n        form_data: post::Model,\n    ) -> Result<post::Model, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post::ActiveModel {\n            id: post.id,\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n        }\n        .update(db)\n        .await\n    }\n\n    pub async fn delete_post(db: &DbConn, id: i32) -> Result<DeleteResult, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post.delete(db).await\n    }\n\n    pub async fn delete_all_posts(db: &DbConn) -> Result<DeleteResult, DbErr> {\n        Post::delete_many().exec(db).await\n    }\n}\n"
  },
  {
    "path": "examples/rocket_example/api/src/service/query.rs",
    "content": "use entity::{post, post::Entity as Post};\nuse sea_orm::{DbConn, DbErr, EntityTrait, PaginatorTrait, QueryOrder};\n\npub struct Query;\n\nimpl Query {\n    pub async fn find_post_by_id(db: &DbConn, id: i32) -> Result<Option<post::Model>, DbErr> {\n        Post::find_by_id(id).one(db).await\n    }\n\n    /// If ok, returns (post models, num pages).\n    pub async fn find_posts_in_page(\n        db: &DbConn,\n        page: u64,\n        posts_per_page: u64,\n    ) -> Result<(Vec<post::Model>, u64), DbErr> {\n        // Setup paginator\n        let paginator = Post::find()\n            .order_by_asc(post::Column::Id)\n            .paginate(db, posts_per_page);\n        let num_pages = paginator.num_pages().await?;\n\n        // Fetch paginated posts\n        paginator.fetch_page(page - 1).await.map(|p| (p, num_pages))\n    }\n}\n"
  },
  {
    "path": "examples/rocket_example/api/static/css/normalize.css",
    "content": "/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\n\n/**\n * 1. Set default font family to sans-serif.\n * 2. Prevent iOS text size adjust after orientation change, without disabling\n *    user zoom.\n */\n\nhtml {\n  font-family: sans-serif; /* 1 */\n  -ms-text-size-adjust: 100%; /* 2 */\n  -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/**\n * Remove default margin.\n */\n\nbody {\n  margin: 0;\n}\n\n/* HTML5 display definitions\n   ========================================================================== */\n\n/**\n * Correct `block` display not defined for any HTML5 element in IE 8/9.\n * Correct `block` display not defined for `details` or `summary` in IE 10/11\n * and Firefox.\n * Correct `block` display not defined for `main` in IE 11.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n/**\n * 1. Correct `inline-block` display not defined in IE 8/9.\n * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n */\n\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block; /* 1 */\n  vertical-align: baseline; /* 2 */\n}\n\n/**\n * Prevent modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n/**\n * Address `[hidden]` styling not present in IE 8/9/10.\n * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.\n */\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n/* Links\n   ========================================================================== */\n\n/**\n * Remove the gray background color from active links in IE 10.\n */\n\na {\n  background-color: transparent;\n}\n\n/**\n * Improve readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n  outline: 0;\n}\n\n/* Text-level semantics\n   ========================================================================== */\n\n/**\n * Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n */\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n/**\n * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n */\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n/**\n * Address styling not present in Safari and Chrome.\n */\n\ndfn {\n  font-style: italic;\n}\n\n/**\n * Address variable `h1` font-size and margin within `section` and `article`\n * contexts in Firefox 4+, Safari, and Chrome.\n */\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n/**\n * Address styling not present in IE 8/9.\n */\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n/**\n * Address inconsistent and variable font size in all browsers.\n */\n\nsmall {\n  font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n/* Embedded content\n   ========================================================================== */\n\n/**\n * Remove border when inside `a` element in IE 8/9/10.\n */\n\nimg {\n  border: 0;\n}\n\n/**\n * Correct overflow not hidden in IE 9/10/11.\n */\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n/* Grouping content\n   ========================================================================== */\n\n/**\n * Address margin not present in IE 8/9 and Safari.\n */\n\nfigure {\n  margin: 1em 40px;\n}\n\n/**\n * Address differences between Firefox and other browsers.\n */\n\nhr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\n\n/**\n * Contain overflow in all browsers.\n */\n\npre {\n  overflow: auto;\n}\n\n/**\n * Address odd `em`-unit font size rendering in all browsers.\n */\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n/* Forms\n   ========================================================================== */\n\n/**\n * Known limitation: by default, Chrome and Safari on OS X allow very limited\n * styling of `select`, unless a `border` property is set.\n */\n\n/**\n * 1. Correct color not being inherited.\n *    Known issue: affects color of disabled elements.\n * 2. Correct font properties not being inherited.\n * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit; /* 1 */\n  font: inherit; /* 2 */\n  margin: 0; /* 3 */\n}\n\n/**\n * Address `overflow` set to `hidden` in IE 8/9/10/11.\n */\n\nbutton {\n  overflow: visible;\n}\n\n/**\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\n * All other form control elements do not inherit `text-transform` values.\n * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n * Correct `select` style inheritance in Firefox.\n */\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n/**\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *    and `video` controls.\n * 2. Correct inability to style clickable `input` types in iOS.\n * 3. Improve usability and consistency of cursor style between image-type\n *    `input` and others.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; /* 2 */\n  cursor: pointer; /* 3 */\n}\n\n/**\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n/**\n * Remove inner padding and border in Firefox 4+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n/**\n * Address Firefox 4+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\ninput {\n  line-height: normal;\n}\n\n/**\n * It's recommended that you don't attempt to style these elements.\n * Firefox's implementation doesn't respect box-sizing, padding, or width.\n *\n * 1. Address box sizing set to `content-box` in IE 8/9/10.\n * 2. Remove excess padding in IE 8/9/10.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Fix the cursor style for Chrome's increment/decrement buttons. For certain\n * `font-size` values of the `input`, it causes the cursor style of the\n * decrement button to change from `default` to `text`.\n */\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n/**\n * 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n * 2. Address `box-sizing` set to `border-box` in Safari and Chrome\n *    (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; /* 1 */\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box; /* 2 */\n  box-sizing: content-box;\n}\n\n/**\n * Remove inner padding and search cancel button in Safari and Chrome on OS X.\n * Safari (but not Chrome) clips the cancel button when the search input has\n * padding (and `textfield` appearance).\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n/**\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n/**\n * 1. Correct `color` not being inherited in IE 8/9/10/11.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\n\nlegend {\n  border: 0; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Remove default vertical scrollbar in IE 8/9/10/11.\n */\n\ntextarea {\n  overflow: auto;\n}\n\n/**\n * Don't inherit the `font-weight` (applied by a rule above).\n * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n */\n\noptgroup {\n  font-weight: bold;\n}\n\n/* Tables\n   ========================================================================== */\n\n/**\n * Remove most spacing between table cells.\n */\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n"
  },
  {
    "path": "examples/rocket_example/api/static/css/skeleton.css",
    "content": "/*\n* Skeleton V2.0.4\n* Copyright 2014, Dave Gamache\n* www.getskeleton.com\n* Free to use under the MIT license.\n* https://opensource.org/licenses/mit-license.php\n* 12/29/2014\n*/\n\n\n/* Table of contents\n––––––––––––––––––––––––––––––––––––––––––––––––––\n- Grid\n- Base Styles\n- Typography\n- Links\n- Buttons\n- Forms\n- Lists\n- Code\n- Tables\n- Spacing\n- Utilities\n- Clearing\n- Media Queries\n*/\n\n\n/* Grid\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.container {\n  position: relative;\n  width: 100%;\n  max-width: 960px;\n  margin: 0 auto;\n  padding: 0 20px;\n  box-sizing: border-box; }\n.column,\n.columns {\n  width: 100%;\n  float: left;\n  box-sizing: border-box; }\n\n/* For devices larger than 400px */\n@media (min-width: 400px) {\n  .container {\n    width: 85%;\n    padding: 0; }\n}\n\n/* For devices larger than 550px */\n@media (min-width: 550px) {\n  .container {\n    width: 80%; }\n  .column,\n  .columns {\n    margin-left: 4%; }\n  .column:first-child,\n  .columns:first-child {\n    margin-left: 0; }\n\n  .one.column,\n  .one.columns                    { width: 4.66666666667%; }\n  .two.columns                    { width: 13.3333333333%; }\n  .three.columns                  { width: 22%;            }\n  .four.columns                   { width: 30.6666666667%; }\n  .five.columns                   { width: 39.3333333333%; }\n  .six.columns                    { width: 48%;            }\n  .seven.columns                  { width: 56.6666666667%; }\n  .eight.columns                  { width: 65.3333333333%; }\n  .nine.columns                   { width: 74.0%;          }\n  .ten.columns                    { width: 82.6666666667%; }\n  .eleven.columns                 { width: 91.3333333333%; }\n  .twelve.columns                 { width: 100%; margin-left: 0; }\n\n  .one-third.column               { width: 30.6666666667%; }\n  .two-thirds.column              { width: 65.3333333333%; }\n\n  .one-half.column                { width: 48%; }\n\n  /* Offsets */\n  .offset-by-one.column,\n  .offset-by-one.columns          { margin-left: 8.66666666667%; }\n  .offset-by-two.column,\n  .offset-by-two.columns          { margin-left: 17.3333333333%; }\n  .offset-by-three.column,\n  .offset-by-three.columns        { margin-left: 26%;            }\n  .offset-by-four.column,\n  .offset-by-four.columns         { margin-left: 34.6666666667%; }\n  .offset-by-five.column,\n  .offset-by-five.columns         { margin-left: 43.3333333333%; }\n  .offset-by-six.column,\n  .offset-by-six.columns          { margin-left: 52%;            }\n  .offset-by-seven.column,\n  .offset-by-seven.columns        { margin-left: 60.6666666667%; }\n  .offset-by-eight.column,\n  .offset-by-eight.columns        { margin-left: 69.3333333333%; }\n  .offset-by-nine.column,\n  .offset-by-nine.columns         { margin-left: 78.0%;          }\n  .offset-by-ten.column,\n  .offset-by-ten.columns          { margin-left: 86.6666666667%; }\n  .offset-by-eleven.column,\n  .offset-by-eleven.columns       { margin-left: 95.3333333333%; }\n\n  .offset-by-one-third.column,\n  .offset-by-one-third.columns    { margin-left: 34.6666666667%; }\n  .offset-by-two-thirds.column,\n  .offset-by-two-thirds.columns   { margin-left: 69.3333333333%; }\n\n  .offset-by-one-half.column,\n  .offset-by-one-half.columns     { margin-left: 52%; }\n\n}\n\n\n/* Base Styles\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n/* NOTE\nhtml is set to 62.5% so that all the REM measurements throughout Skeleton\nare based on 10px sizing. So basically 1.5rem = 15px :) */\nhtml {\n  font-size: 62.5%; }\nbody {\n  font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */\n  line-height: 1.6;\n  font-weight: 400;\n  font-family: \"Raleway\", \"HelveticaNeue\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  color: #222; }\n\n\n/* Typography\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nh1, h2, h3, h4, h5, h6 {\n  margin-top: 0;\n  margin-bottom: 2rem;\n  font-weight: 300; }\nh1 { font-size: 4.0rem; line-height: 1.2;  letter-spacing: -.1rem;}\nh2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; }\nh3 { font-size: 3.0rem; line-height: 1.3;  letter-spacing: -.1rem; }\nh4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; }\nh5 { font-size: 1.8rem; line-height: 1.5;  letter-spacing: -.05rem; }\nh6 { font-size: 1.5rem; line-height: 1.6;  letter-spacing: 0; }\n\n/* Larger than phablet */\n@media (min-width: 550px) {\n  h1 { font-size: 5.0rem; }\n  h2 { font-size: 4.2rem; }\n  h3 { font-size: 3.6rem; }\n  h4 { font-size: 3.0rem; }\n  h5 { font-size: 2.4rem; }\n  h6 { font-size: 1.5rem; }\n}\n\np {\n  margin-top: 0; }\n\n\n/* Links\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\na {\n  color: #1EAEDB; }\na:hover {\n  color: #0FA0CE; }\n\n\n/* Buttons\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.button,\nbutton,\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n  display: inline-block;\n  height: 38px;\n  padding: 0 30px;\n  color: #555;\n  text-align: center;\n  font-size: 11px;\n  font-weight: 600;\n  line-height: 38px;\n  letter-spacing: .1rem;\n  text-transform: uppercase;\n  text-decoration: none;\n  white-space: nowrap;\n  background-color: transparent;\n  border-radius: 4px;\n  border: 1px solid #bbb;\n  cursor: pointer;\n  box-sizing: border-box; }\n.button:hover,\nbutton:hover,\ninput[type=\"submit\"]:hover,\ninput[type=\"reset\"]:hover,\ninput[type=\"button\"]:hover,\n.button:focus,\nbutton:focus,\ninput[type=\"submit\"]:focus,\ninput[type=\"reset\"]:focus,\ninput[type=\"button\"]:focus {\n  color: #333;\n  border-color: #888;\n  outline: 0; }\n.button.button-primary,\nbutton.button-primary,\nbutton.primary,\ninput[type=\"submit\"].button-primary,\ninput[type=\"reset\"].button-primary,\ninput[type=\"button\"].button-primary {\n  color: #FFF;\n  background-color: #33C3F0;\n  border-color: #33C3F0; }\n.button.button-primary:hover,\nbutton.button-primary:hover,\nbutton.primary:hover,\ninput[type=\"submit\"].button-primary:hover,\ninput[type=\"reset\"].button-primary:hover,\ninput[type=\"button\"].button-primary:hover,\n.button.button-primary:focus,\nbutton.button-primary:focus,\nbutton.primary:focus,\ninput[type=\"submit\"].button-primary:focus,\ninput[type=\"reset\"].button-primary:focus,\ninput[type=\"button\"].button-primary:focus {\n  color: #FFF;\n  background-color: #1EAEDB;\n  border-color: #1EAEDB; }\n\n\n/* Forms\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ninput[type=\"text\"],\ninput[type=\"tel\"],\ninput[type=\"url\"],\ninput[type=\"password\"],\ntextarea,\nselect {\n  height: 38px;\n  padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */\n  background-color: #fff;\n  border: 1px solid #D1D1D1;\n  border-radius: 4px;\n  box-shadow: none;\n  box-sizing: border-box; }\n/* Removes awkward default styles on some inputs for iOS */\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ninput[type=\"text\"],\ninput[type=\"tel\"],\ninput[type=\"url\"],\ninput[type=\"password\"],\ntextarea {\n  -webkit-appearance: none;\n     -moz-appearance: none;\n          appearance: none; }\ntextarea {\n  min-height: 65px;\n  padding-top: 6px;\n  padding-bottom: 6px; }\ninput[type=\"email\"]:focus,\ninput[type=\"number\"]:focus,\ninput[type=\"search\"]:focus,\ninput[type=\"text\"]:focus,\ninput[type=\"tel\"]:focus,\ninput[type=\"url\"]:focus,\ninput[type=\"password\"]:focus,\ntextarea:focus,\nselect:focus {\n  border: 1px solid #33C3F0;\n  outline: 0; }\nlabel,\nlegend {\n  display: block;\n  margin-bottom: .5rem;\n  font-weight: 600; }\nfieldset {\n  padding: 0;\n  border-width: 0; }\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  display: inline; }\nlabel > .label-body {\n  display: inline-block;\n  margin-left: .5rem;\n  font-weight: normal; }\n\n\n/* Lists\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nul {\n  list-style: circle inside; }\nol {\n  list-style: decimal inside; }\nol, ul {\n  padding-left: 0;\n  margin-top: 0; }\nul ul,\nul ol,\nol ol,\nol ul {\n  margin: 1.5rem 0 1.5rem 3rem;\n  font-size: 90%; }\nli {\n  margin-bottom: 1rem; }\n\n\n/* Code\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\ncode {\n  padding: .2rem .5rem;\n  margin: 0 .2rem;\n  font-size: 90%;\n  white-space: nowrap;\n  background: #F1F1F1;\n  border: 1px solid #E1E1E1;\n  border-radius: 4px; }\npre > code {\n  display: block;\n  padding: 1rem 1.5rem;\n  white-space: pre; }\n\n\n/* Tables\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nth,\ntd {\n  padding: 12px 15px;\n  text-align: left;\n  border-bottom: 1px solid #E1E1E1; }\nth:first-child,\ntd:first-child {\n  padding-left: 0; }\nth:last-child,\ntd:last-child {\n  padding-right: 0; }\n\n\n/* Spacing\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nbutton,\n.button {\n  margin-bottom: 1rem; }\ninput,\ntextarea,\nselect,\nfieldset {\n  margin-bottom: 1.5rem; }\npre,\nblockquote,\ndl,\nfigure,\ntable,\np,\nul,\nol,\nform {\n  margin-bottom: 2.5rem; }\n\n\n/* Utilities\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.u-full-width {\n  width: 100%;\n  box-sizing: border-box; }\n.u-max-full-width {\n  max-width: 100%;\n  box-sizing: border-box; }\n.u-pull-right {\n  float: right; }\n.u-pull-left {\n  float: left; }\n\n\n/* Misc\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nhr {\n  margin-top: 3rem;\n  margin-bottom: 3.5rem;\n  border-width: 0;\n  border-top: 1px solid #E1E1E1; }\n\n\n/* Clearing\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n\n/* Self Clearing Goodness */\n.container:after,\n.row:after,\n.u-cf {\n  content: \"\";\n  display: table;\n  clear: both; }\n\n\n/* Media Queries\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n/*\nNote: The best way to structure the use of media queries is to create the queries\nnear the relevant code. For example, if you wanted to change the styles for buttons\non small devices, paste the mobile query code up in the buttons section and style it\nthere.\n*/\n\n\n/* Larger than mobile */\n@media (min-width: 400px) {}\n\n/* Larger than phablet (also point when grid becomes active) */\n@media (min-width: 550px) {}\n\n/* Larger than tablet */\n@media (min-width: 750px) {}\n\n/* Larger than desktop */\n@media (min-width: 1000px) {}\n\n/* Larger than Desktop HD */\n@media (min-width: 1200px) {}\n"
  },
  {
    "path": "examples/rocket_example/api/static/css/style.css",
    "content": ".field-error {\n  border: 1px solid #ff0000 !important;\n}\n\n.field-error-flash {\n  color: #ff0000;\n  display: block;\n  margin: -10px 0 10px 0;\n}\n\n.field-success {\n  border: 1px solid #5ab953 !important;\n}\n\n.field-success-flash {\n  color: #5ab953;\n  display: block;\n  margin: -10px 0 10px 0;\n}\n\nspan.completed {\n  text-decoration: line-through;\n}\n\nform.inline {\n  display: inline;\n}\n\nform.link,\nbutton.link {\n  display: inline;\n  color: #1eaedb;\n  border: none;\n  outline: none;\n  background: none;\n  cursor: pointer;\n  padding: 0;\n  margin: 0 0 0 0;\n  height: inherit;\n  text-decoration: underline;\n  font-size: inherit;\n  text-transform: none;\n  font-weight: normal;\n  line-height: inherit;\n  letter-spacing: inherit;\n}\n\nform.link:hover,\nbutton.link:hover {\n  color: #0fa0ce;\n}\n\nbutton.small {\n  height: 20px;\n  padding: 0 10px;\n  font-size: 10px;\n  line-height: 20px;\n  margin: 0 2.5px;\n}\n\n.post:hover {\n  background-color: #bce2ee;\n}\n\n.post td {\n  padding: 5px;\n  width: 150px;\n}\n\n#delete-button {\n  color: red;\n  border-color: red;\n}\n"
  },
  {
    "path": "examples/rocket_example/api/templates/base.html.tera",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>Rocket SeaORM Example</title>\n    <meta name=\"description\" content=\"Example Rocket - SeaORM integration\" />\n    <meta name=\"author\" content=\"Sam Samai\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\n    <link\n      href=\"//fonts.googleapis.com/css?family=Raleway:400,300,600\"\n      rel=\"stylesheet\"\n      type=\"text/css\"\n    />\n    <link rel=\"stylesheet\" href=\"/css/normalize.css\" />\n    <link rel=\"stylesheet\" href=\"/css/skeleton.css\" />\n    <link rel=\"stylesheet\" href=\"/css/style.css\" />\n    <link rel=\"icon\" type=\"image/png\" href=\"/images/favicon.png\" />\n  </head>\n  <body>\n    <div class=\"container\">\n      <p><!--Nothing to see here --></p>\n      {% block content %}{% endblock content %}\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/rocket_example/api/templates/edit.html.tera",
    "content": "{% extends \"base\" %} {% block content %}\n<div class=\"row\">\n  <h4>Edit Post</h4>\n  <div class=\"twelve columns\">\n    <div class=\"ten columns\">\n      <form action=\"/{{ post.id }}\" method=\"post\">\n        <div class=\"twelve columns\">\n          <input\n            type=\"hidden\"\n            name=\"id\"\n            id=\"id\"\n            value=\"0\"\n          />\n          <input\n            type=\"text\"\n            placeholder=\"title\"\n            name=\"title\"\n            id=\"title\"\n            value=\"{{ post.title }}\"\n            autofocus\n            class=\"u-full-width\"\n          />\n          <input\n            type=\"text\"\n            placeholder=\"content\"\n            name=\"text\"\n            id=\"text\"\n            value=\"{{ post.text }}\"\n            autofocus\n            class=\"u-full-width\"\n          />\n        </div>\n        <div class=\"twelve columns\">\n          <div class=\"two columns\">\n            <a href=\"/\">\n              <input type=\"button\" value=\"cancel\" />\n            </a>\n          </div>\n          <div class=\"eight columns\"></div>\n          <div class=\"two columns\">\n            <input type=\"submit\" value=\"save post\" />\n          </div>\n        </div>\n      </form>\n    </div>\n    <div class=\"two columns\">\n      <form action=\"/{{ post.id }}\" method=\"post\">\n        <div class=\"two columns\">\n          <input type=\"hidden\" name=\"_method\" value=\"delete\" />\n          <input id=\"delete-button\" type=\"submit\" value=\"delete post\" />\n        </div>\n      </form>\n    </div>\n  </div>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/rocket_example/api/templates/error/404.html.tera",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>404 - tera</title>\n  </head>\n  <body>\n    <h1>404: Hey! There's nothing here.</h1>\n    The page at {{ uri }} does not exist!\n  </body>\n</html>\n"
  },
  {
    "path": "examples/rocket_example/api/templates/index.html.tera",
    "content": "{% extends \"base\" %} {% block content %}\n<h1>Posts</h1>\n{% if flash %}\n<small class=\"field-{{ flash.0 }}-flash\">\n  {{ flash.1 }}\n</small>\n{% endif %}\n<table>\n  <tbody>\n    <thead>\n      <tr>\n        <th>ID</th>\n        <th>Title</th>\n        <th>Text</th>\n      </tr>\n    </thead>\n    {% for post in posts %}\n    <tr class=\"post\" onclick=\"window.location='/{{ post.id }}';\">\n      <td>{{ post.id }}</td>\n      <td>{{ post.title }}</td>\n      <td>{{ post.text }}</td>\n    </tr>\n    {% endfor %}\n  </tbody>\n  <tfoot>\n    <tr>\n      <td></td>\n      <td>\n        {% if page == 1 %} Previous {% else %}\n        <a href=\"/?page={{ page - 1 }}&posts_per_page={{ posts_per_page }}\">Previous</a>\n        {% endif %} | {% if page == num_pages %} Next {% else %}\n        <a href=\"/?page={{ page + 1 }}&posts_per_page={{ posts_per_page }}\">Next</a>\n        {% endif %}\n      </td>\n      <td></td>\n    </tr>\n  </tfoot>\n</table>\n\n<div class=\"twelve columns\">\n  <a href=\"/new\">\n    <input type=\"button\" value=\"add post\" />\n  </a>\n</div>\n\n{% endblock content %}\n"
  },
  {
    "path": "examples/rocket_example/api/templates/new.html.tera",
    "content": "{% extends \"base\" %} {% block content %}\n<div class=\"row\">\n  <h4>New Post</h4>\n  <form action=\"/\" method=\"post\">\n    <div class=\"twelve columns\">\n      <input\n        type=\"hidden\"\n        name=\"id\"\n        id=\"id\"\n        value=\"0\"\n      />\n      <input\n        type=\"text\"\n        placeholder=\"enter title\"\n        name=\"title\"\n        id=\"title\"\n        value=\"\"\n        autofocus\n        class=\"u-full-width\"\n      />\n      <input\n        type=\"text\"\n        placeholder=\"enter content\"\n        name=\"text\"\n        id=\"text\"\n        value=\"\"\n        autofocus\n        class=\"u-full-width\"\n      />\n    </div>\n    <div class=\"twelve columns\">\n      <div class=\"two columns\">\n        <a href=\"/\">\n          <input type=\"button\" value=\"cancel\" />\n        </a>\n      </div>\n      <div class=\"eight columns\"></div>\n      <div class=\"two columns\">\n        <input type=\"submit\" value=\"save post\" />\n      </div>\n    </div>\n  </form>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/rocket_example/api/tests/crud_tests.rs",
    "content": "use entity::post;\nuse rocket_example_api::service::{Mutation, Query};\nuse sea_orm::Database;\n\n#[tokio::test]\nasync fn crud_tests() {\n    let db = &Database::connect(\"sqlite::memory:\").await.unwrap();\n\n    db.get_schema_builder()\n        .register(post::Entity)\n        .apply(db)\n        .await\n        .unwrap();\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title A\".to_owned(),\n                text: \"Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(1),\n                title: sea_orm::ActiveValue::Unchanged(\"Title A\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text A\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title B\".to_owned(),\n                text: \"Text B\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(2),\n                title: sea_orm::ActiveValue::Unchanged(\"Title B\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text B\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 1).await.unwrap().unwrap();\n\n        assert_eq!(post.id, 1);\n        assert_eq!(post.title, \"Title A\");\n    }\n\n    {\n        let post = Mutation::update_post_by_id(\n            db,\n            1,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            }\n        );\n    }\n\n    {\n        let result = Mutation::delete_post(db, 2).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 2).await.unwrap();\n        assert!(post.is_none());\n    }\n\n    {\n        let result = Mutation::delete_all_posts(db).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n}\n"
  },
  {
    "path": "examples/rocket_example/entity/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"entity\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"entity\"\npath = \"src/lib.rs\"\n\n[dependencies]\nrocket = { version = \"0.5\", features = [\"json\"] }\n\n[dependencies.sea-orm]\npath    = \"../../../\"    # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n"
  },
  {
    "path": "examples/rocket_example/entity/src/lib.rs",
    "content": "#[macro_use]\nextern crate rocket;\n\npub mod post;\n"
  },
  {
    "path": "examples/rocket_example/entity/src/post.rs",
    "content": "use rocket::serde::{Deserialize, Serialize};\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize, FromForm)]\n#[serde(crate = \"rocket::serde\")]\n#[sea_orm(table_name = \"post\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub title: String,\n    #[sea_orm(column_type = \"Text\")]\n    pub text: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/rocket_example/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nentity = { path = \"../entity\" }\ntokio  = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable following runtime and db backend features if you want to run migration via CLI\n    \"runtime-tokio-native-tls\",\n    \"sqlx-postgres\",\n]\npath = \"../../../sea-orm-migration\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/rocket_example/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/rocket_example/migration/src/lib.rs",
    "content": "pub use sea_orm_migration::prelude::*;\n\nmod m20220120_000001_create_post_table;\nmod m20220120_000002_seed_posts;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220120_000001_create_post_table::Migration),\n            Box::new(m20220120_000002_seed_posts::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "examples/rocket_example/migration/src/m20220120_000001_create_post_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"post\")\n                    .if_not_exists()\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"title\"))\n                    .col(string(\"text\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"post\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/rocket_example/migration/src/m20220120_000002_seed_posts.rs",
    "content": "use entity::post;\nuse sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};\nuse sea_orm_migration::prelude::*;\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let seed_data = vec![\n            (\"First Post\", \"This is the first post.\"),\n            (\"Second Post\", \"This is another post.\"),\n        ];\n\n        for (title, text) in seed_data {\n            let model = post::ActiveModel {\n                title: Set(title.to_string()),\n                text: Set(text.to_string()),\n                ..Default::default()\n            };\n            model.insert(db).await?;\n        }\n\n        println!(\"Posts table seeded successfully.\");\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let titles_to_delete = vec![\"First Post\", \"Second Post\"];\n        post::Entity::delete_many()\n            .filter(post::Column::Title.is_in(titles_to_delete))\n            .exec(db)\n            .await?;\n\n        println!(\"Posts seeded data removed.\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/rocket_example/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/rocket_example/src/main.rs",
    "content": "fn main() {\n    rocket_example_api::main();\n}\n"
  },
  {
    "path": "examples/rocket_okapi_example/Cargo.toml",
    "content": "[package]\nauthors = [\n    \"Sam Samai <sam@studio2pi.com.au>\",\n    \"Erick Pacheco <eum602@gmail.com\",\n]\nedition = \"2024\"\nname = \"sea-orm-rocket-okapi-example\"\npublish = false\nrust-version = \"1.85.0\"\nversion = \"0.1.0\"\n\n[workspace]\nmembers = [\".\", \"api\", \"service\", \"entity\", \"migration\", \"dto\"]\n\n[dependencies]\nrocket-example-api = { path = \"api\" }\n"
  },
  {
    "path": "examples/rocket_okapi_example/README.md",
    "content": "# Rocket and Rocket-API with SeaORM example app\n\n1. Modify the `url` var in `api/Rocket.toml` to point to your chosen database (or leave it as-is to use in-memory SQLite)\n\n1. If not using the SQLite DB: turn on the appropriate database feature for your chosen db in `api/Cargo.toml` (the `\"sqlx-postgres\",` line)\n\n1. Execute `cargo run` to start the server\n\n1. You can go to ```http://localhost:8000/swagger-ui/index.html``` to see the api documentation about this demo project.\n   ![swagger](swagger.png)\n1. Additionally, you can navigate to ```http://localhost:8000/rapidoc/index.html``` to see the rapidoc format for api documentation \n   ![rapidoc](rapidoc.png)\n"
  },
  {
    "path": "examples/rocket_okapi_example/Rocket.toml",
    "content": "[default]\ntemplate_dir = \"api/templates/\"\n\n[default.databases.sea_orm]\n# Mysql\n# make sure to enable \"sqlx-mysql\" feature in Cargo.toml, i.e default = [\"sqlx-mysql\"]\n# url = \"mysql://root:@localhost/rocket_example\"\n\n# Postgres\n# make sure to enable \"sqlx-postgres\" feature in Cargo.toml, i.e default = [\"sqlx-postgres\"]\n# url = \"postgres://user:pass@localhost:5432/rocket\"\n\n# SQLite\n# make sure to enable \"sqlx-sqlite\" feature in Cargo.toml, i.e default = [\"sqlx-sqlite\"]\nurl = \"sqlite::memory:\"\n"
  },
  {
    "path": "examples/rocket_okapi_example/api/Cargo.toml",
    "content": "[package]\nauthors      = [\"Sam Samai <sam@studio2pi.com.au>\"]\nedition      = \"2024\"\nname         = \"rocket-example-api\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nasync-stream = { version = \"0.3\" }\nasync-trait = { version = \"0.1\" }\ndto = { path = \"../dto\" }\nentity = { path = \"../entity\" }\nfutures = { version = \"0.3\" }\nfutures-util = { version = \"0.3\" }\nmigration = { path = \"../migration\" }\nrocket = { version = \"0.5\", features = [\"json\"] }\nrocket-okapi-example-service = { path = \"../service\" }\nrocket_cors = \"0.6\"\nrocket_db_pools = \"0.2\"\nrocket_dyn_templates = { version = \"0.2\", features = [\"tera\"] }\nrocket_okapi = { version = \"0.9\", features = [\n    \"swagger\",\n    \"rapidoc\",\n    \"rocket_db_pools\",\n] }\nserde = \"1.0\"\nserde_json = { version = \"1\" }\ntokio = \"1.41\"\n\n[dependencies.sea-orm-rocket]\nfeatures = [\n    \"rocket_okapi\",\n] # enables rocket_okapi so to have open api features enabled\npath = \"../../../sea-orm-rocket/lib\" # remove this line in your own project and use the version line\n# version = \"0.5\"\n"
  },
  {
    "path": "examples/rocket_okapi_example/api/src/error.rs",
    "content": "use rocket::{\n    http::{ContentType, Status},\n    request::Request,\n    response::{self, Responder, Response},\n};\nuse rocket_okapi::okapi::openapi3::Responses;\nuse rocket_okapi::okapi::schemars::{self, Map};\nuse rocket_okapi::{OpenApiError, r#gen::OpenApiGenerator, response::OpenApiResponderInner};\n\n/// Error messages returned to user\n#[derive(Debug, serde::Serialize, schemars::JsonSchema)]\npub struct Error {\n    /// The title of the error message\n    pub err: String,\n    /// The description of the error\n    pub msg: Option<String>,\n    // HTTP Status Code returned\n    #[serde(skip)]\n    pub http_status_code: u16,\n}\n\nimpl OpenApiResponderInner for Error {\n    fn responses(_generator: &mut OpenApiGenerator) -> Result<Responses, OpenApiError> {\n        use rocket_okapi::okapi::openapi3::{RefOr, Response as OpenApiResponse};\n\n        let mut responses = Map::new();\n        responses.insert(\n            \"400\".to_string(),\n            RefOr::Object(OpenApiResponse {\n                description: \"\\\n                # [400 Bad Request](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400)\\n\\\n                The request given is wrongly formatted or data asked could not be fulfilled. \\\n                \"\n                .to_string(),\n                ..Default::default()\n            }),\n        );\n        responses.insert(\n            \"404\".to_string(),\n            RefOr::Object(OpenApiResponse {\n                description: \"\\\n                # [404 Not Found](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404)\\n\\\n                This response is given when you request a page that does not exists.\\\n                \"\n                .to_string(),\n                ..Default::default()\n            }),\n        );\n        responses.insert(\n            \"422\".to_string(),\n            RefOr::Object(OpenApiResponse {\n                description: \"\\\n                # [422 Unprocessable Entity](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422)\\n\\\n                This response is given when you request body is not correctly formatted. \\\n                \".to_string(),\n                ..Default::default()\n            }),\n        );\n        responses.insert(\n            \"500\".to_string(),\n            RefOr::Object(OpenApiResponse {\n                description: \"\\\n                # [500 Internal Server Error](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500)\\n\\\n                This response is given when something wend wrong on the server. \\\n                \".to_string(),\n                ..Default::default()\n            }),\n        );\n        Ok(Responses {\n            responses,\n            ..Default::default()\n        })\n    }\n}\n\nimpl std::fmt::Display for Error {\n    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(\n            formatter,\n            \"Error `{}`: {}\",\n            self.err,\n            self.msg.as_deref().unwrap_or(\"<no message>\")\n        )\n    }\n}\n\nimpl std::error::Error for Error {}\n\nimpl<'r> Responder<'r, 'static> for Error {\n    fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> {\n        // Convert object to json\n        let body = serde_json::to_string(&self).unwrap();\n        Response::build()\n            .sized_body(body.len(), std::io::Cursor::new(body))\n            .header(ContentType::JSON)\n            .status(Status::new(self.http_status_code))\n            .ok()\n    }\n}\n\nimpl From<rocket::serde::json::Error<'_>> for Error {\n    fn from(err: rocket::serde::json::Error) -> Self {\n        use rocket::serde::json::Error::*;\n        match err {\n            Io(io_error) => Error {\n                err: \"IO Error\".to_owned(),\n                msg: Some(io_error.to_string()),\n                http_status_code: 422,\n            },\n            Parse(_raw_data, parse_error) => Error {\n                err: \"Parse Error\".to_owned(),\n                msg: Some(parse_error.to_string()),\n                http_status_code: 422,\n            },\n        }\n    }\n}\n"
  },
  {
    "path": "examples/rocket_okapi_example/api/src/lib.rs",
    "content": "#[macro_use]\nextern crate rocket;\n\nuse rocket::fairing::{self, AdHoc};\nuse rocket::{Build, Rocket};\n\nuse migration::MigratorTrait;\nuse rocket_db_pools::Database;\n\nuse rocket_okapi::mount_endpoints_and_merged_docs;\nuse rocket_okapi::okapi::openapi3::OpenApi;\nuse rocket_okapi::rapidoc::{GeneralConfig, HideShowConfig, RapiDocConfig, make_rapidoc};\nuse rocket_okapi::settings::UrlObject;\nuse rocket_okapi::swagger_ui::{SwaggerUIConfig, make_swagger_ui};\n\nuse rocket::http::Method;\nuse rocket_cors::{AllowedHeaders, AllowedOrigins, Cors};\n\nmod pool;\nuse pool::Db;\nmod error;\nmod okapi_example;\n\npub use entity::post;\npub use entity::post::Entity as Post;\n\nasync fn run_migrations(rocket: Rocket<Build>) -> fairing::Result {\n    let conn = &Db::fetch(&rocket).unwrap().conn;\n    let _ = migration::Migrator::up(conn, None).await;\n    Ok(rocket)\n}\n\n#[tokio::main]\nasync fn start() -> Result<(), rocket::Error> {\n    let mut building_rocket = rocket::build()\n        .attach(Db::init())\n        .attach(AdHoc::try_on_ignite(\"Migrations\", run_migrations))\n        .mount(\n            \"/swagger-ui/\",\n            make_swagger_ui(&SwaggerUIConfig {\n                url: \"../v1/openapi.json\".to_owned(),\n                ..Default::default()\n            }),\n        )\n        .mount(\n            \"/rapidoc/\",\n            make_rapidoc(&RapiDocConfig {\n                title: Some(\"Rocket/SeaOrm - RapiDoc documentation | RapiDoc\".to_owned()),\n                general: GeneralConfig {\n                    spec_urls: vec![UrlObject::new(\"General\", \"../v1/openapi.json\")],\n                    ..Default::default()\n                },\n                hide_show: HideShowConfig {\n                    allow_spec_url_load: false,\n                    allow_spec_file_load: false,\n                    ..Default::default()\n                },\n                ..Default::default()\n            }),\n        )\n        .attach(cors());\n\n    let openapi_settings = rocket_okapi::settings::OpenApiSettings::default();\n    let custom_route_spec = (vec![], custom_openapi_spec());\n    mount_endpoints_and_merged_docs! {\n        building_rocket, \"/v1\".to_owned(), openapi_settings,\n            \"/additional\" => custom_route_spec,\n            \"/okapi-example\" => okapi_example::get_routes_and_docs(&openapi_settings),\n    };\n\n    building_rocket.launch().await.map(|_| ())\n}\n\nfn cors() -> Cors {\n    let allowed_origins =\n        AllowedOrigins::some_exact(&[\"http://localhost:8000\", \"http://127.0.0.1:8000\"]);\n\n    rocket_cors::CorsOptions {\n        allowed_origins,\n        allowed_methods: vec![Method::Get, Method::Post, Method::Delete]\n            .into_iter()\n            .map(From::from)\n            .collect(),\n        allowed_headers: AllowedHeaders::all(),\n        allow_credentials: true,\n        ..Default::default()\n    }\n    .to_cors()\n    .unwrap()\n}\n\nfn custom_openapi_spec() -> OpenApi {\n    use rocket_okapi::okapi::openapi3::*;\n    OpenApi {\n        openapi: OpenApi::default_version(),\n        info: Info {\n            title: \"SeaOrm-Rocket-Okapi Example\".to_owned(),\n            description: Some(\"API Docs for Rocket/SeaOrm example\".to_owned()),\n            terms_of_service: Some(\"https://github.com/SeaQL/sea-orm#license\".to_owned()),\n            contact: Some(Contact {\n                name: Some(\"SeaOrm\".to_owned()),\n                url: Some(\"https://github.com/SeaQL/sea-orm\".to_owned()),\n                email: None,\n                ..Default::default()\n            }),\n            license: Some(License {\n                name: \"MIT\".to_owned(),\n                url: Some(\"https://github.com/SeaQL/sea-orm/blob/master/LICENSE-MIT\".to_owned()),\n                ..Default::default()\n            }),\n            version: env!(\"CARGO_PKG_VERSION\").to_owned(),\n            ..Default::default()\n        },\n        servers: vec![\n            Server {\n                url: \"http://127.0.0.1:8000/v1\".to_owned(),\n                description: Some(\"Localhost\".to_owned()),\n                ..Default::default()\n            },\n            Server {\n                url: \"https://production-server.com/\".to_owned(),\n                description: Some(\"Remote development server\".to_owned()),\n                ..Default::default()\n            },\n        ],\n        ..Default::default()\n    }\n}\n\npub fn main() {\n    let result = start();\n\n    println!(\"Rocket: deorbit.\");\n\n    if let Some(err) = result.err() {\n        println!(\"Error: {err}\");\n    }\n}\n"
  },
  {
    "path": "examples/rocket_okapi_example/api/src/okapi_example.rs",
    "content": "use dto::dto;\nuse rocket::serde::json::Json;\nuse rocket_okapi_example_service::{Mutation, Query};\n\nuse rocket_db_pools::Connection;\n\nuse rocket_okapi::okapi::openapi3::OpenApi;\n\nuse crate::error;\nuse crate::pool;\nuse pool::Db;\n\npub use entity::post;\n\nuse rocket_okapi::settings::OpenApiSettings;\n\nuse rocket_okapi::{openapi, openapi_get_routes_spec};\n\nconst DEFAULT_POSTS_PER_PAGE: u64 = 5;\n\npub fn get_routes_and_docs(settings: &OpenApiSettings) -> (Vec<rocket::Route>, OpenApi) {\n    openapi_get_routes_spec![settings: create, update, list, get_by_id, delete, destroy]\n}\n\npub type R<T> = std::result::Result<rocket::serde::json::Json<T>, error::Error>;\npub type DataResult<'a, T> =\n    std::result::Result<rocket::serde::json::Json<T>, rocket::serde::json::Error<'a>>;\n\n/// # Add a new post\n#[openapi(tag = \"POST\")]\n#[post(\"/\", data = \"<post_data>\")]\nasync fn create(conn: Connection<Db>, post_data: DataResult<'_, post::Model>) -> R<Option<String>> {\n    let db = conn.into_inner();\n    let form = post_data?.into_inner();\n    let cmd = Mutation::create_post(&db, form);\n    match cmd.await {\n        Ok(_) => Ok(Json(Some(\"Post successfully added.\".to_string()))),\n        Err(e) => {\n            let m = error::Error {\n                err: \"Could not insert post\".to_string(),\n                msg: Some(e.to_string()),\n                http_status_code: 400,\n            };\n            Err(m)\n        }\n    }\n}\n\n/// # Update a post\n#[openapi(tag = \"POST\")]\n#[post(\"/<id>\", data = \"<post_data>\")]\nasync fn update(\n    conn: Connection<Db>,\n    id: i32,\n    post_data: DataResult<'_, post::Model>,\n) -> R<Option<String>> {\n    let db = conn.into_inner();\n\n    let form = post_data?.into_inner();\n\n    let cmd = Mutation::update_post_by_id(&db, id, form);\n    match cmd.await {\n        Ok(_) => Ok(Json(Some(\"Post successfully updated.\".to_string()))),\n        Err(e) => {\n            let m = error::Error {\n                err: \"Could not update post\".to_string(),\n                msg: Some(e.to_string()),\n                http_status_code: 400,\n            };\n            Err(m)\n        }\n    }\n}\n\n/// # Get post list\n#[openapi(tag = \"POST\")]\n#[get(\"/?<page>&<posts_per_page>\")]\nasync fn list(\n    conn: Connection<Db>,\n    page: Option<u64>,\n    posts_per_page: Option<u64>,\n) -> R<dto::PostsDto> {\n    let db = conn.into_inner();\n\n    // Set page number and items per page\n    let page = page.unwrap_or(1);\n    let posts_per_page = posts_per_page.unwrap_or(DEFAULT_POSTS_PER_PAGE);\n    if page == 0 {\n        let m = error::Error {\n            err: \"error getting posts\".to_string(),\n            msg: Some(\"'page' param cannot be zero\".to_string()),\n            http_status_code: 400,\n        };\n        return Err(m);\n    }\n\n    let (posts, num_pages) = Query::find_posts_in_page(&db, page, posts_per_page)\n        .await\n        .expect(\"Cannot find posts in page\");\n\n    Ok(Json(dto::PostsDto {\n        page,\n        posts_per_page,\n        num_pages,\n        posts,\n    }))\n}\n\n/// # get post by Id\n#[openapi(tag = \"POST\")]\n#[get(\"/<id>\")]\nasync fn get_by_id(conn: Connection<Db>, id: i32) -> R<Option<post::Model>> {\n    let db = conn.into_inner();\n\n    let post: Option<post::Model> = Query::find_post_by_id(&db, id)\n        .await\n        .expect(\"could not find post\");\n    Ok(Json(post))\n}\n\n/// # delete post by Id\n#[openapi(tag = \"POST\")]\n#[delete(\"/<id>\")]\nasync fn delete(conn: Connection<Db>, id: i32) -> R<Option<String>> {\n    let db = conn.into_inner();\n\n    let cmd = Mutation::delete_post(&db, id);\n    match cmd.await {\n        Ok(_) => Ok(Json(Some(\"Post successfully deleted.\".to_string()))),\n        Err(e) => {\n            let m = error::Error {\n                err: \"Error deleting post\".to_string(),\n                msg: Some(e.to_string()),\n                http_status_code: 400,\n            };\n            Err(m)\n        }\n    }\n}\n\n/// # delete all posts\n#[openapi(tag = \"POST\")]\n#[delete(\"/\")]\nasync fn destroy(conn: Connection<Db>) -> R<Option<String>> {\n    let db = conn.into_inner();\n\n    let cmd = Mutation::delete_all_posts(&db);\n\n    match cmd.await {\n        Ok(_) => Ok(Json(Some(\n            \"All Posts were successfully deleted.\".to_string(),\n        ))),\n        Err(e) => {\n            let m = error::Error {\n                err: \"Error deleting all posts at once\".to_string(),\n                msg: Some(e.to_string()),\n                http_status_code: 400,\n            };\n            Err(m)\n        }\n    }\n}\n"
  },
  {
    "path": "examples/rocket_okapi_example/api/src/pool.rs",
    "content": "use rocket_okapi_example_service::sea_orm;\n\nuse async_trait::async_trait;\nuse rocket_db_pools::Database;\nuse sea_orm::ConnectOptions;\nuse sea_orm_rocket::{Config, rocket::figment::Figment};\nuse std::time::Duration;\n\n#[derive(Database, Debug)]\n#[database(\"sea_orm\")]\npub struct Db(SeaOrmPool);\n\n#[derive(Debug, Clone)]\npub struct SeaOrmPool {\n    pub conn: sea_orm::DatabaseConnection,\n}\n\n#[async_trait]\nimpl rocket_db_pools::Pool for SeaOrmPool {\n    type Error = sea_orm::DbErr;\n\n    type Connection = sea_orm::DatabaseConnection;\n\n    async fn init(figment: &Figment) -> Result<Self, Self::Error> {\n        let config = figment.extract::<Config>().unwrap();\n        let mut options: ConnectOptions = config.url.into();\n        options\n            .max_connections(config.max_connections as u32)\n            .min_connections(config.min_connections.unwrap_or_default())\n            .connect_timeout(Duration::from_secs(config.connect_timeout));\n        if let Some(idle_timeout) = config.idle_timeout {\n            options.idle_timeout(Duration::from_secs(idle_timeout));\n        }\n        let conn = sea_orm::Database::connect(options).await?;\n\n        Ok(SeaOrmPool { conn })\n    }\n\n    async fn get(&self) -> Result<Self::Connection, Self::Error> {\n        Ok(self.conn.clone())\n    }\n\n    // DatabaseConnection automatically closes on drop\n    async fn close(&self) {}\n}\n"
  },
  {
    "path": "examples/rocket_okapi_example/dto/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"dto\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"dto\"\npath = \"src/lib.rs\"\n\n[dependencies]\nrocket = { version = \"0.5\", features = [\"json\"] }\n\n[dependencies.entity]\npath = \"../entity\"\n\n[dependencies.rocket_okapi]\nversion = \"0.9\"\n"
  },
  {
    "path": "examples/rocket_okapi_example/dto/src/dto.rs",
    "content": "use entity::*;\nuse rocket::serde::{Deserialize, Serialize};\nuse rocket_okapi::okapi::schemars::{self, JsonSchema};\n\n#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]\n#[serde(crate = \"rocket::serde\")]\npub struct PostsDto {\n    pub page: u64,\n    pub posts_per_page: u64,\n    pub num_pages: u64,\n    pub posts: Vec<post::Model>,\n}\n"
  },
  {
    "path": "examples/rocket_okapi_example/dto/src/lib.rs",
    "content": "pub mod dto;\n"
  },
  {
    "path": "examples/rocket_okapi_example/entity/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"entity\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"entity\"\npath = \"src/lib.rs\"\n\n[dependencies]\nrocket = { version = \"0.5\", features = [\"json\"] }\n\n[dependencies.sea-orm]\npath    = \"../../../\"    # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n\n[dependencies.rocket_okapi]\nversion = \"0.9\"\n"
  },
  {
    "path": "examples/rocket_okapi_example/entity/src/lib.rs",
    "content": "#[macro_use]\nextern crate rocket;\n\npub mod post;\n"
  },
  {
    "path": "examples/rocket_okapi_example/entity/src/post.rs",
    "content": "use rocket::serde::{Deserialize, Serialize};\nuse rocket_okapi::okapi::schemars::{self, JsonSchema};\nuse sea_orm::entity::prelude::*;\n\n#[derive(\n    Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize, Serialize, FromForm, JsonSchema,\n)]\n#[serde(crate = \"rocket::serde\")]\n#[sea_orm(table_name = \"post\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub title: String,\n    #[sea_orm(column_type = \"Text\")]\n    pub text: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/rocket_okapi_example/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nrocket = { version = \"0.5\" }\ntokio  = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable following runtime and db backend features if you want to run migration via CLI\n    # \"runtime-tokio-native-tls\",\n    # \"sqlx-postgres\",\n]\npath = \"../../../sea-orm-migration\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/rocket_okapi_example/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/rocket_okapi_example/migration/src/lib.rs",
    "content": "pub use sea_orm_migration::prelude::*;\n\nmod m20220120_000001_create_post_table;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![Box::new(m20220120_000001_create_post_table::Migration)]\n    }\n}\n"
  },
  {
    "path": "examples/rocket_okapi_example/migration/src/m20220120_000001_create_post_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"post\")\n                    .if_not_exists()\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"title\"))\n                    .col(string(\"text\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"post\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/rocket_okapi_example/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    //  Setting `DATABASE_URL` environment variable\n    let key = \"DATABASE_URL\";\n    if std::env::var(key).is_err() {\n        // Getting the database URL from Rocket.toml if it's not set\n        let figment = rocket::Config::figment();\n        let database_url: String = figment\n            .extract_inner(\"databases.sea_orm.url\")\n            .expect(\"Cannot find Database URL in Rocket.toml\");\n        unsafe {\n            std::env::set_var(key, database_url);\n        }\n    }\n\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/rocket_okapi_example/service/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"rocket-okapi-example-service\"\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[dependencies]\nentity = { path = \"../entity\" }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"runtime-tokio-native-tls\",\n    #    \"sqlx-postgres\",\n    #    \"sqlx-mysql\",\n    \"sqlx-sqlite\",\n]\npath = \"../../../\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n\n[dev-dependencies]\ntokio = \"1.41\"\n"
  },
  {
    "path": "examples/rocket_okapi_example/service/src/lib.rs",
    "content": "mod mutation;\nmod query;\n\npub use mutation::*;\npub use query::*;\n\npub use sea_orm;\n"
  },
  {
    "path": "examples/rocket_okapi_example/service/src/mutation.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Mutation;\n\nimpl Mutation {\n    pub async fn create_post(\n        db: &DbConn,\n        form_data: post::Model,\n    ) -> Result<post::ActiveModel, DbErr> {\n        post::ActiveModel {\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n            ..Default::default()\n        }\n        .save(db)\n        .await\n    }\n\n    pub async fn update_post_by_id(\n        db: &DbConn,\n        id: i32,\n        form_data: post::Model,\n    ) -> Result<post::Model, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post::ActiveModel {\n            id: post.id,\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n        }\n        .update(db)\n        .await\n    }\n\n    pub async fn delete_post(db: &DbConn, id: i32) -> Result<DeleteResult, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post.delete(db).await\n    }\n\n    pub async fn delete_all_posts(db: &DbConn) -> Result<DeleteResult, DbErr> {\n        Post::delete_many().exec(db).await\n    }\n}\n"
  },
  {
    "path": "examples/rocket_okapi_example/service/src/query.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Query;\n\nimpl Query {\n    pub async fn find_post_by_id(db: &DbConn, id: i32) -> Result<Option<post::Model>, DbErr> {\n        Post::find_by_id(id).one(db).await\n    }\n\n    /// If ok, returns (post models, num pages).\n    pub async fn find_posts_in_page(\n        db: &DbConn,\n        page: u64,\n        posts_per_page: u64,\n    ) -> Result<(Vec<post::Model>, u64), DbErr> {\n        // Setup paginator\n        let paginator = Post::find()\n            .order_by_asc(post::Column::Id)\n            .paginate(db, posts_per_page);\n        let num_pages = paginator.num_pages().await?;\n\n        // Fetch paginated posts\n        paginator.fetch_page(page - 1).await.map(|p| (p, num_pages))\n    }\n}\n"
  },
  {
    "path": "examples/rocket_okapi_example/service/tests/crud_tests.rs",
    "content": "use entity::post;\nuse rocket_okapi_example_service::{Mutation, Query};\nuse sea_orm::Database;\n\n#[tokio::test]\nasync fn main() {\n    let db = &Database::connect(\"sqlite::memory:\").await.unwrap();\n\n    db.get_schema_builder()\n        .register(post::Entity)\n        .apply(db)\n        .await\n        .unwrap();\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title A\".to_owned(),\n                text: \"Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(1),\n                title: sea_orm::ActiveValue::Unchanged(\"Title A\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text A\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title B\".to_owned(),\n                text: \"Text B\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(2),\n                title: sea_orm::ActiveValue::Unchanged(\"Title B\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text B\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 1).await.unwrap().unwrap();\n\n        assert_eq!(post.id, 1);\n        assert_eq!(post.title, \"Title A\");\n    }\n\n    {\n        let post = Mutation::update_post_by_id(\n            db,\n            1,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            }\n        );\n    }\n\n    {\n        let result = Mutation::delete_post(db, 2).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 2).await.unwrap();\n        assert!(post.is_none());\n    }\n\n    {\n        let result = Mutation::delete_all_posts(db).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n}\n"
  },
  {
    "path": "examples/rocket_okapi_example/src/main.rs",
    "content": "fn main() {\n    rocket_example_api::main();\n}\n"
  },
  {
    "path": "examples/salvo_example/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"sea-orm-salvo-example\"\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n[workspace]\nmembers = [\".\", \"api\", \"entity\", \"migration\"]\n\n[dependencies]\nsalvo-example-api = { path = \"api\" }\n"
  },
  {
    "path": "examples/salvo_example/README.md",
    "content": "![screenshot](Screenshot.png)\n\n# Salvo with SeaORM example app\n\n1. Modify the `DATABASE_URL` var in `.env` to point to your chosen database\n\n1. Turn on the appropriate database feature for your chosen db in `api/Cargo.toml` (the `\"sqlx-sqlite\",` line)\n\n1. Execute `cargo run` to start the server\n\n1. Visit [localhost:8000](http://localhost:8000) in browser after seeing the `server started` line\n\nRun tests:\n\n```bash\ncd api\ncargo test\n```"
  },
  {
    "path": "examples/salvo_example/api/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"salvo-example-api\"\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\ndotenvy            = \"0.15\"\nentity             = { path = \"../entity\" }\nmigration          = { path = \"../migration\" }\nsalvo              = { version = \"0.50\", features = [\"affix\", \"serve-static\"] }\nserde              = { version = \"1\", features = [\"derive\"] }\ntera               = \"1.19.0\"\ntokio              = { version = \"1.29.0\", features = [\"macros\", \"rt-multi-thread\"] }\ntracing-subscriber = { version = \"0.3.17\", features = [\"env-filter\"] }\n\n[dependencies.sea-orm]\nfeatures = [\n    \"debug-print\",\n    \"runtime-tokio-native-tls\",\n    # \"sqlx-mysql\",\n    # \"sqlx-postgres\",\n    \"sqlx-sqlite\",\n]\npath = \"../../../\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n"
  },
  {
    "path": "examples/salvo_example/api/src/lib.rs",
    "content": "pub mod service;\n\nuse entity::post;\nuse migration::{Migrator, MigratorTrait};\nuse salvo::affix;\nuse salvo::prelude::*;\nuse sea_orm::{Database, DatabaseConnection};\nuse service::{Mutation, Query};\nuse tera::Tera;\n\nconst DEFAULT_POSTS_PER_PAGE: u64 = 5;\ntype Result<T> = std::result::Result<T, StatusError>;\n\n#[derive(Debug, Clone)]\nstruct AppState {\n    templates: tera::Tera,\n    conn: DatabaseConnection,\n}\n\n#[handler]\nasync fn create(req: &mut Request, depot: &mut Depot, res: &mut Response) -> Result<()> {\n    let state = depot\n        .obtain::<AppState>()\n        .ok_or_else(StatusError::internal_server_error)?;\n    let conn = &state.conn;\n\n    let form = req\n        .parse_form::<post::Model>()\n        .await\n        .map_err(|_| StatusError::bad_request())?;\n\n    Mutation::create_post(conn, form)\n        .await\n        .map_err(|_| StatusError::internal_server_error())?;\n\n    Redirect::found(\"/\").render(res);\n    Ok(())\n}\n\n#[handler]\nasync fn list(req: &mut Request, depot: &mut Depot) -> Result<Text<String>> {\n    let state = depot\n        .obtain::<AppState>()\n        .ok_or_else(StatusError::internal_server_error)?;\n    let conn = &state.conn;\n\n    let page = req.query(\"page\").unwrap_or(1);\n    let posts_per_page = req\n        .query(\"posts_per_page\")\n        .unwrap_or(DEFAULT_POSTS_PER_PAGE);\n\n    let (posts, num_pages) = Query::find_posts_in_page(conn, page, posts_per_page)\n        .await\n        .map_err(|_| StatusError::internal_server_error())?;\n\n    let mut ctx = tera::Context::new();\n    ctx.insert(\"posts\", &posts);\n    ctx.insert(\"page\", &page);\n    ctx.insert(\"posts_per_page\", &posts_per_page);\n    ctx.insert(\"num_pages\", &num_pages);\n\n    let body = state\n        .templates\n        .render(\"index.html.tera\", &ctx)\n        .map_err(|_| StatusError::internal_server_error())?;\n    Ok(Text::Html(body))\n}\n\n#[handler]\nasync fn new(depot: &mut Depot) -> Result<Text<String>> {\n    let state = depot\n        .obtain::<AppState>()\n        .ok_or_else(StatusError::internal_server_error)?;\n    let ctx = tera::Context::new();\n    let body = state\n        .templates\n        .render(\"new.html.tera\", &ctx)\n        .map_err(|_| StatusError::internal_server_error())?;\n    Ok(Text::Html(body))\n}\n\n#[handler]\nasync fn edit(req: &mut Request, depot: &mut Depot) -> Result<Text<String>> {\n    let state = depot\n        .obtain::<AppState>()\n        .ok_or_else(StatusError::internal_server_error)?;\n    let conn = &state.conn;\n    let id = req.param::<i32>(\"id\").unwrap_or_default();\n\n    let post: post::Model = Query::find_post_by_id(conn, id)\n        .await\n        .map_err(|_| StatusError::internal_server_error())?\n        .ok_or_else(StatusError::not_found)?;\n\n    let mut ctx = tera::Context::new();\n    ctx.insert(\"post\", &post);\n\n    let body = state\n        .templates\n        .render(\"edit.html.tera\", &ctx)\n        .map_err(|_| StatusError::internal_server_error())?;\n    Ok(Text::Html(body))\n}\n\n#[handler]\nasync fn update(req: &mut Request, depot: &mut Depot, res: &mut Response) -> Result<()> {\n    let state = depot\n        .obtain::<AppState>()\n        .ok_or_else(StatusError::internal_server_error)?;\n    let conn = &state.conn;\n    let id = req.param::<i32>(\"id\").unwrap_or_default();\n    let form = req\n        .parse_form::<post::Model>()\n        .await\n        .map_err(|_| StatusError::bad_request())?;\n\n    Mutation::update_post_by_id(conn, id, form)\n        .await\n        .map_err(|_| StatusError::internal_server_error())?;\n\n    Redirect::found(\"/\").render(res);\n    Ok(())\n}\n\n#[handler]\nasync fn delete(req: &mut Request, depot: &mut Depot, res: &mut Response) -> Result<()> {\n    let state = depot\n        .obtain::<AppState>()\n        .ok_or_else(StatusError::internal_server_error)?;\n    let conn = &state.conn;\n    let id = req.param::<i32>(\"id\").unwrap_or_default();\n\n    Mutation::delete_post(conn, id)\n        .await\n        .map_err(|_| StatusError::internal_server_error())?;\n\n    Redirect::found(\"/\").render(res);\n    Ok(())\n}\n\n#[tokio::main]\npub async fn main() {\n    tracing_subscriber::fmt::init();\n\n    // get env vars\n    dotenvy::dotenv().ok();\n    let db_url = std::env::var(\"DATABASE_URL\").expect(\"DATABASE_URL is not set in .env file\");\n    let host = std::env::var(\"HOST\").expect(\"HOST is not set in .env file\");\n    let port = std::env::var(\"PORT\").expect(\"PORT is not set in .env file\");\n    let server_url = format!(\"{host}:{port}\");\n\n    // create post table if not exists\n    let conn = Database::connect(&db_url).await.unwrap();\n    Migrator::up(&conn, None).await.unwrap();\n    let templates = Tera::new(concat!(env!(\"CARGO_MANIFEST_DIR\"), \"/templates/**/*\")).unwrap();\n    let state = AppState { templates, conn };\n\n    println!(\"Starting server at {server_url}\");\n\n    let router = Router::new()\n        .hoop(affix::inject(state))\n        .post(create)\n        .get(list)\n        .push(Router::with_path(\"new\").get(new))\n        .push(Router::with_path(\"<id>\").get(edit).post(update))\n        .push(Router::with_path(\"delete/<id>\").post(delete))\n        .push(\n            Router::with_path(\"static/<**>\").get(salvo::prelude::StaticDir::new(concat!(\n                env!(\"CARGO_MANIFEST_DIR\"),\n                \"/static\"\n            ))),\n        );\n\n    Server::new(TcpListener::bind(TcpListener::new(format!(\"{host}:{port}\"))).await)\n        .serve(router)\n        .await;\n}\n"
  },
  {
    "path": "examples/salvo_example/api/src/service/mod.rs",
    "content": "mod mutation;\nmod query;\n\npub use mutation::*;\npub use query::*;\n"
  },
  {
    "path": "examples/salvo_example/api/src/service/mutation.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Mutation;\n\nimpl Mutation {\n    pub async fn create_post(\n        db: &DbConn,\n        form_data: post::Model,\n    ) -> Result<post::ActiveModel, DbErr> {\n        post::ActiveModel {\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n            ..Default::default()\n        }\n        .save(db)\n        .await\n    }\n\n    pub async fn update_post_by_id(\n        db: &DbConn,\n        id: i32,\n        form_data: post::Model,\n    ) -> Result<post::Model, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post::ActiveModel {\n            id: post.id,\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n        }\n        .update(db)\n        .await\n    }\n\n    pub async fn delete_post(db: &DbConn, id: i32) -> Result<DeleteResult, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post.delete(db).await\n    }\n\n    pub async fn delete_all_posts(db: &DbConn) -> Result<DeleteResult, DbErr> {\n        Post::delete_many().exec(db).await\n    }\n}\n"
  },
  {
    "path": "examples/salvo_example/api/src/service/query.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Query;\n\nimpl Query {\n    pub async fn find_post_by_id(db: &DbConn, id: i32) -> Result<Option<post::Model>, DbErr> {\n        Post::find_by_id(id).one(db).await\n    }\n\n    /// If ok, returns (post models, num pages).\n    pub async fn find_posts_in_page(\n        db: &DbConn,\n        page: u64,\n        posts_per_page: u64,\n    ) -> Result<(Vec<post::Model>, u64), DbErr> {\n        // Setup paginator\n        let paginator = Post::find()\n            .order_by_asc(post::Column::Id)\n            .paginate(db, posts_per_page);\n        let num_pages = paginator.num_pages().await?;\n\n        // Fetch paginated posts\n        paginator.fetch_page(page - 1).await.map(|p| (p, num_pages))\n    }\n}\n"
  },
  {
    "path": "examples/salvo_example/api/static/css/normalize.css",
    "content": "/*! normalize.css v3.0.2 | MIT License | git.io/normalize */\n\n/**\n * 1. Set default font family to sans-serif.\n * 2. Prevent iOS text size adjust after orientation change, without disabling\n *    user zoom.\n */\n\nhtml {\n  font-family: sans-serif; /* 1 */\n  -ms-text-size-adjust: 100%; /* 2 */\n  -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/**\n * Remove default margin.\n */\n\nbody {\n  margin: 0;\n}\n\n/* HTML5 display definitions\n   ========================================================================== */\n\n/**\n * Correct `block` display not defined for any HTML5 element in IE 8/9.\n * Correct `block` display not defined for `details` or `summary` in IE 10/11\n * and Firefox.\n * Correct `block` display not defined for `main` in IE 11.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n/**\n * 1. Correct `inline-block` display not defined in IE 8/9.\n * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n */\n\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block; /* 1 */\n  vertical-align: baseline; /* 2 */\n}\n\n/**\n * Prevent modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n/**\n * Address `[hidden]` styling not present in IE 8/9/10.\n * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.\n */\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n/* Links\n   ========================================================================== */\n\n/**\n * Remove the gray background color from active links in IE 10.\n */\n\na {\n  background-color: transparent;\n}\n\n/**\n * Improve readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n  outline: 0;\n}\n\n/* Text-level semantics\n   ========================================================================== */\n\n/**\n * Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n */\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n/**\n * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n */\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n/**\n * Address styling not present in Safari and Chrome.\n */\n\ndfn {\n  font-style: italic;\n}\n\n/**\n * Address variable `h1` font-size and margin within `section` and `article`\n * contexts in Firefox 4+, Safari, and Chrome.\n */\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n/**\n * Address styling not present in IE 8/9.\n */\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n/**\n * Address inconsistent and variable font size in all browsers.\n */\n\nsmall {\n  font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n/* Embedded content\n   ========================================================================== */\n\n/**\n * Remove border when inside `a` element in IE 8/9/10.\n */\n\nimg {\n  border: 0;\n}\n\n/**\n * Correct overflow not hidden in IE 9/10/11.\n */\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n/* Grouping content\n   ========================================================================== */\n\n/**\n * Address margin not present in IE 8/9 and Safari.\n */\n\nfigure {\n  margin: 1em 40px;\n}\n\n/**\n * Address differences between Firefox and other browsers.\n */\n\nhr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\n\n/**\n * Contain overflow in all browsers.\n */\n\npre {\n  overflow: auto;\n}\n\n/**\n * Address odd `em`-unit font size rendering in all browsers.\n */\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\n\n/* Forms\n   ========================================================================== */\n\n/**\n * Known limitation: by default, Chrome and Safari on OS X allow very limited\n * styling of `select`, unless a `border` property is set.\n */\n\n/**\n * 1. Correct color not being inherited.\n *    Known issue: affects color of disabled elements.\n * 2. Correct font properties not being inherited.\n * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  color: inherit; /* 1 */\n  font: inherit; /* 2 */\n  margin: 0; /* 3 */\n}\n\n/**\n * Address `overflow` set to `hidden` in IE 8/9/10/11.\n */\n\nbutton {\n  overflow: visible;\n}\n\n/**\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\n * All other form control elements do not inherit `text-transform` values.\n * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n * Correct `select` style inheritance in Firefox.\n */\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n/**\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *    and `video` controls.\n * 2. Correct inability to style clickable `input` types in iOS.\n * 3. Improve usability and consistency of cursor style between image-type\n *    `input` and others.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; /* 2 */\n  cursor: pointer; /* 3 */\n}\n\n/**\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n/**\n * Remove inner padding and border in Firefox 4+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n/**\n * Address Firefox 4+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\ninput {\n  line-height: normal;\n}\n\n/**\n * It's recommended that you don't attempt to style these elements.\n * Firefox's implementation doesn't respect box-sizing, padding, or width.\n *\n * 1. Address box sizing set to `content-box` in IE 8/9/10.\n * 2. Remove excess padding in IE 8/9/10.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Fix the cursor style for Chrome's increment/decrement buttons. For certain\n * `font-size` values of the `input`, it causes the cursor style of the\n * decrement button to change from `default` to `text`.\n */\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\n\n/**\n * 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n * 2. Address `box-sizing` set to `border-box` in Safari and Chrome\n *    (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; /* 1 */\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box; /* 2 */\n  box-sizing: content-box;\n}\n\n/**\n * Remove inner padding and search cancel button in Safari and Chrome on OS X.\n * Safari (but not Chrome) clips the cancel button when the search input has\n * padding (and `textfield` appearance).\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n/**\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n/**\n * 1. Correct `color` not being inherited in IE 8/9/10/11.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\n\nlegend {\n  border: 0; /* 1 */\n  padding: 0; /* 2 */\n}\n\n/**\n * Remove default vertical scrollbar in IE 8/9/10/11.\n */\n\ntextarea {\n  overflow: auto;\n}\n\n/**\n * Don't inherit the `font-weight` (applied by a rule above).\n * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n */\n\noptgroup {\n  font-weight: bold;\n}\n\n/* Tables\n   ========================================================================== */\n\n/**\n * Remove most spacing between table cells.\n */\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\ntd,\nth {\n  padding: 0;\n}\n"
  },
  {
    "path": "examples/salvo_example/api/static/css/skeleton.css",
    "content": "/*\n* Skeleton V2.0.4\n* Copyright 2014, Dave Gamache\n* www.getskeleton.com\n* Free to use under the MIT license.\n* https://opensource.org/licenses/mit-license.php\n* 12/29/2014\n*/\n\n\n/* Table of contents\n––––––––––––––––––––––––––––––––––––––––––––––––––\n- Grid\n- Base Styles\n- Typography\n- Links\n- Buttons\n- Forms\n- Lists\n- Code\n- Tables\n- Spacing\n- Utilities\n- Clearing\n- Media Queries\n*/\n\n\n/* Grid\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.container {\n  position: relative;\n  width: 100%;\n  max-width: 960px;\n  margin: 0 auto;\n  padding: 0 20px;\n  box-sizing: border-box; }\n.column,\n.columns {\n  width: 100%;\n  float: left;\n  box-sizing: border-box; }\n\n/* For devices larger than 400px */\n@media (min-width: 400px) {\n  .container {\n    width: 85%;\n    padding: 0; }\n}\n\n/* For devices larger than 550px */\n@media (min-width: 550px) {\n  .container {\n    width: 80%; }\n  .column,\n  .columns {\n    margin-left: 4%; }\n  .column:first-child,\n  .columns:first-child {\n    margin-left: 0; }\n\n  .one.column,\n  .one.columns                    { width: 4.66666666667%; }\n  .two.columns                    { width: 13.3333333333%; }\n  .three.columns                  { width: 22%;            }\n  .four.columns                   { width: 30.6666666667%; }\n  .five.columns                   { width: 39.3333333333%; }\n  .six.columns                    { width: 48%;            }\n  .seven.columns                  { width: 56.6666666667%; }\n  .eight.columns                  { width: 65.3333333333%; }\n  .nine.columns                   { width: 74.0%;          }\n  .ten.columns                    { width: 82.6666666667%; }\n  .eleven.columns                 { width: 91.3333333333%; }\n  .twelve.columns                 { width: 100%; margin-left: 0; }\n\n  .one-third.column               { width: 30.6666666667%; }\n  .two-thirds.column              { width: 65.3333333333%; }\n\n  .one-half.column                { width: 48%; }\n\n  /* Offsets */\n  .offset-by-one.column,\n  .offset-by-one.columns          { margin-left: 8.66666666667%; }\n  .offset-by-two.column,\n  .offset-by-two.columns          { margin-left: 17.3333333333%; }\n  .offset-by-three.column,\n  .offset-by-three.columns        { margin-left: 26%;            }\n  .offset-by-four.column,\n  .offset-by-four.columns         { margin-left: 34.6666666667%; }\n  .offset-by-five.column,\n  .offset-by-five.columns         { margin-left: 43.3333333333%; }\n  .offset-by-six.column,\n  .offset-by-six.columns          { margin-left: 52%;            }\n  .offset-by-seven.column,\n  .offset-by-seven.columns        { margin-left: 60.6666666667%; }\n  .offset-by-eight.column,\n  .offset-by-eight.columns        { margin-left: 69.3333333333%; }\n  .offset-by-nine.column,\n  .offset-by-nine.columns         { margin-left: 78.0%;          }\n  .offset-by-ten.column,\n  .offset-by-ten.columns          { margin-left: 86.6666666667%; }\n  .offset-by-eleven.column,\n  .offset-by-eleven.columns       { margin-left: 95.3333333333%; }\n\n  .offset-by-one-third.column,\n  .offset-by-one-third.columns    { margin-left: 34.6666666667%; }\n  .offset-by-two-thirds.column,\n  .offset-by-two-thirds.columns   { margin-left: 69.3333333333%; }\n\n  .offset-by-one-half.column,\n  .offset-by-one-half.columns     { margin-left: 52%; }\n\n}\n\n\n/* Base Styles\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n/* NOTE\nhtml is set to 62.5% so that all the REM measurements throughout Skeleton\nare based on 10px sizing. So basically 1.5rem = 15px :) */\nhtml {\n  font-size: 62.5%; }\nbody {\n  font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */\n  line-height: 1.6;\n  font-weight: 400;\n  font-family: \"Raleway\", \"HelveticaNeue\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  color: #222; }\n\n\n/* Typography\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nh1, h2, h3, h4, h5, h6 {\n  margin-top: 0;\n  margin-bottom: 2rem;\n  font-weight: 300; }\nh1 { font-size: 4.0rem; line-height: 1.2;  letter-spacing: -.1rem;}\nh2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; }\nh3 { font-size: 3.0rem; line-height: 1.3;  letter-spacing: -.1rem; }\nh4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; }\nh5 { font-size: 1.8rem; line-height: 1.5;  letter-spacing: -.05rem; }\nh6 { font-size: 1.5rem; line-height: 1.6;  letter-spacing: 0; }\n\n/* Larger than phablet */\n@media (min-width: 550px) {\n  h1 { font-size: 5.0rem; }\n  h2 { font-size: 4.2rem; }\n  h3 { font-size: 3.6rem; }\n  h4 { font-size: 3.0rem; }\n  h5 { font-size: 2.4rem; }\n  h6 { font-size: 1.5rem; }\n}\n\np {\n  margin-top: 0; }\n\n\n/* Links\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\na {\n  color: #1EAEDB; }\na:hover {\n  color: #0FA0CE; }\n\n\n/* Buttons\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.button,\nbutton,\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n  display: inline-block;\n  height: 38px;\n  padding: 0 30px;\n  color: #555;\n  text-align: center;\n  font-size: 11px;\n  font-weight: 600;\n  line-height: 38px;\n  letter-spacing: .1rem;\n  text-transform: uppercase;\n  text-decoration: none;\n  white-space: nowrap;\n  background-color: transparent;\n  border-radius: 4px;\n  border: 1px solid #bbb;\n  cursor: pointer;\n  box-sizing: border-box; }\n.button:hover,\nbutton:hover,\ninput[type=\"submit\"]:hover,\ninput[type=\"reset\"]:hover,\ninput[type=\"button\"]:hover,\n.button:focus,\nbutton:focus,\ninput[type=\"submit\"]:focus,\ninput[type=\"reset\"]:focus,\ninput[type=\"button\"]:focus {\n  color: #333;\n  border-color: #888;\n  outline: 0; }\n.button.button-primary,\nbutton.button-primary,\nbutton.primary,\ninput[type=\"submit\"].button-primary,\ninput[type=\"reset\"].button-primary,\ninput[type=\"button\"].button-primary {\n  color: #FFF;\n  background-color: #33C3F0;\n  border-color: #33C3F0; }\n.button.button-primary:hover,\nbutton.button-primary:hover,\nbutton.primary:hover,\ninput[type=\"submit\"].button-primary:hover,\ninput[type=\"reset\"].button-primary:hover,\ninput[type=\"button\"].button-primary:hover,\n.button.button-primary:focus,\nbutton.button-primary:focus,\nbutton.primary:focus,\ninput[type=\"submit\"].button-primary:focus,\ninput[type=\"reset\"].button-primary:focus,\ninput[type=\"button\"].button-primary:focus {\n  color: #FFF;\n  background-color: #1EAEDB;\n  border-color: #1EAEDB; }\n\n\n/* Forms\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ninput[type=\"text\"],\ninput[type=\"tel\"],\ninput[type=\"url\"],\ninput[type=\"password\"],\ntextarea,\nselect {\n  height: 38px;\n  padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */\n  background-color: #fff;\n  border: 1px solid #D1D1D1;\n  border-radius: 4px;\n  box-shadow: none;\n  box-sizing: border-box; }\n/* Removes awkward default styles on some inputs for iOS */\ninput[type=\"email\"],\ninput[type=\"number\"],\ninput[type=\"search\"],\ninput[type=\"text\"],\ninput[type=\"tel\"],\ninput[type=\"url\"],\ninput[type=\"password\"],\ntextarea {\n  -webkit-appearance: none;\n     -moz-appearance: none;\n          appearance: none; }\ntextarea {\n  min-height: 65px;\n  padding-top: 6px;\n  padding-bottom: 6px; }\ninput[type=\"email\"]:focus,\ninput[type=\"number\"]:focus,\ninput[type=\"search\"]:focus,\ninput[type=\"text\"]:focus,\ninput[type=\"tel\"]:focus,\ninput[type=\"url\"]:focus,\ninput[type=\"password\"]:focus,\ntextarea:focus,\nselect:focus {\n  border: 1px solid #33C3F0;\n  outline: 0; }\nlabel,\nlegend {\n  display: block;\n  margin-bottom: .5rem;\n  font-weight: 600; }\nfieldset {\n  padding: 0;\n  border-width: 0; }\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  display: inline; }\nlabel > .label-body {\n  display: inline-block;\n  margin-left: .5rem;\n  font-weight: normal; }\n\n\n/* Lists\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nul {\n  list-style: circle inside; }\nol {\n  list-style: decimal inside; }\nol, ul {\n  padding-left: 0;\n  margin-top: 0; }\nul ul,\nul ol,\nol ol,\nol ul {\n  margin: 1.5rem 0 1.5rem 3rem;\n  font-size: 90%; }\nli {\n  margin-bottom: 1rem; }\n\n\n/* Code\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\ncode {\n  padding: .2rem .5rem;\n  margin: 0 .2rem;\n  font-size: 90%;\n  white-space: nowrap;\n  background: #F1F1F1;\n  border: 1px solid #E1E1E1;\n  border-radius: 4px; }\npre > code {\n  display: block;\n  padding: 1rem 1.5rem;\n  white-space: pre; }\n\n\n/* Tables\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nth,\ntd {\n  padding: 12px 15px;\n  text-align: left;\n  border-bottom: 1px solid #E1E1E1; }\nth:first-child,\ntd:first-child {\n  padding-left: 0; }\nth:last-child,\ntd:last-child {\n  padding-right: 0; }\n\n\n/* Spacing\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nbutton,\n.button {\n  margin-bottom: 1rem; }\ninput,\ntextarea,\nselect,\nfieldset {\n  margin-bottom: 1.5rem; }\npre,\nblockquote,\ndl,\nfigure,\ntable,\np,\nul,\nol,\nform {\n  margin-bottom: 2.5rem; }\n\n\n/* Utilities\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n.u-full-width {\n  width: 100%;\n  box-sizing: border-box; }\n.u-max-full-width {\n  max-width: 100%;\n  box-sizing: border-box; }\n.u-pull-right {\n  float: right; }\n.u-pull-left {\n  float: left; }\n\n\n/* Misc\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\nhr {\n  margin-top: 3rem;\n  margin-bottom: 3.5rem;\n  border-width: 0;\n  border-top: 1px solid #E1E1E1; }\n\n\n/* Clearing\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n\n/* Self Clearing Goodness */\n.container:after,\n.row:after,\n.u-cf {\n  content: \"\";\n  display: table;\n  clear: both; }\n\n\n/* Media Queries\n–––––––––––––––––––––––––––––––––––––––––––––––––– */\n/*\nNote: The best way to structure the use of media queries is to create the queries\nnear the relevant code. For example, if you wanted to change the styles for buttons\non small devices, paste the mobile query code up in the buttons section and style it\nthere.\n*/\n\n\n/* Larger than mobile */\n@media (min-width: 400px) {}\n\n/* Larger than phablet (also point when grid becomes active) */\n@media (min-width: 550px) {}\n\n/* Larger than tablet */\n@media (min-width: 750px) {}\n\n/* Larger than desktop */\n@media (min-width: 1000px) {}\n\n/* Larger than Desktop HD */\n@media (min-width: 1200px) {}\n"
  },
  {
    "path": "examples/salvo_example/api/static/css/style.css",
    "content": ".field-error {\n  border: 1px solid #ff0000 !important;\n}\n\n.field-error-flash {\n  color: #ff0000;\n  display: block;\n  margin: -10px 0 10px 0;\n}\n\n.field-success {\n  border: 1px solid #5ab953 !important;\n}\n\n.field-success-flash {\n  color: #5ab953;\n  display: block;\n  margin: -10px 0 10px 0;\n}\n\nspan.completed {\n  text-decoration: line-through;\n}\n\nform.inline {\n  display: inline;\n}\n\nform.link,\nbutton.link {\n  display: inline;\n  color: #1eaedb;\n  border: none;\n  outline: none;\n  background: none;\n  cursor: pointer;\n  padding: 0;\n  margin: 0 0 0 0;\n  height: inherit;\n  text-decoration: underline;\n  font-size: inherit;\n  text-transform: none;\n  font-weight: normal;\n  line-height: inherit;\n  letter-spacing: inherit;\n}\n\nform.link:hover,\nbutton.link:hover {\n  color: #0fa0ce;\n}\n\nbutton.small {\n  height: 20px;\n  padding: 0 10px;\n  font-size: 10px;\n  line-height: 20px;\n  margin: 0 2.5px;\n}\n\n.post:hover {\n  background-color: #bce2ee;\n}\n\n.post td {\n  padding: 5px;\n  width: 150px;\n}\n\n#delete-button {\n  color: red;\n  border-color: red;\n}\n"
  },
  {
    "path": "examples/salvo_example/api/templates/edit.html.tera",
    "content": "{% extends \"layout.html.tera\" %} {% block content %}\n<div class=\"row\">\n  <h4>Edit Post</h4>\n  <div class=\"twelve columns\">\n    <div class=\"ten columns\">\n      <form action=\"/{{ post.id }}\" method=\"post\">\n        <div class=\"twelve columns\">\n          <input\n            type=\"text\"\n            placeholder=\"title\"\n            name=\"title\"\n            id=\"title\"\n            value=\"{{ post.title }}\"\n            autofocus\n            class=\"u-full-width\"\n          />\n          <input\n            type=\"text\"\n            placeholder=\"content\"\n            name=\"text\"\n            id=\"text\"\n            value=\"{{ post.text }}\"\n            autofocus\n            class=\"u-full-width\"\n          />\n        </div>\n        <div class=\"twelve columns\">\n          <div class=\"two columns\">\n            <a href=\"/\">\n              <input type=\"button\" value=\"cancel\" />\n            </a>\n          </div>\n          <div class=\"eight columns\"></div>\n          <div class=\"two columns\">\n            <input type=\"submit\" value=\"save post\" />\n          </div>\n        </div>\n      </form>\n    </div>\n    <div class=\"two columns\">\n      <form action=\"/delete/{{ post.id }}\" method=\"post\">\n        <div class=\"two columns\">\n          <input id=\"delete-button\" type=\"submit\" value=\"delete post\" />\n        </div>\n      </form>\n    </div>\n  </div>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/salvo_example/api/templates/error/404.html.tera",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>404 - tera</title>\n  </head>\n  <body>\n    <h1>404: Hey! There's nothing here.</h1>\n    The page at {{ uri }} does not exist!\n  </body>\n</html>\n"
  },
  {
    "path": "examples/salvo_example/api/templates/index.html.tera",
    "content": "{% extends \"layout.html.tera\" %} {% block content %}\n<div class=\"container\">\n  <p><!--Nothing to see here --></p>\n  <h1>Posts</h1>\n  {% if flash %}\n  <small class=\"field-{{ flash.kind }}-flash\">\n    {{ flash.message }}\n  </small>\n  {% endif %}\n  <table>\n    <tbody>\n      <thead>\n        <tr>\n          <th>ID</th>\n          <th>Title</th>\n          <th>Text</th>\n        </tr>\n      </thead>\n      {% for post in posts %}\n      <tr class=\"post\" onclick=\"window.location='/{{ post.id }}';\">\n        <td>{{ post.id }}</td>\n        <td>{{ post.title }}</td>\n        <td>{{ post.text }}</td>\n      </tr>\n      {% endfor %}\n    </tbody>\n    <tfoot>\n      <tr>\n        <td></td>\n        <td>\n          {% if page == 1 %} Previous {% else %}\n          <a href=\"/?page={{ page - 1 }}&posts_per_page={{ posts_per_page }}\"\n            >Previous</a\n          >\n          {% endif %} | {% if page == num_pages %} Next {% else %}\n          <a href=\"/?page={{ page + 1 }}&posts_per_page={{ posts_per_page }}\"\n            >Next</a\n          >\n          {% endif %}\n        </td>\n        <td></td>\n      </tr>\n    </tfoot>\n  </table>\n\n  <div class=\"twelve columns\">\n    <a href=\"/new\">\n      <input type=\"button\" value=\"add post\" />\n    </a>\n  </div>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/salvo_example/api/templates/layout.html.tera",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>Salvo Example</title>\n    <meta name=\"description\" content=\"Actix - SeaOrm integration example\" />\n    <meta name=\"author\" content=\"Sam Samai\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\n    <link\n      href=\"//fonts.googleapis.com/css?family=Raleway:400,300,600\"\n      rel=\"stylesheet\"\n      type=\"text/css\"\n    />\n    <link rel=\"stylesheet\" href=\"/static/css/normalize.css\" />\n    <link rel=\"stylesheet\" href=\"/static/css/skeleton.css\" />\n    <link rel=\"stylesheet\" href=\"/static/css/style.css\" />\n    <link rel=\"icon\" type=\"image/png\" href=\"/static/images/favicon.png\" />\n  </head>\n  <body>\n    <div class=\"container\">\n      <p><!--Nothing to see here --></p>\n      {% block content %}{% endblock content %}\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "examples/salvo_example/api/templates/new.html.tera",
    "content": "{% extends \"layout.html.tera\" %} {% block content %}\n<div class=\"row\">\n  <h4>New Post</h4>\n  <form action=\"/\" method=\"post\">\n    <div class=\"twelve columns\">\n      <input\n        type=\"text\"\n        placeholder=\"enter title\"\n        name=\"title\"\n        id=\"title\"\n        value=\"\"\n        autofocus\n        class=\"u-full-width\"\n      />\n      <input\n        type=\"text\"\n        placeholder=\"enter content\"\n        name=\"text\"\n        id=\"text\"\n        value=\"\"\n        autofocus\n        class=\"u-full-width\"\n      />\n    </div>\n    <div class=\"twelve columns\">\n      <div class=\"two columns\">\n        <a href=\"/\">\n          <input type=\"button\" value=\"cancel\" />\n        </a>\n      </div>\n      <div class=\"eight columns\"></div>\n      <div class=\"two columns\">\n        <input type=\"submit\" value=\"save post\" />\n      </div>\n    </div>\n  </form>\n</div>\n{% endblock content %}\n"
  },
  {
    "path": "examples/salvo_example/api/tests/crud_tests.rs",
    "content": "use entity::post;\nuse salvo_example_api::service::{Mutation, Query};\nuse sea_orm::Database;\n\n#[tokio::test]\nasync fn crud_tests() {\n    let db = &Database::connect(\"sqlite::memory:\").await.unwrap();\n\n    db.get_schema_builder()\n        .register(post::Entity)\n        .apply(db)\n        .await\n        .unwrap();\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title A\".to_owned(),\n                text: \"Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(1),\n                title: sea_orm::ActiveValue::Unchanged(\"Title A\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text A\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title B\".to_owned(),\n                text: \"Text B\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(2),\n                title: sea_orm::ActiveValue::Unchanged(\"Title B\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text B\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 1).await.unwrap().unwrap();\n\n        assert_eq!(post.id, 1);\n        assert_eq!(post.title, \"Title A\");\n    }\n\n    {\n        let post = Mutation::update_post_by_id(\n            db,\n            1,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            }\n        );\n    }\n\n    {\n        let result = Mutation::delete_post(db, 2).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 2).await.unwrap();\n        assert!(post.is_none());\n    }\n\n    {\n        let result = Mutation::delete_all_posts(db).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n}\n"
  },
  {
    "path": "examples/salvo_example/entity/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"entity\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"entity\"\npath = \"src/lib.rs\"\n\n[dependencies]\nserde = { version = \"1\", features = [\"derive\"] }\n\n[dependencies.sea-orm]\npath    = \"../../../\"    # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n"
  },
  {
    "path": "examples/salvo_example/entity/src/lib.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub mod prelude;\n\npub mod post;\n"
  },
  {
    "path": "examples/salvo_example/entity/src/post.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"post\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    pub title: String,\n    #[sea_orm(column_type = \"Text\")]\n    pub text: String,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/salvo_example/entity/src/prelude.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub use super::post::Entity as Post;\n"
  },
  {
    "path": "examples/salvo_example/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nentity = { path = \"../entity\" }\ntokio  = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable following runtime and db backend features if you want to run migration via CLI\n    \"runtime-tokio-native-tls\",\n    \"sqlx-sqlite\",\n]\npath = \"../../../sea-orm-migration\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/salvo_example/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/salvo_example/migration/src/lib.rs",
    "content": "pub use sea_orm_migration::prelude::*;\n\nmod m20220120_000001_create_post_table;\nmod m20220120_000002_seed_posts;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220120_000001_create_post_table::Migration),\n            Box::new(m20220120_000002_seed_posts::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "examples/salvo_example/migration/src/m20220120_000001_create_post_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"post\")\n                    .if_not_exists()\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"title\"))\n                    .col(string(\"text\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"post\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/salvo_example/migration/src/m20220120_000002_seed_posts.rs",
    "content": "use entity::post;\nuse sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};\nuse sea_orm_migration::prelude::*;\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let seed_data = vec![\n            (\"First Post\", \"This is the first post.\"),\n            (\"Second Post\", \"This is another post.\"),\n        ];\n\n        for (title, text) in seed_data {\n            let model = post::ActiveModel {\n                title: Set(title.to_string()),\n                text: Set(text.to_string()),\n                ..Default::default()\n            };\n            model.insert(db).await?;\n        }\n\n        println!(\"Posts table seeded successfully.\");\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let titles_to_delete = vec![\"First Post\", \"Second Post\"];\n        post::Entity::delete_many()\n            .filter(post::Column::Title.is_in(titles_to_delete))\n            .exec(db)\n            .await?;\n\n        println!(\"Posts seeded data removed.\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/salvo_example/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/salvo_example/src/main.rs",
    "content": "fn main() {\n    salvo_example_api::main();\n}\n"
  },
  {
    "path": "examples/seaography_example/README.md",
    "content": "# SeaORM + Seaography Example\n\n| ![](https://raw.githubusercontent.com/SeaQL/sea-orm/master/examples/seaography_example/Seaography%20example.png) |\n|:--:| \n| Seaography screenshot with Bakery schema |\n\n| ![](https://raw.githubusercontent.com/SeaQL/sea-orm/master/tests/common/bakery_chain/bakery_chain_erd.png) |\n|:--:| \n| The Bakery schema |\n\n## Running the project\n\nSpecify a database url\n\n```sh\nexport DATABASE_URL=\"sqlite://../bakery.db\"\n```\n\nThen, run\n\n```sh\ncd graphql\ncargo run\n```\n\n## Run some queries\n\n### Find chocolate cakes and know where to buy them\n\n```graphql\n{\n  cake(filters: { name: { contains: \"Chocolate\" } }) {\n    nodes {\n      name\n      price\n      bakery {\n        name\n      }\n    }\n  }\n}\n```\n\n### Find all cakes baked by Alice\n\n```graphql\n{\n  cake(having: { baker: { name: { eq: \"Alice\" } } }) {\n    nodes {\n      name\n      price\n      baker {\n        nodes {\n          name\n        }\n      }\n    }\n  }\n}\n```\n\n### Bakery -> Cake -> Baker\n\n```graphql\n{\n  bakery(pagination: { page: { limit: 10, page: 0 } }, orderBy: { name: ASC }) {\n    nodes {\n      name\n      cake {\n        nodes {\n          name\n          price\n          baker {\n            nodes {\n              name\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n## Starting from scratch\n\n### Setup the Database\n\n`cd` into `migration` folder and follow instructions there, but basically:\n\n```sh\nexport DATABASE_URL=\"sqlite://../bakery.db?mode=rwc\"\n```\n\n```sh\ncd migration\ncargo run\n```\n\n### Install Seaography\n\n```sh\ncargo install sea-orm-cli@^2.0.0-rc\ncargo install seaography-cli@^2.0.0-rc\n```\n\n### Generate GraphQL project\n\n```sh\nrm -rf graphql # this entire folder is generated\nmkdir graphql\ncd graphql\nsea-orm-cli generate entity --output-dir ./src/entities --entity-format dense --seaography\nseaography-cli -o . -e ./src/entities --framework axum sea-orm-seaography-example\n```\n"
  },
  {
    "path": "examples/seaography_example/graphql/Cargo.toml",
    "content": "[package]\nedition = \"2021\"\nname    = \"sea-orm-seaography-example\"\nversion = \"0.1.0\"\n\n[dependencies]\nasync-graphql-axum = { version = \"7.0\" }\naxum               = { version = \"0.8\" }\ndotenv             = \"0.15.0\"\ntokio              = { version = \"1.29.1\", features = [\"macros\", \"rt-multi-thread\"] }\ntracing            = { version = \"0.1.37\" }\ntracing-subscriber = { version = \"0.3.17\" }\n\n[dependencies.sea-orm]\nfeatures = [\"sqlx-sqlite\", \"runtime-tokio-native-tls\", \"seaography\"]\nversion  = \"~2.0.0-rc\"\n\n[dependencies.seaography]\nfeatures = [\"graphql-playground\", \"with-decimal\", \"with-chrono\"]\nversion  = \"~2.0.0-rc.3\"                                         # seaography version\n\n[dev-dependencies]\nserde_json = { version = \"1.0.103\" }\n\n[workspace]\nmembers = []\n"
  },
  {
    "path": "examples/seaography_example/graphql/src/entities/baker.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.14\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"baker\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub contact: String,\n    pub bakery_id: Option<i32>,\n    #[sea_orm(\n        belongs_to,\n        from = \"bakery_id\",\n        to = \"id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    pub bakery: HasOne<super::bakery::Entity>,\n    #[sea_orm(has_many, via = \"cake_baker\")]\n    pub cakes: HasMany<super::cake::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/seaography_example/graphql/src/entities/bakery.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.14\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bakery\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(column_type = \"Double\")]\n    pub profit_margin: f64,\n    #[sea_orm(has_many)]\n    pub bakers: HasMany<super::baker::Entity>,\n    #[sea_orm(has_many)]\n    pub cakes: HasMany<super::cake::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/seaography_example/graphql/src/entities/cake.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.14\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub price: Decimal,\n    pub bakery_id: i32,\n    pub gluten_free: bool,\n    #[sea_orm(\n        belongs_to,\n        from = \"bakery_id\",\n        to = \"id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    pub bakery: HasOne<super::bakery::Entity>,\n    #[sea_orm(has_many, via = \"cake_baker\")]\n    pub bakers: HasMany<super::baker::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/seaography_example/graphql/src/entities/cake_baker.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.14\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake_baker\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub baker_id: i32,\n    #[sea_orm(\n        belongs_to,\n        from = \"baker_id\",\n        to = \"id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    pub baker: HasOne<super::baker::Entity>,\n    #[sea_orm(\n        belongs_to,\n        from = \"cake_id\",\n        to = \"id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    pub cake: HasOne<super::cake::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/seaography_example/graphql/src/entities/mod.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.14\n\npub mod prelude;\n\npub mod baker;\npub mod bakery;\npub mod cake;\npub mod cake_baker;\n\nseaography::register_entity_modules!([baker, bakery, cake, cake_baker,]);\n"
  },
  {
    "path": "examples/seaography_example/graphql/src/entities/prelude.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.14\n\npub use super::baker::Entity as Baker;\npub use super::bakery::Entity as Bakery;\npub use super::cake::Entity as Cake;\npub use super::cake_baker::Entity as CakeBaker;\n"
  },
  {
    "path": "examples/seaography_example/graphql/src/lib.rs",
    "content": "pub mod entities;\npub mod query_root;\n"
  },
  {
    "path": "examples/seaography_example/graphql/src/main.rs",
    "content": "use async_graphql::{\n    dynamic::Schema,\n    http::{playground_source, GraphQLPlaygroundConfig},\n};\nuse async_graphql_axum::{GraphQLRequest, GraphQLResponse};\nuse axum::{\n    extract::State,\n    response::{self, IntoResponse},\n    routing::get,\n    Router,\n};\nuse dotenv::dotenv;\nuse sea_orm::Database;\nuse seaography::{async_graphql, lazy_static::lazy_static};\nuse std::env;\nuse tokio::net::TcpListener;\n\nlazy_static! {\n    static ref URL: String = env::var(\"URL\").unwrap_or(\"localhost:8000\".into());\n    static ref ENDPOINT: String = env::var(\"ENDPOINT\").unwrap_or(\"/\".into());\n    static ref DATABASE_URL: String =\n        env::var(\"DATABASE_URL\").expect(\"DATABASE_URL environment variable not set\");\n    static ref DEPTH_LIMIT: Option<usize> = env::var(\"DEPTH_LIMIT\").map_or(None, |data| Some(\n        data.parse().expect(\"DEPTH_LIMIT is not a number\")\n    ));\n    static ref COMPLEXITY_LIMIT: Option<usize> = env::var(\"COMPLEXITY_LIMIT\")\n        .map_or(None, |data| {\n            Some(data.parse().expect(\"COMPLEXITY_LIMIT is not a number\"))\n        });\n}\n\nasync fn graphql_playground() -> impl IntoResponse {\n    response::Html(playground_source(GraphQLPlaygroundConfig::new(&*ENDPOINT)))\n}\n\nasync fn graphql_handler(State(schema): State<Schema>, req: GraphQLRequest) -> GraphQLResponse {\n    let req = req.into_inner();\n    schema.execute(req).await.into()\n}\n\n#[tokio::main]\nasync fn main() {\n    dotenv().ok();\n    tracing_subscriber::fmt()\n        .with_max_level(tracing::Level::INFO)\n        .with_test_writer()\n        .init();\n    let db = Database::connect(&*DATABASE_URL)\n        .await\n        .expect(\"Fail to initialize database connection\");\n    let schema =\n        sea_orm_seaography_example::query_root::schema(db, *DEPTH_LIMIT, *COMPLEXITY_LIMIT)\n            .unwrap();\n    let app = Router::new()\n        .route(&*ENDPOINT, get(graphql_playground).post(graphql_handler))\n        .with_state(schema);\n    println!(\"Visit GraphQL Playground at http://{}\", *URL);\n    axum::serve(TcpListener::bind(&*URL).await.unwrap(), app)\n        .await\n        .unwrap();\n}\n"
  },
  {
    "path": "examples/seaography_example/graphql/src/query_root.rs",
    "content": "use crate::entities::*;\nuse async_graphql::dynamic::*;\nuse sea_orm::DatabaseConnection;\nuse seaography::{async_graphql, lazy_static::lazy_static, Builder, BuilderContext};\n\nlazy_static! {\n    static ref CONTEXT: BuilderContext = BuilderContext::default();\n}\n\npub fn schema(\n    database: DatabaseConnection,\n    depth: Option<usize>,\n    complexity: Option<usize>,\n) -> Result<Schema, SchemaError> {\n    schema_builder(&CONTEXT, database, depth, complexity).finish()\n}\n\npub fn schema_builder(\n    context: &'static BuilderContext,\n    database: DatabaseConnection,\n    depth: Option<usize>,\n    complexity: Option<usize>,\n) -> SchemaBuilder {\n    let mut builder = Builder::new(context, database.clone());\n    builder = register_entity_modules(builder);\n    builder\n        .set_depth_limit(depth)\n        .set_complexity_limit(complexity)\n        .schema_builder()\n        .data(database)\n}\n"
  },
  {
    "path": "examples/seaography_example/graphql/tests/query_tests.rs",
    "content": "use async_graphql::{dynamic::*, Response};\nuse sea_orm::Database;\nuse seaography::async_graphql;\n\nasync fn schema() -> Schema {\n    let database = Database::connect(\n        std::env::var(\"DATABASE_URL\").unwrap_or_else(|_| \"sqlite://../bakery.db\".into()),\n    )\n    .await\n    .unwrap();\n    sea_orm_seaography_example::query_root::schema(database, None, None).unwrap()\n}\n\nfn assert_eq(a: Response, b: &str) {\n    assert_eq!(\n        a.data.into_json().unwrap(),\n        serde_json::from_str::<serde_json::Value>(b).unwrap()\n    )\n}\n\n#[tokio::test]\nasync fn test_cake_with_bakery() {\n    let schema = schema().await;\n\n    assert_eq(\n        schema\n            .execute(\n                r#\"\n                {\n                  cake(filters: { name: { contains: \"Chocolate\" } }) {\n                    nodes {\n                      name\n                      price\n                      bakery {\n                        name\n                      }\n                    }\n                  }\n                }\n                \"#,\n            )\n            .await,\n        r#\"\n        {\n          \"cake\": {\n            \"nodes\": [\n              {\n                \"name\": \"Chocolate Cake\",\n                \"price\": \"10.25\",\n                \"bakery\": {\n                  \"name\": \"SeaSide Bakery\"\n                }\n              },\n              {\n                \"name\": \"Double Chocolate\",\n                \"price\": \"12.5\",\n                \"bakery\": {\n                  \"name\": \"SeaSide Bakery\"\n                }\n              },\n              {\n                \"name\": \"Double Chocolate\",\n                \"price\": \"12.5\",\n                \"bakery\": {\n                  \"name\": \"LakeSide Bakery\"\n                }\n              }\n            ]\n          }\n        }\n        \"#,\n    )\n}\n\n#[tokio::test]\nasync fn test_cake_with_baker() {\n    let schema = schema().await;\n\n    assert_eq(\n        schema\n            .execute(\n                r#\"\n                {\n                  cake(\n                    filters: { name: { contains: \"Cheese\" } }\n                    having: { baker: { name: { eq: \"Alice\" } } }\n                  ) {\n                    nodes {\n                      name\n                      price\n                      baker {\n                        nodes {\n                          name\n                        }\n                      }\n                    }\n                  }\n                }\n                \"#,\n            )\n            .await,\n        r#\"\n        {\n          \"cake\": {\n            \"nodes\": [\n              {\n                \"name\": \"New York Cheese\",\n                \"price\": \"12.5\",\n                \"baker\": {\n                  \"nodes\": [\n                    {\n                      \"name\": \"Alice\"\n                    },\n                    {\n                      \"name\": \"Bob\"\n                    }\n                  ]\n                }\n              },\n              {\n                \"name\": \"New York Cheese\",\n                \"price\": \"12.5\",\n                \"baker\": {\n                  \"nodes\": [\n                    {\n                      \"name\": \"Alice\"\n                    },\n                    {\n                      \"name\": \"Bob\"\n                    }\n                  ]\n                }\n              },\n              {\n                \"name\": \"Blueburry Cheese\",\n                \"price\": \"11.5\",\n                \"baker\": {\n                  \"nodes\": [\n                    {\n                      \"name\": \"Alice\"\n                    }\n                  ]\n                }\n              }\n            ]\n          }\n        }\n        \"#,\n    )\n}\n\n#[tokio::test]\nasync fn test_bakery_with_cake_with_baker() {\n    let schema = schema().await;\n\n    assert_eq(\n        schema\n            .execute(\n                r#\"\n                {\n                  bakery(pagination: { page: { limit: 1, page: 0 } }, orderBy: { name: ASC }) {\n                    nodes {\n                      name\n                      cake {\n                        nodes {\n                          name\n                          price\n                          baker {\n                            nodes {\n                              name\n                            }\n                          }\n                        }\n                      }\n                    }\n                  }\n                }\n                \"#,\n            )\n            .await,\n        r#\"\n        {\n          \"bakery\": {\n            \"nodes\": [\n              {\n                \"name\": \"LakeSide Bakery\",\n                \"cake\": {\n                  \"nodes\": [\n                    {\n                      \"name\": \"Double Chocolate\",\n                      \"price\": \"12.5\",\n                      \"baker\": {\n                        \"nodes\": [\n                          {\n                            \"name\": \"Bob\"\n                          }\n                        ]\n                      }\n                    },\n                    {\n                      \"name\": \"Lemon Cake\",\n                      \"price\": \"8.8\",\n                      \"baker\": {\n                        \"nodes\": [\n                          {\n                            \"name\": \"Bob\"\n                          }\n                        ]\n                      }\n                    },\n                    {\n                      \"name\": \"Strawberry Cake\",\n                      \"price\": \"9.9\",\n                      \"baker\": {\n                        \"nodes\": [\n                          {\n                            \"name\": \"Bob\"\n                          }\n                        ]\n                      }\n                    },\n                    {\n                      \"name\": \"Orange Cake\",\n                      \"price\": \"6.5\",\n                      \"baker\": {\n                        \"nodes\": [\n                          {\n                            \"name\": \"Bob\"\n                          }\n                        ]\n                      }\n                    },\n                    {\n                      \"name\": \"New York Cheese\",\n                      \"price\": \"12.5\",\n                      \"baker\": {\n                        \"nodes\": [\n                          {\n                            \"name\": \"Alice\"\n                          },\n                          {\n                            \"name\": \"Bob\"\n                          }\n                        ]\n                      }\n                    },\n                    {\n                      \"name\": \"Blueburry Cheese\",\n                      \"price\": \"11.5\",\n                      \"baker\": {\n                        \"nodes\": [\n                          {\n                            \"name\": \"Bob\"\n                          }\n                        ]\n                      }\n                    }\n                  ]\n                }\n              }\n            ]\n          }\n        }\n        \"#,\n    )\n}\n"
  },
  {
    "path": "examples/seaography_example/migration/Cargo.toml",
    "content": "[workspace]\n\n[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\ntokio = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm]\npath    = \"../../../\"    # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    \"runtime-tokio-native-tls\",\n    \"sqlx-sqlite\",\n]\npath = \"../../../sea-orm-migration\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/seaography_example/migration/README.md",
    "content": "# Bakery Schema\n\n## MySQL\n\nAssume the database is named `bakery`:\n\n```sql\nCREATE DATABASE bakery;\nGRANT ALL PRIVILEGES ON bakery.* TO sea;\n```\n\n## SQLite\n\n```sh\nexport DATABASE_URL=sqlite://../bakery.db?mode=rwc\n```\n\n# Re-generate entities\n\n```sh\nsea-orm-cli generate entity --output-dir src/entity\n```\n\n# Running Migrator CLI\n\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/seaography_example/migration/src/entity/baker.rs",
    "content": "//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"baker\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub contact: String,\n    pub bakery_id: Option<i32>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::bakery::Entity\",\n        from = \"Column::BakeryId\",\n        to = \"super::bakery::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Bakery,\n    #[sea_orm(has_many = \"super::cake_baker::Entity\")]\n    CakeBaker,\n}\n\nimpl Related<super::bakery::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bakery.def()\n    }\n}\n\nimpl Related<super::cake_baker::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::CakeBaker.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_baker::Relation::Cake.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_baker::Relation::Baker.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/seaography_example/migration/src/entity/bakery.rs",
    "content": "//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bakery\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(column_type = \"Double\")]\n    pub profit_margin: f64,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::baker::Entity\")]\n    Baker,\n    #[sea_orm(has_many = \"super::cake::Entity\")]\n    Cake,\n}\n\nimpl Related<super::baker::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Baker.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/seaography_example/migration/src/entity/cake.rs",
    "content": "//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub price: Decimal,\n    pub bakery_id: Option<i32>,\n    pub gluten_free: i8,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::bakery::Entity\",\n        from = \"Column::BakeryId\",\n        to = \"super::bakery::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Bakery,\n    #[sea_orm(has_many = \"super::cake_baker::Entity\")]\n    CakeBaker,\n}\n\nimpl Related<super::bakery::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bakery.def()\n    }\n}\n\nimpl Related<super::cake_baker::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::CakeBaker.def()\n    }\n}\n\nimpl Related<super::baker::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_baker::Relation::Baker.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_baker::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/seaography_example/migration/src/entity/cake_baker.rs",
    "content": "//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake_baker\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub baker_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::baker::Entity\",\n        from = \"Column::BakerId\",\n        to = \"super::baker::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Baker,\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Cake,\n}\n\nimpl Related<super::baker::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Baker.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/seaography_example/migration/src/entity/mod.rs",
    "content": "//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1\n\npub mod prelude;\n\npub mod baker;\npub mod bakery;\npub mod cake;\npub mod cake_baker;\n"
  },
  {
    "path": "examples/seaography_example/migration/src/entity/prelude.rs",
    "content": "//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.1\n\npub use super::baker::Entity as Baker;\npub use super::bakery::Entity as Bakery;\npub use super::cake::Entity as Cake;\npub use super::cake_baker::Entity as CakeBaker;\n"
  },
  {
    "path": "examples/seaography_example/migration/src/lib.rs",
    "content": "pub use sea_orm_migration::prelude::*;\n\nmod entity;\nmod m20230101_000001_create_bakery_table;\nmod m20230101_000002_create_baker_table;\nmod m20230101_000003_create_cake_table;\nmod m20230101_000004_create_cake_baker_table;\nmod m20230101_000005_create_customer_table;\nmod m20230101_000006_create_order_table;\nmod m20230101_000007_create_lineitem_table;\nmod m20230102_000001_seed_bakery_data;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20230101_000001_create_bakery_table::Migration),\n            Box::new(m20230101_000002_create_baker_table::Migration),\n            Box::new(m20230101_000003_create_cake_table::Migration),\n            Box::new(m20230101_000004_create_cake_baker_table::Migration),\n            // Box::new(m20230101_000005_create_customer_table::Migration),\n            // Box::new(m20230101_000006_create_order_table::Migration),\n            // Box::new(m20230101_000007_create_lineitem_table::Migration),\n            Box::new(m20230102_000001_seed_bakery_data::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "examples/seaography_example/migration/src/m20230101_000001_create_bakery_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"bakery\")\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"name\"))\n                    .col(double(\"profit_margin\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"bakery\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/seaography_example/migration/src/m20230101_000002_create_baker_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"baker\")\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"name\"))\n                    .col(string(\"contact\"))\n                    .col(integer_null(\"bakery_id\"))\n                    .foreign_key(\n                        ForeignKey::create()\n                            .name(\"fk-baker-bakery_id\")\n                            .from(\"baker\", \"bakery_id\")\n                            .to(\"bakery\", \"id\")\n                            .on_delete(ForeignKeyAction::Cascade)\n                            .on_update(ForeignKeyAction::Cascade),\n                    )\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"baker\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/seaography_example/migration/src/m20230101_000003_create_cake_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"cake\")\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"name\"))\n                    .col(decimal_len(\"price\", 16, 4))\n                    .col(integer(\"bakery_id\"))\n                    .foreign_key(\n                        ForeignKey::create()\n                            .name(\"fk-cake-bakery_id\")\n                            .from(\"cake\", \"bakery_id\")\n                            .to(\"bakery\", \"id\")\n                            .on_delete(ForeignKeyAction::Cascade)\n                            .on_update(ForeignKeyAction::Cascade),\n                    )\n                    .col(boolean(\"gluten_free\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"cake\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/seaography_example/migration/src/m20230101_000004_create_cake_baker_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"cake_baker\")\n                    .col(integer(\"cake_id\"))\n                    .col(integer(\"baker_id\"))\n                    .primary_key(\n                        Index::create()\n                            .name(\"pk-cake_baker\")\n                            .col(\"cake_id\")\n                            .col(\"baker_id\"),\n                    )\n                    .foreign_key(\n                        ForeignKey::create()\n                            .name(\"fk-cake_baker-cake_id\")\n                            .from(\"cake_baker\", \"cake_id\")\n                            .to(\"cake\", \"id\")\n                            .on_delete(ForeignKeyAction::Cascade)\n                            .on_update(ForeignKeyAction::Cascade),\n                    )\n                    .foreign_key(\n                        ForeignKey::create()\n                            .name(\"fk-cake_baker-baker_id\")\n                            .from(\"cake_baker\", \"baker_id\")\n                            .to(\"baker\", \"id\")\n                            .on_delete(ForeignKeyAction::Cascade)\n                            .on_update(ForeignKeyAction::Cascade),\n                    )\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"cake_baker\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/seaography_example/migration/src/m20230101_000005_create_customer_table.rs",
    "content": "\n"
  },
  {
    "path": "examples/seaography_example/migration/src/m20230101_000006_create_order_table.rs",
    "content": "\n"
  },
  {
    "path": "examples/seaography_example/migration/src/m20230101_000007_create_lineitem_table.rs",
    "content": "\n"
  },
  {
    "path": "examples/seaography_example/migration/src/m20230102_000001_seed_bakery_data.rs",
    "content": "use crate::entity::{prelude::*, *};\nuse sea_orm::entity::*;\nuse sea_orm_migration::prelude::*;\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let bakery = bakery::ActiveModel {\n            name: Set(\"SeaSide Bakery\".to_owned()),\n            profit_margin: Set(10.4),\n            ..Default::default()\n        };\n        let sea = Bakery::insert(bakery).exec(db).await?.last_insert_id;\n\n        let bakery = bakery::ActiveModel {\n            name: Set(\"LakeSide Bakery\".to_owned()),\n            profit_margin: Set(5.8),\n            ..Default::default()\n        };\n        let lake = Bakery::insert(bakery).exec(db).await?.last_insert_id;\n\n        let alice = baker::ActiveModel {\n            name: Set(\"Alice\".to_owned()),\n            contact: Set(\"+44 15273388\".to_owned()),\n            bakery_id: Set(Some(sea)),\n            ..Default::default()\n        };\n        let alice = Baker::insert(alice).exec(db).await?.last_insert_id;\n\n        let bob = baker::ActiveModel {\n            name: Set(\"Bob\".to_owned()),\n            contact: Set(\"+852 12345678\".to_owned()),\n            bakery_id: Set(Some(lake)),\n            ..Default::default()\n        };\n        let bob = Baker::insert(bob).exec(db).await?.last_insert_id;\n\n        let cake = cake::ActiveModel {\n            name: Set(\"Chocolate Cake\".to_owned()),\n            price: Set(\"10.25\".parse().unwrap()),\n            gluten_free: Set(0),\n            bakery_id: Set(Some(sea)),\n            ..Default::default()\n        };\n        let choco = Cake::insert(cake).exec(db).await?.last_insert_id;\n\n        let mut cake = cake::ActiveModel {\n            name: Set(\"Double Chocolate\".to_owned()),\n            price: Set(\"12.5\".parse().unwrap()),\n            gluten_free: Set(0),\n            bakery_id: Set(Some(sea)),\n            ..Default::default()\n        };\n        let double_1 = Cake::insert(cake.clone()).exec(db).await?.last_insert_id;\n        cake.bakery_id = Set(Some(lake));\n        let double_2 = Cake::insert(cake).exec(db).await?.last_insert_id;\n\n        let mut cake = cake::ActiveModel {\n            name: Set(\"Lemon Cake\".to_owned()),\n            price: Set(\"8.8\".parse().unwrap()),\n            gluten_free: Set(0),\n            bakery_id: Set(Some(sea)),\n            ..Default::default()\n        };\n        let lemon_1 = Cake::insert(cake.clone()).exec(db).await?.last_insert_id;\n        cake.bakery_id = Set(Some(lake));\n        let lemon_2 = Cake::insert(cake).exec(db).await?.last_insert_id;\n\n        let mut cake = cake::ActiveModel {\n            name: Set(\"Strawberry Cake\".to_owned()),\n            price: Set(\"9.9\".parse().unwrap()),\n            gluten_free: Set(0),\n            bakery_id: Set(Some(sea)),\n            ..Default::default()\n        };\n        let straw_1 = Cake::insert(cake.clone()).exec(db).await?.last_insert_id;\n        cake.bakery_id = Set(Some(lake));\n        let straw_2 = Cake::insert(cake).exec(db).await?.last_insert_id;\n\n        let cake = cake::ActiveModel {\n            name: Set(\"Orange Cake\".to_owned()),\n            price: Set(\"6.5\".parse().unwrap()),\n            gluten_free: Set(1),\n            bakery_id: Set(Some(lake)),\n            ..Default::default()\n        };\n        let orange = Cake::insert(cake).exec(db).await?.last_insert_id;\n\n        let mut cake = cake::ActiveModel {\n            name: Set(\"New York Cheese\".to_owned()),\n            price: Set(\"12.5\".parse().unwrap()),\n            gluten_free: Set(0),\n            bakery_id: Set(Some(sea)),\n            ..Default::default()\n        };\n        let cheese_1 = Cake::insert(cake.clone()).exec(db).await?.last_insert_id;\n        cake.bakery_id = Set(Some(lake));\n        let cheese_2 = Cake::insert(cake).exec(db).await?.last_insert_id;\n\n        let mut cake = cake::ActiveModel {\n            name: Set(\"Blueburry Cheese\".to_owned()),\n            price: Set(\"11.5\".parse().unwrap()),\n            gluten_free: Set(1),\n            bakery_id: Set(Some(sea)),\n            ..Default::default()\n        };\n        let blue_1 = Cake::insert(cake.clone()).exec(db).await?.last_insert_id;\n        cake.bakery_id = Set(Some(lake));\n        let blue_2 = Cake::insert(cake).exec(db).await?.last_insert_id;\n\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(choco),\n            baker_id: Set(alice),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(double_1),\n            baker_id: Set(alice),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(double_2),\n            baker_id: Set(bob),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(lemon_1),\n            baker_id: Set(alice),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(lemon_2),\n            baker_id: Set(bob),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(straw_1),\n            baker_id: Set(alice),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(straw_2),\n            baker_id: Set(bob),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(orange),\n            baker_id: Set(bob),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(cheese_1),\n            baker_id: Set(alice),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(cheese_1),\n            baker_id: Set(bob),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(cheese_2),\n            baker_id: Set(alice),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(cheese_2),\n            baker_id: Set(bob),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(blue_1),\n            baker_id: Set(alice),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n        let rel = cake_baker::ActiveModel {\n            cake_id: Set(blue_2),\n            baker_id: Set(bob),\n        };\n        CakeBaker::insert(rel).exec(db).await?;\n\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        Cake::delete_many().exec(db).await?;\n        Baker::delete_many().exec(db).await?;\n        Bakery::delete_many().exec(db).await?;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/seaography_example/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/tonic_example/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"sea-orm-tonic-example\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html\n\n[workspace]\nmembers = [\".\", \"api\", \"entity\", \"migration\"]\n\n[dependencies]\ntokio             = { version = \"1.29\", features = [\"macros\", \"rt-multi-thread\", \"full\"] }\ntonic             = \"0.9.2\"\ntonic-example-api = { path = \"api\" }\n\n[[bin]]\nname = \"server\"\npath = \"./src/server.rs\"\n\n[[bin]]\nname = \"client\"\npath = \"./src/client.rs\"\n"
  },
  {
    "path": "examples/tonic_example/README.md",
    "content": "# Tonic + gRPC + SeaORM\n\nSimple implementation of gRPC using SeaORM.\n\nrun server using\n\n```bash\ncargo run --bin server\n```\n\nrun client using\n\n```bash\ncargo run --bin client\n```\n\nRun tests:\n\n```bash\ncd api\ncargo test\n```\n"
  },
  {
    "path": "examples/tonic_example/api/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"tonic-example-api\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nentity    = { path = \"../entity\" }\nmigration = { path = \"../migration\" }\nprost     = \"0.11.9\"\nserde     = \"1.0\"\ntokio     = { version = \"1.29\", features = [\"full\"] }\ntonic     = \"0.9.2\"\n\n[dependencies.sea-orm]\nfeatures = [\n    \"debug-print\",\n    \"runtime-tokio-rustls\",\n    # \"sqlx-mysql\",\n    # \"sqlx-postgres\",\n    \"sqlx-sqlite\",\n]\npath = \"../../../\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n\n[build-dependencies]\ntonic-build = \"0.9.2\"\n"
  },
  {
    "path": "examples/tonic_example/api/build.rs",
    "content": "fn main() {\n    let proto_file = \"./proto/post.proto\";\n\n    tonic_build::configure()\n        .build_server(true)\n        .compile(&[proto_file], &[\".\"])\n        .unwrap_or_else(|e| panic!(\"protobuf compile error: {}\", e));\n\n    println!(\"cargo:rerun-if-changed={}\", proto_file);\n}\n"
  },
  {
    "path": "examples/tonic_example/api/proto/post.proto",
    "content": "syntax = \"proto3\";\n\npackage Post;\n\nservice Blogpost {\n  rpc GetPosts(PostPerPage) returns (PostList) {}\n  rpc AddPost(Post) returns (PostId) {}\n  rpc UpdatePost(Post) returns (ProcessStatus) {}\n  rpc DeletePost(PostId) returns (ProcessStatus) {}\n  rpc GetPostById(PostId) returns (Post) {}\n}\n\nmessage PostPerPage { uint64 per_page = 1; }\n\nmessage ProcessStatus { bool success = 1; }\n\nmessage PostId { int32 id = 1; }\n\nmessage Post {\n  int32 id = 1;\n  string title = 2;\n  string content = 3;\n}\n\nmessage PostList { repeated Post post = 1; }"
  },
  {
    "path": "examples/tonic_example/api/src/lib.rs",
    "content": "pub mod service;\n\nuse tonic::transport::Server;\nuse tonic::{Request, Response, Status};\n\nuse entity::post;\nuse migration::{Migrator, MigratorTrait};\nuse sea_orm::{Database, DatabaseConnection};\nuse service::{Mutation, Query};\n\nuse std::env;\n\npub mod post_mod {\n    tonic::include_proto!(\"post\");\n}\n\nuse post_mod::{\n    Post, PostId, PostList, PostPerPage, ProcessStatus,\n    blogpost_server::{Blogpost, BlogpostServer},\n};\n\nimpl Post {\n    fn into_model(self) -> post::Model {\n        post::Model {\n            id: self.id,\n            title: self.title,\n            text: self.content,\n        }\n    }\n}\n\n#[derive(Default)]\npub struct MyServer {\n    connection: DatabaseConnection,\n}\n\n#[tonic::async_trait]\nimpl Blogpost for MyServer {\n    async fn get_posts(&self, request: Request<PostPerPage>) -> Result<Response<PostList>, Status> {\n        let conn = &self.connection;\n        let posts_per_page = request.into_inner().per_page;\n\n        let mut response = PostList { post: Vec::new() };\n\n        let (posts, _) = Query::find_posts_in_page(conn, 1, posts_per_page)\n            .await\n            .expect(\"Cannot find posts in page\");\n\n        for post in posts {\n            response.post.push(Post {\n                id: post.id,\n                title: post.title,\n                content: post.text,\n            });\n        }\n\n        Ok(Response::new(response))\n    }\n\n    async fn add_post(&self, request: Request<Post>) -> Result<Response<PostId>, Status> {\n        let conn = &self.connection;\n\n        let input = request.into_inner().into_model();\n\n        let inserted = Mutation::create_post(conn, input)\n            .await\n            .expect(\"could not insert post\");\n\n        let response = PostId {\n            id: inserted.id.unwrap(),\n        };\n\n        Ok(Response::new(response))\n    }\n\n    async fn update_post(&self, request: Request<Post>) -> Result<Response<ProcessStatus>, Status> {\n        let conn = &self.connection;\n        let input = request.into_inner().into_model();\n\n        match Mutation::update_post_by_id(conn, input.id, input).await {\n            Ok(_) => Ok(Response::new(ProcessStatus { success: true })),\n            Err(_) => Ok(Response::new(ProcessStatus { success: false })),\n        }\n    }\n\n    async fn delete_post(\n        &self,\n        request: Request<PostId>,\n    ) -> Result<Response<ProcessStatus>, Status> {\n        let conn = &self.connection;\n        let id = request.into_inner().id;\n\n        match Mutation::delete_post(conn, id).await {\n            Ok(_) => Ok(Response::new(ProcessStatus { success: true })),\n            Err(_) => Ok(Response::new(ProcessStatus { success: false })),\n        }\n    }\n\n    async fn get_post_by_id(&self, request: Request<PostId>) -> Result<Response<Post>, Status> {\n        let conn = &self.connection;\n        let id = request.into_inner().id;\n\n        if let Some(post) = Query::find_post_by_id(conn, id).await.ok().flatten() {\n            Ok(Response::new(Post {\n                id,\n                title: post.title,\n                content: post.text,\n            }))\n        } else {\n            Err(Status::new(\n                tonic::Code::Aborted,\n                \"Could not find post with id \".to_owned() + &id.to_string(),\n            ))\n        }\n    }\n}\n\n#[tokio::main]\nasync fn start() -> Result<(), Box<dyn std::error::Error>> {\n    let addr = \"0.0.0.0:50051\".parse()?;\n\n    let database_url = env::var(\"DATABASE_URL\").expect(\"DATABASE_URL must be set\");\n\n    // establish database connection\n    let connection = Database::connect(&database_url).await?;\n    Migrator::up(&connection, None).await?;\n\n    let hello_server = MyServer { connection };\n    Server::builder()\n        .add_service(BlogpostServer::new(hello_server))\n        .serve(addr)\n        .await?;\n\n    Ok(())\n}\n\npub fn main() {\n    let result = start();\n\n    if let Some(err) = result.err() {\n        println!(\"Error: {err}\");\n    }\n}\n"
  },
  {
    "path": "examples/tonic_example/api/src/service/mod.rs",
    "content": "mod mutation;\nmod query;\n\npub use mutation::*;\npub use query::*;\n"
  },
  {
    "path": "examples/tonic_example/api/src/service/mutation.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Mutation;\n\nimpl Mutation {\n    pub async fn create_post(\n        db: &DbConn,\n        form_data: post::Model,\n    ) -> Result<post::ActiveModel, DbErr> {\n        post::ActiveModel {\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n            ..Default::default()\n        }\n        .save(db)\n        .await\n    }\n\n    pub async fn update_post_by_id(\n        db: &DbConn,\n        id: i32,\n        form_data: post::Model,\n    ) -> Result<post::Model, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post::ActiveModel {\n            id: post.id,\n            title: Set(form_data.title.to_owned()),\n            text: Set(form_data.text.to_owned()),\n        }\n        .update(db)\n        .await\n    }\n\n    pub async fn delete_post(db: &DbConn, id: i32) -> Result<DeleteResult, DbErr> {\n        let post: post::ActiveModel = Post::find_by_id(id)\n            .one(db)\n            .await?\n            .ok_or(DbErr::Custom(\"Cannot find post.\".to_owned()))\n            .map(Into::into)?;\n\n        post.delete(db).await\n    }\n\n    pub async fn delete_all_posts(db: &DbConn) -> Result<DeleteResult, DbErr> {\n        Post::delete_many().exec(db).await\n    }\n}\n"
  },
  {
    "path": "examples/tonic_example/api/src/service/query.rs",
    "content": "use ::entity::{post, post::Entity as Post};\nuse sea_orm::*;\n\npub struct Query;\n\nimpl Query {\n    pub async fn find_post_by_id(db: &DbConn, id: i32) -> Result<Option<post::Model>, DbErr> {\n        Post::find_by_id(id).one(db).await\n    }\n\n    /// If ok, returns (post models, num pages).\n    pub async fn find_posts_in_page(\n        db: &DbConn,\n        page: u64,\n        posts_per_page: u64,\n    ) -> Result<(Vec<post::Model>, u64), DbErr> {\n        // Setup paginator\n        let paginator = Post::find()\n            .order_by_asc(post::Column::Id)\n            .paginate(db, posts_per_page);\n        let num_pages = paginator.num_pages().await?;\n\n        // Fetch paginated posts\n        paginator.fetch_page(page - 1).await.map(|p| (p, num_pages))\n    }\n}\n"
  },
  {
    "path": "examples/tonic_example/api/tests/crud_tests.rs",
    "content": "use entity::post;\nuse sea_orm::Database;\nuse tonic_example_api::service::{Mutation, Query};\n\n#[tokio::test]\nasync fn crud_tests() {\n    let db = &Database::connect(\"sqlite::memory:\").await.unwrap();\n\n    db.get_schema_builder()\n        .register(post::Entity)\n        .apply(db)\n        .await\n        .unwrap();\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title A\".to_owned(),\n                text: \"Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(1),\n                title: sea_orm::ActiveValue::Unchanged(\"Title A\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text A\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Mutation::create_post(\n            db,\n            post::Model {\n                id: 0,\n                title: \"Title B\".to_owned(),\n                text: \"Text B\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::ActiveModel {\n                id: sea_orm::ActiveValue::Unchanged(2),\n                title: sea_orm::ActiveValue::Unchanged(\"Title B\".to_owned()),\n                text: sea_orm::ActiveValue::Unchanged(\"Text B\".to_owned())\n            }\n        );\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 1).await.unwrap().unwrap();\n\n        assert_eq!(post.id, 1);\n        assert_eq!(post.title, \"Title A\");\n    }\n\n    {\n        let post = Mutation::update_post_by_id(\n            db,\n            1,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            },\n        )\n        .await\n        .unwrap();\n\n        assert_eq!(\n            post,\n            post::Model {\n                id: 1,\n                title: \"New Title A\".to_owned(),\n                text: \"New Text A\".to_owned(),\n            }\n        );\n    }\n\n    {\n        let result = Mutation::delete_post(db, 2).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n\n    {\n        let post = Query::find_post_by_id(db, 2).await.unwrap();\n        assert!(post.is_none());\n    }\n\n    {\n        let result = Mutation::delete_all_posts(db).await.unwrap();\n\n        assert_eq!(result.rows_affected, 1);\n    }\n}\n"
  },
  {
    "path": "examples/tonic_example/entity/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"entity\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"entity\"\npath = \"src/lib.rs\"\n\n[dependencies]\nserde = { version = \"1\", features = [\"derive\"] }\n\n[dependencies.sea-orm]\npath    = \"../../../\"    # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm version\n"
  },
  {
    "path": "examples/tonic_example/entity/src/lib.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub mod prelude;\n\npub mod post;\n"
  },
  {
    "path": "examples/tonic_example/entity/src/post.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"post\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    pub title: String,\n    #[sea_orm(column_type = \"Text\")]\n    pub text: String,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "examples/tonic_example/entity/src/prelude.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub use super::post::Entity as Post;\n"
  },
  {
    "path": "examples/tonic_example/migration/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nentity = { path = \"../entity\" }\ntokio  = { version = \"1\", features = [\"macros\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable following runtime and db backend features if you want to run migration via CLI\n    \"runtime-tokio-native-tls\",\n    \"sqlx-sqlite\",\n]\npath = \"../../../sea-orm-migration\" # remove this line in your own project\nversion = \"~2.0.0-rc.37\" # sea-orm-migration version\n"
  },
  {
    "path": "examples/tonic_example/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "examples/tonic_example/migration/src/lib.rs",
    "content": "pub use sea_orm_migration::prelude::*;\n\nmod m20220120_000001_create_post_table;\nmod m20220120_000002_seed_posts;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220120_000001_create_post_table::Migration),\n            Box::new(m20220120_000002_seed_posts::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "examples/tonic_example/migration/src/m20220120_000001_create_post_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"post\")\n                    .if_not_exists()\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"title\"))\n                    .col(string(\"text\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"post\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "examples/tonic_example/migration/src/m20220120_000002_seed_posts.rs",
    "content": "use entity::post;\nuse sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set};\nuse sea_orm_migration::prelude::*;\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let seed_data = vec![\n            (\"First Post\", \"This is the first post.\"),\n            (\"Second Post\", \"This is another post.\"),\n        ];\n\n        for (title, text) in seed_data {\n            let model = post::ActiveModel {\n                title: Set(title.to_string()),\n                text: Set(text.to_string()),\n                ..Default::default()\n            };\n            model.insert(db).await?;\n        }\n\n        println!(\"Posts table seeded successfully.\");\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let titles_to_delete = vec![\"First Post\", \"Second Post\"];\n        post::Entity::delete_many()\n            .filter(post::Column::Title.is_in(titles_to_delete))\n            .exec(db)\n            .await?;\n\n        println!(\"Posts seeded data removed.\");\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "examples/tonic_example/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "examples/tonic_example/src/client.rs",
    "content": "use tonic::Request;\nuse tonic::transport::Endpoint;\n\nuse tonic_example_api::post_mod::{PostPerPage, blogpost_client::BlogpostClient};\n\n#[tokio::main]\nasync fn main() -> Result<(), Box<dyn std::error::Error>> {\n    let addr = Endpoint::from_static(\"http://0.0.0.0:50051\");\n\n    /*\n    Client code is not implemented in completely\n     as it would just make the code base look too complicated ....\n     and interface requires a lot of boilerplate code to implement.\n\n     But a basic implementation is given below ....\n     please refer it to implement other ways to make your code pretty\n    */\n\n    let mut client = BlogpostClient::connect(addr).await?;\n    let request = Request::new(PostPerPage { per_page: 10 });\n    let response = client.get_posts(request).await?;\n\n    for post in response.into_inner().post.iter() {\n        println!(\"{post:?}\");\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "examples/tonic_example/src/server.rs",
    "content": "fn main() {\n    tonic_example_api::main();\n}\n"
  },
  {
    "path": "issues/1143/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-1143\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nserde = \"1\"\ntokio = { version = \"1\", features = [\"rt\", \"rt-multi-thread\", \"macros\"] }\n\n[dependencies.sea-orm]\ndefault-features = false\nfeatures         = [\"macros\", \"runtime-tokio-native-tls\"]\npath             = \"../../\"\n"
  },
  {
    "path": "issues/1143/src/entity/mod.rs",
    "content": "pub mod sea_orm_active_enums;\n"
  },
  {
    "path": "issues/1143/src/entity/sea_orm_active_enums.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"String\", db_type = \"String(StringLen::N(1))\")]\npub enum Category {\n    #[sea_orm(string_value = \"B\")]\n    Big,\n    #[sea_orm(string_value = \"S\")]\n    Small,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"i32\", db_type = \"Integer\")]\npub enum Color {\n    #[sea_orm(num_value = 0)]\n    Black,\n    #[sea_orm(num_value = 1)]\n    White,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"tea\")]\npub enum Tea {\n    #[sea_orm(string_value = \"EverydayTea\")]\n    EverydayTea,\n    #[sea_orm(string_value = \"BreakfastTea\")]\n    BreakfastTea,\n}\n"
  },
  {
    "path": "issues/1143/src/main.rs",
    "content": "mod entity;\n\n#[tokio::main]\nasync fn main() {}\n"
  },
  {
    "path": "issues/1278/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-1278\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nserde = \"1\"\ntokio = { version = \"1\", features = [\"rt\", \"rt-multi-thread\", \"macros\"] }\n\n[dependencies.sea-orm]\ndefault-features = false\nfeatures         = [\"macros\", \"runtime-tokio-native-tls\"]\npath             = \"../../\"\n"
  },
  {
    "path": "issues/1278/src/entity.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"pool\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/1278/src/main.rs",
    "content": "use sea_orm::{\n    Database, DeriveColumn, EntityTrait, EnumIter, FromQueryResult, QuerySelect,\n};\n\nmod entity;\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\nenum QueryAs {\n    PoolName,\n}\n\n#[derive(Debug, FromQueryResult)]\nstruct PoolResult {\n    name: String,\n}\n\n#[tokio::main]\nasync fn main() {\n    let db = Database::connect(\"xxxx\").await.unwrap();\n\n    let result1 = entity::Entity::find()\n        .select_only()\n        .column(entity::Column::Name)\n        .into_model::<PoolResult>()\n        .all(&db)\n        .await\n        .unwrap();\n\n    let result2: Vec<String> = entity::Entity::find()\n        .select_only()\n        .column_as(entity::Column::Name, QueryAs::PoolName)\n        .into_values::<_, QueryAs>()\n        .all(&db)\n        .await\n        .unwrap();\n}"
  },
  {
    "path": "issues/1357/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-1357\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nanyhow = \"1\"\nserde  = \"1\"\ntokio  = { version = \"1\", features = [\"rt\", \"rt-multi-thread\", \"macros\"] }\n\n[dependencies.sea-orm]\ndefault-features = false\nfeatures         = [\"macros\", \"runtime-tokio-native-tls\", \"sqlx-sqlite\"]\npath             = \"../../\"\n"
  },
  {
    "path": "issues/1357/src/entity.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"pool\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id: i64,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/1357/src/main.rs",
    "content": "use anyhow::Result;\nuse sea_orm::{ConnectionTrait, Database, EntityTrait, IntoActiveModel, Schema};\n\nmod entity;\n\nuse entity::*;\n\n#[tokio::main]\nasync fn main() -> Result<()> {\n    let db = Database::connect(\"sqlite::memory:\").await.unwrap();\n\n    let builder = db.get_database_backend();\n    let schema = Schema::new(builder);\n    let stmt = schema.create_table_from_entity(Entity);\n    db.execute(builder.build(&stmt)).await?;\n\n    let model = Model {\n        id: 100,\n        name: \"Hello\".to_owned(),\n    };\n\n    let res = Entity::insert(model.clone().into_active_model())\n        .exec(&db)\n        .await?;\n\n    assert_eq!(Entity::find().one(&db).await?, Some(model.clone()));\n    assert_eq!(res.last_insert_id, model.id);\n\n    let model = Model {\n        id: -10,\n        name: \"World\".to_owned(),\n    };\n\n    let res = Entity::insert(model.clone().into_active_model())\n        .exec(&db)\n        .await?;\n\n    assert_eq!(Entity::find().one(&db).await?, Some(model.clone()));\n    assert_eq!(res.last_insert_id, model.id);\n\n    Ok(())\n}\n"
  },
  {
    "path": "issues/1473/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-1473\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies.sea-orm]\ndefault-features = false\nfeatures         = [\"macros\", \"runtime-tokio-native-tls\"]\npath             = \"../../\"\n"
  },
  {
    "path": "issues/1473/src/main.rs",
    "content": "use sea_orm::{DeriveIden, Iden};\n\n#[derive(DeriveIden)]\nenum Character {\n    Table,\n    Id,\n}\n\n#[derive(DeriveIden)]\nstruct Glyph;\n\nfn main() {\n    assert_eq!(Character::Table.to_string(), \"character\");\n    assert_eq!(Character::Id.to_string(), \"id\");\n    assert_eq!(Glyph.to_string(), \"glyph\");\n}\n"
  },
  {
    "path": "issues/1582/schema.sql",
    "content": "CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";\n\n-- Table without any dependencies\nCREATE TABLE IF NOT EXISTS public.table_1 (\n  id uuid DEFAULT public.uuid_generate_v4() NOT NULL PRIMARY KEY\n);\n\n-- Table that depends on table_1\nCREATE TABLE IF NOT EXISTS public.table_2 (\n    id uuid DEFAULT public.uuid_generate_v4() NOT NULL,\n    table_1_id uuid NOT NULL REFERENCES public.table_1(id),\n    -- Add constraints / uniques here if needed. Will auto apply to all partitions.\n    PRIMARY KEY (id, table_1_id)\n)\nPARTITION BY HASH (table_1_id);\n\n-- Generate partition tables.\n-- No clue if this works on other SQL implementations than PostgreSQL.\nDO $$\n  DECLARE\n    counter integer := 0;\n  BEGIN\n    WHILE counter < 128\n    LOOP\n      EXECUTE('CREATE TABLE IF NOT EXISTS public.table_2_p_hash_p' || counter || ' PARTITION OF public.table_2 FOR VALUES WITH (MODULUS 128, REMAINDER ' || counter || ');');\n      counter := counter + 1;\n    END LOOP;\nEND$$;\n\n-- Table that depends on table_1 and table_2.\n-- Foreign keys to table_2 are through the partitions\nCREATE TABLE IF NOT EXISTS public.table_3 (\n    id uuid DEFAULT public.uuid_generate_v4() NOT NULL PRIMARY KEY,\n    -- FK to table_1 only needed so that we can FK to table_2\n    table_1_id uuid REFERENCES public.table_1(id) NOT NULL,\n    table_2_id uuid NOT NULL,\n    FOREIGN KEY (table_2_id, table_1_id) REFERENCES public.table_2(id, table_1_id)\n);\n\n"
  },
  {
    "path": "issues/1599/Cargo.toml",
    "content": "[workspace]\nmembers = [\"entity\", \"graphql\"]\n"
  },
  {
    "path": "issues/1599/entity/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"entity\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"entity\"\npath = \"src/lib.rs\"\n\n[dependencies]\nasync-graphql = { version = \"5\", optional = true }\nsea-orm       = { path = \"../../../\" }\nseaography    = { path = \"../../../../seaography\", optional = true }\n\n[features]\nseaography = [\"dep:seaography\", \"async-graphql\", \"sea-orm/seaography\"]\n"
  },
  {
    "path": "issues/1599/entity/src/cake.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_name = \"name\", enum_name = \"Name\")]\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n    #[sea_orm(\n        has_many = \"super::fruit::Entity\",\n        on_condition = r#\"super::fruit::Column::Name.like(\"%tropical%\")\"#\n    )]\n    TropicalFruit,\n    #[sea_orm(\n        has_many = \"super::fruit::Entity\",\n        condition_type = \"any\",\n        on_condition = r#\"super::fruit::Column::Name.like(\"%tropical%\")\"#\n    )]\n    OrTropicalFruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]\npub enum RelatedEntity {\n    #[sea_orm(entity = \"super::fruit::Entity\")]\n    Fruit,\n    #[sea_orm(entity = \"super::filling::Entity\")]\n    Filling,\n    #[sea_orm(entity = \"super::fruit::Entity\", def = \"Relation::TropicalFruit.def()\")]\n    TropicalFruit,\n    #[sea_orm(\n        entity = \"super::fruit::Entity\",\n        def = \"Relation::OrTropicalFruit.def()\"\n    )]\n    OrTropicalFruit,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/1599/entity/src/cake_filling.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> &'static str {\n        \"cake_filling\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\npub struct Model {\n    pub cake_id: i32,\n    pub filling_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    CakeId,\n    FillingId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    CakeId,\n    FillingId,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = (i32, i32);\n\n    fn auto_increment() -> bool {\n        false\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Cake,\n    Filling,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::CakeId => ColumnType::Integer.def(),\n            Self::FillingId => ColumnType::Integer.def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Cake => Entity::belongs_to(super::cake::Entity)\n                .from(Column::CakeId)\n                .to(super::cake::Column::Id)\n                .into(),\n            Self::Filling => Entity::belongs_to(super::filling::Entity)\n                .from(Column::FillingId)\n                .to(super::filling::Column::Id)\n                .into(),\n        }\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/1599/entity/src/filling.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n#[sea_orm(table_name = \"filling\")]\npub struct Entity;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n    pub vendor_id: Option<i32>,\n    #[sea_orm(ignore)]\n    pub ignored_attr: i32,\n}\n\n// If your column names are not in snake-case, derive `DeriveCustomColumn` here.\n#[derive(Copy, Clone, Debug, EnumIter, DeriveCustomColumn)]\npub enum Column {\n    Id,\n    Name,\n    VendorId,\n}\n\n// Then, customize each column names here.\nimpl IdenStatic for Column {\n    fn as_str(&self) -> &str {\n        match self {\n            // Override column names\n            Self::Id => \"id\",\n            // Leave all other columns using default snake-case values\n            _ => self.default_as_str(),\n        }\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::None).def(),\n            Self::VendorId => ColumnType::Integer.def().nullable(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        panic!(\"No RelationDef\")\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Cake.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Filling.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/1599/entity/src/fruit.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"fruit\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[cfg_attr(feature = \"with-json\", serde(skip_deserializing))]\n    pub id: i32,\n    pub name: String,\n    pub cake_id: Option<i32>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\"\n    )]\n    Cake,\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/1599/entity/src/lib.rs",
    "content": "pub mod cake;\npub mod cake_filling;\npub mod filling;\npub mod fruit;\n"
  },
  {
    "path": "issues/1599/graphql/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"graphql\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nasync-graphql = { version = \"5.0.6\", features = [\n    \"decimal\",\n    \"chrono\",\n    \"dataloader\",\n    \"dynamic-schema\",\n] }\nasync-graphql-poem = { version = \"5.0.6\" }\nasync-trait = { version = \"0.1.64\" }\ndotenv = \"0.15.0\"\nlazy_static = { version = \"1.4.0\" }\npoem = { version = \"1.3.55\" }\ntokio = { version = \"1.26.0\", features = [\"macros\", \"rt-multi-thread\"] }\ntracing = { version = \"0.1.37\" }\ntracing-subscriber = { version = \"0.3.16\" }\n\nentity     = { path = \"../entity\", features = [\"seaography\"] }\nsea-orm    = { path = \"../../../\" }\nseaography = { path = \"../../../../seaography\" }\n"
  },
  {
    "path": "issues/1599/graphql/src/main.rs",
    "content": "use async_graphql::{\n    dataloader::DataLoader,\n    http::{playground_source, GraphQLPlaygroundConfig},\n};\nuse async_graphql_poem::GraphQL;\nuse dotenv::dotenv;\nuse lazy_static::lazy_static;\nuse poem::{get, handler, listener::TcpListener, web::Html, IntoResponse, Route, Server};\nuse sea_orm::{prelude::*, Database};\nuse std::env;\n\npub mod query_root;\n\npub struct OrmDataloader {\n    pub db: DatabaseConnection,\n}\n\nlazy_static! {\n    static ref URL: String = env::var(\"URL\").unwrap_or(\"0.0.0.0:8000\".into());\n    static ref ENDPOINT: String = env::var(\"ENDPOINT\").unwrap_or(\"/\".into());\n    static ref DATABASE_URL: String =\n        env::var(\"DATABASE_URL\").expect(\"DATABASE_URL environment variable not set\");\n    static ref DEPTH_LIMIT: Option<usize> = env::var(\"DEPTH_LIMIT\").map_or(None, |data| Some(\n        data.parse().expect(\"DEPTH_LIMIT is not a number\")\n    ));\n    static ref COMPLEXITY_LIMIT: Option<usize> = env::var(\"COMPLEXITY_LIMIT\")\n        .map_or(None, |data| {\n            Some(data.parse().expect(\"COMPLEXITY_LIMIT is not a number\"))\n        });\n}\n\n#[handler]\nasync fn graphql_playground() -> impl IntoResponse {\n    Html(playground_source(GraphQLPlaygroundConfig::new(&ENDPOINT)))\n}\n\n#[tokio::main]\nasync fn main() {\n    dotenv().ok();\n    tracing_subscriber::fmt()\n        .with_max_level(tracing::Level::INFO)\n        .with_test_writer()\n        .init();\n    let database = Database::connect(&*DATABASE_URL)\n        .await\n        .expect(\"Fail to initialize database connection\");\n    let orm_dataloader: DataLoader<OrmDataloader> = DataLoader::new(\n        OrmDataloader {\n            db: database.clone(),\n        },\n        tokio::spawn,\n    );\n    let schema =\n        query_root::schema(database, orm_dataloader, *DEPTH_LIMIT, *COMPLEXITY_LIMIT).unwrap();\n    let app = Route::new().at(\n        &*ENDPOINT,\n        get(graphql_playground).post(GraphQL::new(schema)),\n    );\n    println!(\"Visit GraphQL Playground at http://{}\", *URL);\n    Server::new(TcpListener::bind(&*URL))\n        .run(app)\n        .await\n        .expect(\"Fail to start web server\");\n}\n"
  },
  {
    "path": "issues/1599/graphql/src/query_root.rs",
    "content": "use crate::OrmDataloader;\nuse async_graphql::{dataloader::DataLoader, dynamic::*};\nuse entity::*;\nuse sea_orm::DatabaseConnection;\nuse seaography::{Builder, BuilderContext};\n\nlazy_static::lazy_static! { static ref CONTEXT : BuilderContext = BuilderContext :: default () ; }\n\npub fn schema(\n    database: DatabaseConnection,\n    orm_dataloader: DataLoader<OrmDataloader>,\n    depth: Option<usize>,\n    complexity: Option<usize>,\n) -> Result<Schema, SchemaError> {\n    let mut builder = Builder::new(&CONTEXT);\n\n    // Register entity including relations\n    seaography::register_entities!(builder, [cake]);\n    // Register entity only, no relations\n    seaography::register_entities_without_relation!(builder, [cake_filling, filling, fruit]);\n\n    let schema = builder.schema_builder();\n    let schema = if let Some(depth) = depth {\n        schema.limit_depth(depth)\n    } else {\n        schema\n    };\n    let schema = if let Some(complexity) = complexity {\n        schema.limit_complexity(complexity)\n    } else {\n        schema\n    };\n    schema.data(database).data(orm_dataloader).finish()\n}\n"
  },
  {
    "path": "issues/1790/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-1790\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nanyhow = \"1\"\nserde  = \"1\"\ntokio  = { version = \"1\", features = [\"rt\", \"rt-multi-thread\", \"macros\"] }\n\n[dependencies.sea-orm]\ndefault-features = false\nfeatures         = [\"macros\", \"runtime-tokio-native-tls\", \"sqlx-sqlite\"]\npath             = \"../../\"\n"
  },
  {
    "path": "issues/1790/insert_test.rs",
    "content": "mod tests {\n    // currently ok\n    #[test]\n    fn insert_do_nothing_postgres() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::new()\n                .add(cake::Model {\n                    id: 1,\n                    name: \"Apple Pie\".to_owned(),\n                })\n                .on_conflict(OnConflict::new()\n                    .do_nothing()\n                    .to_owned()\n                )\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie') ON CONFLICT DO NOTHING\"#,\n        );\n    }\n\n    //failed to run\n    #[test]\n    fn insert_do_nothing_mysql() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::new()\n                .add(cake::Model {\n                    id: 1,\n                    name: \"Apple Pie\".to_owned(),\n                })\n                .on_conflict(OnConflict::new()\n                    .do_nothing()\n                    .to_owned()\n                )\n                .build(DbBackend::Mysql)\n                .to_string(),\n            r#\"INSERT IGNORE INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#,\n        );\n    }\n\n    // currently ok\n    #[test]\n    fn insert_do_nothing() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::new()\n                .add(cake::Model {\n                    id: 1,\n                    name: \"Apple Pie\".to_owned(),\n                })\n                .on_conflict(OnConflict::new()\n                    .do_nothing()\n                    .to_owned()\n                )\n                .build(DbBackend::Sqlite)\n                .to_string(),\n            r#\"INSERT IGNORE INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#,\n        );\n    }\n}"
  },
  {
    "path": "issues/249/Cargo.toml",
    "content": "[workspace]\nmembers = [\"service\", \"app\"]\n"
  },
  {
    "path": "issues/249/README.md",
    "content": "# Demo of a pure logic crate depending on SeaORM with no enabled features"
  },
  {
    "path": "issues/249/app/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-249-app\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nsea-orm = { path = \"../../../\", default-features = false, features = [\n    \"macros\",\n    \"tests-cfg\",\n    \"sqlx-sqlite\",\n    \"runtime-async-std-native-tls\",\n] }\nservice = { path = \"../service\" }\n"
  },
  {
    "path": "issues/249/app/src/main.rs",
    "content": "use service::clone_a_model;\n\nuse sea_orm::tests_cfg::cake;\n\nfn main() {\n\tlet c1 = cake::Model {\n\t\tid: 1,\n\t\tname: \"Cheese\".to_owned(),\n\t};\n\n\tlet c2 = clone_a_model(&c1);\n\n\tprintln!(\"{:?}\", c2);\n}"
  },
  {
    "path": "issues/249/service/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"service\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nsea-orm = { path = \"../../../\", default-features = false }\n\n[dev-dependencies]\nsea-orm = { path = \"../../../\", features = [\"mock\"] }\n"
  },
  {
    "path": "issues/249/service/src/lib.rs",
    "content": "pub use sea_orm::entity::*;\n\npub fn clone_a_model<M>(model: &M) -> M\nwhere\n\tM: ModelTrait {\n\tmodel.clone()\n}\n\n#[cfg(test)]\nmod tests {\n\tuse super::*;\n\n\t#[test]\n\tfn test() {\n\t\tprintln!(\"OK\");\n\t}\n}"
  },
  {
    "path": "issues/262/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-262\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nasync-std = { version = \"1\", features = [\"attributes\", \"tokio1\"] }\nsea-orm = { path = \"../../\", features = [\n    \"sqlx-all\",\n    \"runtime-async-std-native-tls\",\n    \"debug-print\",\n] }\n"
  },
  {
    "path": "issues/262/src/cake.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub md5hash: String,\n    pub md5_hash: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_case_transform_1() {\n        assert_eq!(Column::Md5hash.to_string().as_str(), \"md5hash\");\n        assert_eq!(Column::Md5Hash.to_string().as_str(), \"md5_hash\");\n    }\n}\n"
  },
  {
    "path": "issues/262/src/main.rs",
    "content": "mod cake;\nuse sea_orm::*;\n\n#[async_std::main]\npub async fn main() {\n    let db = Database::connect(\"mysql://sea:sea@localhost/bakery\")\n        .await\n        .unwrap();\n\n    async_std::task::spawn(async move {\n        cake::Entity::find().one(&db).await.unwrap();\n    })\n    .await;\n}\n"
  },
  {
    "path": "issues/319/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-319\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nasync-std = { version = \"1\", features = [\"attributes\", \"tokio1\"] }\nsea-orm = { path = \"../../\", features = [\n    \"sqlx-mysql\",\n    \"runtime-async-std-native-tls\",\n    \"with-json\",\n    \"with-chrono\",\n    \"macros\",\n], default-features = false }\nserde = { version = \"1\", features = [\"derive\"] }\n"
  },
  {
    "path": "issues/319/src/main.rs",
    "content": "mod material;\nuse sea_orm::*;\n\n#[async_std::main]\npub async fn main() {\n    let db = Database::connect(\"mysql://sea:sea@localhost/bakery\")\n        .await\n        .unwrap();\n\n    async_std::task::spawn(async move {\n        material::Entity::find().one(&db).await.unwrap();\n    })\n    .await;\n}\n"
  },
  {
    "path": "issues/319/src/material.rs",
    "content": "use sea_orm::entity::prelude::*;\nuse serde::{Serialize, Deserialize};\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"materials\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub created_at: DateTimeWithTimeZone,\n    pub updated_at: DateTimeWithTimeZone,\n    pub name: String,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub description: Option<String> ,\n    pub tag_ids: Vec<u8> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/324/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-324\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nsea-orm = { path = \"../../\", features = [\n    \"sqlx-mysql\",\n    \"runtime-async-std-native-tls\",\n] }\n"
  },
  {
    "path": "issues/324/src/main.rs",
    "content": "mod model;\n\npub fn main() {}\n"
  },
  {
    "path": "issues/324/src/model.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"model\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: AccountId,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[derive(Clone, Debug, PartialEq)]\npub struct AccountId(Uuid);\n\nimpl From<AccountId> for Uuid {\n    fn from(account_id: AccountId) -> Self {\n        account_id.0\n    }\n}\n\nmacro_rules! impl_try_from_u64_err {\n    ($newtype: ident) => {\n        impl sea_orm::TryFromU64 for $newtype {\n            fn try_from_u64(_n: u64) -> Result<Self, sea_orm::DbErr> {\n                Err(sea_orm::DbErr::ConvertFromU64(stringify!($newtype)))\n            }\n        }\n    };\n}\n\nmacro_rules! into_sea_query_value {\n    ($newtype: ident: Box($name: ident)) => {\n        impl From<$newtype> for sea_orm::Value {\n            fn from(source: $newtype) -> Self {\n                sea_orm::Value::$name(Some(Box::new(source.into())))\n            }\n        }\n\n        impl sea_orm::TryGetable for $newtype {\n            fn try_get(\n                res: &sea_orm::QueryResult,\n                pre: &str,\n                col: &str,\n            ) -> Result<Self, sea_orm::TryGetError> {\n                let val: $name = res.try_get(pre, col).map_err(sea_orm::TryGetError::DbErr)?;\n                Ok($newtype(val))\n            }\n        }\n\n        impl sea_orm::sea_query::Nullable for $newtype {\n            fn null() -> sea_orm::Value {\n                sea_orm::Value::$name(None)\n            }\n        }\n\n        impl sea_orm::sea_query::ValueType for $newtype {\n            fn try_from(v: sea_orm::Value) -> Result<Self, sea_orm::sea_query::ValueTypeErr> {\n                match v {\n                    sea_orm::Value::$name(Some(x)) => Ok($newtype(*x)),\n                    _ => Err(sea_orm::sea_query::ValueTypeErr),\n                }\n            }\n\n            fn type_name() -> String {\n                stringify!($newtype).to_owned()\n            }\n\n            fn array_type() -> sea_orm::sea_query::ArrayType {\n                sea_orm::sea_query::ArrayType::$name\n            }\n\n            fn column_type() -> sea_orm::sea_query::ColumnType {\n                sea_orm::sea_query::ColumnType::$name\n            }\n        }\n    };\n}\n\ninto_sea_query_value!(AccountId: Box(Uuid));\nimpl_try_from_u64_err!(AccountId);\n"
  },
  {
    "path": "issues/352/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-352\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nsea-orm = { path = \"../../\", features = [\n    \"sqlx-mysql\",\n    \"runtime-async-std-native-tls\",\n] }\n"
  },
  {
    "path": "issues/352/src/binary_primary_key.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"model\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_1: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_2: String,\n    pub owner: String,\n    pub name: String,\n    pub description: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/352/src/main.rs",
    "content": "mod unary_primary_key;\nmod binary_primary_key;\nmod ternary_primary_key;\nmod quaternary_primary_key;\nmod quinary_primary_key;\nmod senary_primary_key;\n\npub fn main() {}\n"
  },
  {
    "path": "issues/352/src/quaternary_primary_key.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"model\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_1: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_2: String,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_3: f64,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_4: Uuid,\n    pub owner: String,\n    pub name: String,\n    pub description: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/352/src/quinary_primary_key.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"model\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_1: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_2: String,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_3: f64,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_4: Uuid,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_5: DateTime,\n    pub owner: String,\n    pub name: String,\n    pub description: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/352/src/senary_primary_key.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"model\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_1: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_2: String,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_3: f64,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_4: Uuid,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_5: DateTime,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_6: DateTimeWithTimeZone,\n    pub owner: String,\n    pub name: String,\n    pub description: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/352/src/ternary_primary_key.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"model\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_1: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_2: String,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_3: f64,\n    pub owner: String,\n    pub name: String,\n    pub description: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/352/src/unary_primary_key.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"model\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id_1: i32,\n    pub owner: String,\n    pub name: String,\n    pub description: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/356/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-356\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nsea-orm = { path = \"../../\", features = [\n    \"sqlx-mysql\",\n    \"runtime-async-std-native-tls\",\n] }\n"
  },
  {
    "path": "issues/356/src/main.rs",
    "content": "mod model;\n\npub fn main() {}\n"
  },
  {
    "path": "issues/356/src/model.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"model\", table_iden)]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub owner: String,\n    pub name: String,\n    pub description: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use sea_orm::*;\n\n    #[test]\n    fn test_columns_1() {\n        assert_eq!(\n            Column::iter()\n                .map(|col| col.to_string())\n                .collect::<Vec<_>>(),\n            vec![\n                \"id\".to_owned(),\n                \"owner\".to_owned(),\n                \"name\".to_owned(),\n                \"description\".to_owned(),\n            ]\n        );\n        assert_eq!(Column::Table.to_string().as_str(), \"model\");\n        assert_eq!(Column::Id.to_string().as_str(), \"id\");\n        assert_eq!(Column::Owner.to_string().as_str(), \"owner\");\n        assert_eq!(Column::Name.to_string().as_str(), \"name\");\n        assert_eq!(Column::Description.to_string().as_str(), \"description\");\n    }\n}\n"
  },
  {
    "path": "issues/400/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-400\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nsea-orm = { path = \"../../\", features = [\n    \"sqlx-mysql\",\n    \"runtime-async-std-native-tls\",\n] }\n"
  },
  {
    "path": "issues/400/src/main.rs",
    "content": "mod model;\n\npub fn main() {}\n"
  },
  {
    "path": "issues/400/src/model.rs",
    "content": "use sea_orm::entity::prelude::*;\nuse std::marker::PhantomData;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"model\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: AccountId<String>,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[derive(Clone, Debug, PartialEq)]\npub struct AccountId<T>(Uuid, PhantomData<T>);\n\nimpl<T> AccountId<T> {\n    pub fn new(id: Uuid) -> Self {\n        AccountId(id, PhantomData)\n    }\n}\n\nimpl<T> From<AccountId<T>> for Uuid {\n    fn from(account_id: AccountId<T>) -> Self {\n        account_id.0\n    }\n}\n\nimpl<T> sea_orm::TryFromU64 for AccountId<T> {\n    fn try_from_u64(_n: u64) -> Result<Self, sea_orm::DbErr> {\n        Err(sea_orm::DbErr::ConvertFromU64(stringify!(AccountId<T>)))\n    }\n}\n\nimpl<T> From<AccountId<T>> for sea_orm::Value {\n    fn from(source: AccountId<T>) -> Self {\n        sea_orm::Value::Uuid(Some(Box::new(source.into())))\n    }\n}\n\nimpl<T> sea_orm::TryGetable for AccountId<T> {\n    fn try_get(\n        res: &sea_orm::QueryResult,\n        pre: &str,\n        col: &str,\n    ) -> Result<Self, sea_orm::TryGetError> {\n        let val: Uuid = res.try_get(pre, col).map_err(sea_orm::TryGetError::DbErr)?;\n        Ok(AccountId::<T>::new(val))\n    }\n}\n\nimpl<T> sea_orm::sea_query::Nullable for AccountId<T> {\n    fn null() -> sea_orm::Value {\n        sea_orm::Value::Uuid(None)\n    }\n}\n\nimpl<T> sea_orm::sea_query::ValueType for AccountId<T> {\n    fn try_from(v: sea_orm::Value) -> Result<Self, sea_orm::sea_query::ValueTypeErr> {\n        match v {\n            sea_orm::Value::Uuid(Some(x)) => Ok(AccountId::<T>::new(*x)),\n            _ => Err(sea_orm::sea_query::ValueTypeErr),\n        }\n    }\n\n    fn type_name() -> String {\n        stringify!(AccountId).to_owned()\n    }\n\n    fn array_type() -> sea_orm::sea_query::ArrayType {\n        sea_orm::sea_query::ArrayType::Uuid\n    }\n\n    fn column_type() -> sea_orm::sea_query::ColumnType {\n        sea_orm::sea_query::ColumnType::Uuid\n    }\n}\n"
  },
  {
    "path": "issues/471/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nauthors      = [\"Sebastian Pütz <seb.puetz@gmail.com>\"]\nedition      = \"2024\"\nname         = \"sea-orm-issues-400-471\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nanyhow             = \"1\"\ndotenvy            = \"0.15\"\nfutures-util       = \"0.3\"\nserde              = \"1\"\ntokio              = { version = \"1.14\", features = [\"full\"] }\ntracing-subscriber = { version = \"0.3.17\", features = [\"env-filter\"] }\n\n[dependencies.sea-orm]\ndefault-features = false\nfeatures = [\n    \"macros\",\n    \"mock\",\n    \"sqlx-all\",\n    \"runtime-tokio-rustls\",\n    \"debug-print\",\n]\npath = \"../../\" # remove this line in your own project\n"
  },
  {
    "path": "issues/471/README.md",
    "content": "Demonstrator for using streaming queries with `tokio::spawn` or in contexts that require `Send` futures."
  },
  {
    "path": "issues/471/src/main.rs",
    "content": "mod post;\nmod setup;\n\nuse futures_util::StreamExt;\nuse post::Entity as Post;\nuse sea_orm::{prelude::*, Database};\nuse std::env;\n\n#[tokio::main]\nasync fn main() -> anyhow::Result<()> {\n    unsafe {\n        env::set_var(\"RUST_LOG\", \"debug\");\n    }\n    tracing_subscriber::fmt::init();\n\n    dotenvy::dotenv().ok();\n    let db_url = env::var(\"DATABASE_URL\").expect(\"DATABASE_URL is not set in .env file\");\n    let db = Database::connect(db_url)\n        .await\n        .expect(\"Database connection failed\");\n    let _ = setup::create_post_table(&db);\n    tokio::task::spawn(async move {\n        let mut stream = Post::find().stream(&db).await.unwrap();\n        while let Some(item) = stream.next().await {\n            let item = item?;\n            println!(\"got something: {}\", item.text);\n        }\n        Ok::<(), anyhow::Error>(())\n    })\n    .await?\n}\n"
  },
  {
    "path": "issues/471/src/post.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.3.2\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"posts\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    pub title: String,\n    #[sea_orm(column_type = \"Text\")]\n    pub text: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/471/src/setup.rs",
    "content": "use sea_orm::sea_query::{ColumnDef, TableCreateStatement};\nuse sea_orm::{error::*, sea_query, ConnectionTrait, DbConn, ExecResult};\n\nasync fn create_table(db: &DbConn, stmt: &TableCreateStatement) -> Result<ExecResult, DbErr> {\n    let builder = db.get_database_backend();\n    db.execute(builder.build(stmt)).await\n}\n\npub async fn create_post_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(super::post::Entity)\n        .if_not_exists()\n        .col(\n            ColumnDef::new(super::post::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(super::post::Column::Title)\n                .string()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(super::post::Column::Text)\n                .string()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &stmt).await\n}\n"
  },
  {
    "path": "issues/630/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nauthors      = [\"Erik Rhodes <erik@space-nav.com>\"]\nedition      = \"2024\"\nname         = \"sea-orm-issues-630\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nserde = \"1\"\ntokio = { version = \"1\", features = [\"rt\", \"rt-multi-thread\", \"macros\"] }\n\n[dependencies.sea-orm]\ndefault-features = false\nfeatures = [\n    \"macros\",\n    \"runtime-tokio-native-tls\",\n    \"debug-print\",\n    \"with-json\",\n    \"with-chrono\",\n]\npath = \"../../\"\n\n[features]\ndefault    = [\"sqlx-mysql\"]\nsqlx-mysql = [\"sea-orm/sqlx-mysql\"]\n"
  },
  {
    "path": "issues/630/README.md",
    "content": "# sea_orm_underscore_fields\nA minimal repository showing an issue with SeaORM.\n\nConnects to the database with `env!()`, so make sure to set `DATABASE_URL` when compiling.\n\nThe file `src/entity/underscores_workaround.rs` shows the workaround to get the names to query correctly, and what happens if it's not included.\n"
  },
  {
    "path": "issues/630/create_underscores_table.sql",
    "content": "CREATE TABLE underscores (\n    `id` INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,\n    `a_b_c_d` INT NOT NULL,\n    `a_b_c_dd` INT NOT NULL,\n    `a_b_cc_d` INT NOT NULL,\n    `a_bb_c_d` INT NOT NULL,\n    `aa_b_c_d` INT NOT NULL\n);\n\nINSERT INTO underscores (\n    `a_b_c_d`,\n    `a_b_c_dd`,\n    `a_b_cc_d`,\n    `a_bb_c_d`,\n    `aa_b_c_d`\n)\nVALUES (1, 2, 3, 4, 5);\n"
  },
  {
    "path": "issues/630/src/entity/mod.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.6.0\n\npub mod prelude;\n\npub mod underscores;\npub mod underscores_workaround;\n"
  },
  {
    "path": "issues/630/src/entity/prelude.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.6.0\n\npub use super::underscores::Entity as Underscores;\n"
  },
  {
    "path": "issues/630/src/entity/underscores.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.6.0\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"underscores\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: u32,\n    pub a_b_c_d: i32,\n    pub a_b_c_dd: i32,\n    pub a_b_cc_d: i32,\n    pub a_bb_c_d: i32,\n    pub aa_b_c_d: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use sea_orm::Iterable;\n\n    #[test]\n    fn column_names() {\n        assert_eq!(\n            Column::iter().map(|c| c.to_string()).collect::<Vec<_>>(),\n            vec![\"id\", \"a_b_c_d\", \"a_b_c_dd\", \"a_b_cc_d\", \"a_bb_c_d\", \"aa_b_c_d\"]\n        )\n    }\n}\n"
  },
  {
    "path": "issues/630/src/entity/underscores_workaround.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.6.0\n\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"underscores\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: u32,\n    #[sea_orm(column_name = \"a_b_c_d\")]\n    pub a_b_c_d: i32,\n    #[sea_orm(column_name = \"a_b_c_dd\")]\n    pub a_b_c_dd: i32,\n    #[sea_orm(column_name = \"a_b_cc_d\")]\n    pub a_b_cc_d: i32,\n    #[sea_orm(column_name = \"a_bb_c_d\")]\n    pub a_bb_c_d: i32,\n    #[sea_orm(column_name = \"aa_b_c_d\")]\n    pub aa_b_c_d: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use sea_orm::Iterable;\n\n    #[test]\n    fn column_names() {\n        assert_eq!(\n            Column::iter().map(|c| c.to_string()).collect::<Vec<_>>(),\n            vec![\"id\", \"a_b_c_d\", \"a_b_c_dd\", \"a_b_cc_d\", \"a_bb_c_d\", \"aa_b_c_d\"]\n        )\n    }\n}\n"
  },
  {
    "path": "issues/630/src/main.rs",
    "content": "use std::collections::HashMap;\n\n// use sea_orm::sea_query::tests_cfg::json;\nuse sea_orm::{ConnectOptions, Database, EntityTrait};\n\nmod entity;\nuse entity::{underscores, underscores_workaround};\n\n#[tokio::main]\nasync fn main() {\n    let url = option_env!(\"DATABASE_URL\");\n    if let Some(url) = url {\n        let opts = ConnectOptions::new(url.to_string());\n        let conn = Database::connect(opts).await.unwrap();\n\n        let results = underscores::Entity::find().all(&conn).await;\n        dbg!(results);\n\n        let results_workaround = underscores_workaround::Entity::find().all(&conn).await;\n        dbg!(results_workaround);\n    }\n\n    let control = HashMap::from([\n        (\"a_b_c_d\", 1i32),\n        (\"a_b_c_dd\", 2i32),\n        (\"a_b_cc_d\", 3i32),\n        (\"a_bb_c_d\", 4i32),\n        (\"aa_b_c_d\", 5i32),\n    ]);\n    // let control = json!(control);\n    dbg!(control);\n}\n"
  },
  {
    "path": "issues/693/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nauthors      = [\"bleuse <raphael.bleuse@univ-grenoble-alpes.fr>\"]\nedition      = \"2024\"\nname         = \"sea-orm-issues-693\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nanyhow             = \"1\"\ndotenvy            = \"0.15\"\nfutures-util       = \"0.3\"\nserde              = \"1\"\ntokio              = { version = \"1.14\", features = [\"full\"] }\ntracing-subscriber = { version = \"0.3.17\", features = [\"env-filter\"] }\n\n[dependencies.sea-orm]\ndefault-features = false\nfeatures         = [\"runtime-tokio-rustls\", \"sqlx-mysql\", \"macros\"]\npath             = \"../../\"                                         # remove this line in your own project\n"
  },
  {
    "path": "issues/693/src/container.rs",
    "content": "pub mod prelude {\n    pub use super::model::{\n        ActiveModel as ContainerActiveModel, Column as ContainerColumn, Entity as Container,\n        Model as ContainerModel, PrimaryKey as ContainerPrimaryKey, Relation as ContainerRelation,\n    };\n}\n\npub mod model {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"container\")]\n    pub struct Model {\n        #[sea_orm(primary_key, column_name = \"db_id\")]\n        pub rust_id: i32,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {\n        #[sea_orm(has_many = \"crate::Content\")]\n        Content, // 1(Container) ⇆ n(Content)\n    }\n\n    impl Related<crate::Content> for Entity {\n        fn to() -> RelationDef {\n            Relation::Content.def()\n        }\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n"
  },
  {
    "path": "issues/693/src/content.rs",
    "content": "pub mod prelude {\n    pub use super::model::{\n        ActiveModel as ContentActiveModel, Column as ContentColumn, Entity as Content,\n        Model as ContentModel, PrimaryKey as ContentPrimaryKey, Relation as ContentRelation,\n    };\n}\n\npub mod model {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"content\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub container_id: i32,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {\n        #[sea_orm(\n            belongs_to = \"crate::Container\",\n            from = \"crate::ContentColumn::ContainerId\",\n            to = \"crate::ContainerColumn::RustId\"\n        )]\n        Container, // 1(Container) ⇆ n(Content)\n    }\n\n    impl Related<crate::Container> for Entity {\n        fn to() -> RelationDef {\n            Relation::Container.def()\n        }\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n"
  },
  {
    "path": "issues/693/src/main.rs",
    "content": "mod container;\nmod content;\n\nuse container::prelude::*;\nuse content::prelude::*;\nuse sea_orm::{DbBackend, EntityTrait, QueryTrait};\n\nfn main() {\n    assert_eq!(\n        Container::find().find_with_related(Content).build(DbBackend::MySql).to_string(),\n        [\n            \"SELECT `container`.`db_id` AS `A_db_id`, `content`.`id` AS `B_id`, `content`.`container_id` AS `B_container_id`\",\n            \"FROM `container`\",\n            \"LEFT JOIN `content` ON `container`.`db_id` = `content`.`container_id`\",\n            \"ORDER BY `container`.`db_id` ASC\",\n        ].join(\" \")\n    );\n}\n"
  },
  {
    "path": "issues/86/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-issues-86\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nsea-orm = { path = \"../../\", features = [\n    \"sqlx-all\",\n    \"runtime-tokio-native-tls\",\n    \"debug-print\",\n] }\ntokio = { version = \"1\", features = [\"full\"] }\ntracing = { version = \"0.1\" }\ntracing-subscriber = { version = \"0.3.17\", features = [\"env-filter\"] }\n"
  },
  {
    "path": "issues/86/src/cake.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "issues/86/src/main.rs",
    "content": "mod cake;\nuse sea_orm::*;\n\n#[tokio::main]\npub async fn main() {\n    tracing_subscriber::fmt()\n        .with_max_level(tracing::Level::DEBUG)\n        .with_test_writer()\n        .init();\n\n    let db = Database::connect(\"mysql://sea:sea@localhost/bakery\")\n        .await\n        .unwrap();\n\n    tokio::spawn(async move {\n        cake::Entity::find().one(&db).await.unwrap();\n    })\n    .await.unwrap();\n}"
  },
  {
    "path": "issues/892/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nauthors      = []\nedition      = \"2024\"\nname         = \"sea-orm-issues-892\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\ntokio = { version = \"1.20.0\", features = [\"rt-multi-thread\", \"macros\"] }\n\n[dependencies.sea-orm]\ndefault-features = false\nfeatures         = [\"runtime-tokio-rustls\", \"tests-cfg\", \"sqlx-sqlite\", \"macros\"]\npath             = \"../../\"                                                       # remove this line in your own project\n"
  },
  {
    "path": "issues/892/src/main.rs",
    "content": "use sea_orm::tests_cfg::{cake, cake_filling};\nuse sea_orm::{Database, DbErr, EntityTrait, JoinType, QuerySelect, RelationTrait};\n\n#[tokio::main]\nasync fn main() -> Result<(), DbErr> {\n    let db = Database::connect(\"sqlite::memory:\").await?;\n\n    tokio::spawn(async move {\n        let _cakes = cake::Entity::find()\n            .join_rev(JoinType::InnerJoin, cake_filling::Relation::Cake.def())\n            .all(&db)\n            .await\n            .unwrap();\n    })\n    .await\n    .unwrap();\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-arrow/Cargo.toml",
    "content": "[package]\nauthors       = [\"Chris Tsang <chris.2y3@outlook.com>\"]\ncategories    = [\"database\"]\ndescription   = \"Arrow integration for SeaORM\"\ndocumentation = \"https://docs.rs/sea-orm-arrow\"\nedition       = \"2024\"\nhomepage      = \"https://www.sea-ql.org/SeaORM\"\nkeywords      = [\"orm\", \"arrow\", \"parquet\", \"sea-orm\"]\nlicense       = \"MIT OR Apache-2.0\"\nname          = \"sea-orm-arrow\"\nrepository    = \"https://github.com/SeaQL/sea-orm\"\nrust-version  = \"1.85.0\"\nversion       = \"2.0.0-rc.4\"\n\n[dependencies]\narrow = { version = \"58\", default-features = false }\nsea-query = { version = \"1.0.0-rc\", default-features = false, features = [\n    \"thread-safe\",\n] }\nthiserror = { version = \"2\", default-features = false }\n\n[features]\nprettyprint       = [\"arrow/prettyprint\"]\nwith-bigdecimal   = [\"sea-query/with-bigdecimal\"]\nwith-chrono       = [\"sea-query/with-chrono\"]\nwith-rust_decimal = [\"sea-query/with-rust_decimal\"]\nwith-time         = [\"sea-query/with-time\"]\n"
  },
  {
    "path": "sea-orm-arrow/src/lib.rs",
    "content": "pub use arrow;\n\nuse arrow::array::*;\nuse arrow::datatypes::i256;\nuse sea_query::{ColumnType, Value};\n\n// ---------------------------------------------------------------------------\n// Error type\n// ---------------------------------------------------------------------------\n\n/// Errors that can occur when converting between SeaORM [`Value`]s and Arrow arrays.\n#[derive(Debug, thiserror::Error)]\npub enum ArrowError {\n    /// The Arrow array type is incompatible with the target SeaORM column type.\n    #[error(\"expected {expected} for column type {col_type}, got Arrow type {actual}\")]\n    TypeMismatch {\n        expected: &'static str,\n        col_type: &'static str,\n        actual: String,\n    },\n\n    /// A value lies outside the representable range for the target type.\n    #[error(\"{0}\")]\n    OutOfRange(String),\n\n    /// The column type or Arrow data type is not supported for conversion.\n    #[error(\"{0}\")]\n    Unsupported(String),\n}\n\nfn type_err(expected: &'static str, col_type: &'static str, array: &dyn Array) -> ArrowError {\n    ArrowError::TypeMismatch {\n        expected,\n        col_type,\n        actual: format!(\"{:?}\", array.data_type()),\n    }\n}\n\n// ---------------------------------------------------------------------------\n// Arrow -> Value\n// ---------------------------------------------------------------------------\n\n/// Extract a [`Value`] from an Arrow array at the given row index,\n/// based on the expected [`ColumnType`] from the entity definition.\n///\n/// For date/time column types, this produces chrono `Value` variants when\n/// the `with-chrono` feature is enabled, or time-crate variants when only\n/// `with-time` is enabled.\npub fn arrow_array_to_value(\n    array: &dyn Array,\n    col_type: &ColumnType,\n    row: usize,\n) -> Result<Value, ArrowError> {\n    if array.is_null(row) {\n        return Ok(null_value_for_type(col_type));\n    }\n    match col_type {\n        ColumnType::TinyInteger => {\n            let arr = array\n                .as_any()\n                .downcast_ref::<Int8Array>()\n                .ok_or_else(|| type_err(\"Int8Array\", \"TinyInteger\", array))?;\n            Ok(Value::TinyInt(Some(arr.value(row))))\n        }\n        ColumnType::SmallInteger => {\n            let arr = array\n                .as_any()\n                .downcast_ref::<Int16Array>()\n                .ok_or_else(|| type_err(\"Int16Array\", \"SmallInteger\", array))?;\n            Ok(Value::SmallInt(Some(arr.value(row))))\n        }\n        ColumnType::Integer => {\n            let arr = array\n                .as_any()\n                .downcast_ref::<Int32Array>()\n                .ok_or_else(|| type_err(\"Int32Array\", \"Integer\", array))?;\n            Ok(Value::Int(Some(arr.value(row))))\n        }\n        ColumnType::BigInteger => {\n            let arr = array\n                .as_any()\n                .downcast_ref::<Int64Array>()\n                .ok_or_else(|| type_err(\"Int64Array\", \"BigInteger\", array))?;\n            Ok(Value::BigInt(Some(arr.value(row))))\n        }\n        ColumnType::TinyUnsigned => {\n            let arr = array\n                .as_any()\n                .downcast_ref::<UInt8Array>()\n                .ok_or_else(|| type_err(\"UInt8Array\", \"TinyUnsigned\", array))?;\n            Ok(Value::TinyUnsigned(Some(arr.value(row))))\n        }\n        ColumnType::SmallUnsigned => {\n            let arr = array\n                .as_any()\n                .downcast_ref::<UInt16Array>()\n                .ok_or_else(|| type_err(\"UInt16Array\", \"SmallUnsigned\", array))?;\n            Ok(Value::SmallUnsigned(Some(arr.value(row))))\n        }\n        ColumnType::Unsigned => {\n            let arr = array\n                .as_any()\n                .downcast_ref::<UInt32Array>()\n                .ok_or_else(|| type_err(\"UInt32Array\", \"Unsigned\", array))?;\n            Ok(Value::Unsigned(Some(arr.value(row))))\n        }\n        ColumnType::BigUnsigned => {\n            let arr = array\n                .as_any()\n                .downcast_ref::<UInt64Array>()\n                .ok_or_else(|| type_err(\"UInt64Array\", \"BigUnsigned\", array))?;\n            Ok(Value::BigUnsigned(Some(arr.value(row))))\n        }\n        ColumnType::Float => {\n            let arr = array\n                .as_any()\n                .downcast_ref::<Float32Array>()\n                .ok_or_else(|| type_err(\"Float32Array\", \"Float\", array))?;\n            Ok(Value::Float(Some(arr.value(row))))\n        }\n        ColumnType::Double => {\n            let arr = array\n                .as_any()\n                .downcast_ref::<Float64Array>()\n                .ok_or_else(|| type_err(\"Float64Array\", \"Double\", array))?;\n            Ok(Value::Double(Some(arr.value(row))))\n        }\n        ColumnType::String(_) | ColumnType::Text | ColumnType::Char(_) => {\n            if let Some(arr) = array.as_any().downcast_ref::<StringArray>() {\n                Ok(Value::String(Some(arr.value(row).to_owned())))\n            } else if let Some(arr) = array.as_any().downcast_ref::<LargeStringArray>() {\n                Ok(Value::String(Some(arr.value(row).to_owned())))\n            } else {\n                Err(type_err(\n                    \"StringArray or LargeStringArray\",\n                    \"String/Text\",\n                    array,\n                ))\n            }\n        }\n        ColumnType::Boolean => {\n            let arr = array\n                .as_any()\n                .downcast_ref::<BooleanArray>()\n                .ok_or_else(|| type_err(\"BooleanArray\", \"Boolean\", array))?;\n            Ok(Value::Bool(Some(arr.value(row))))\n        }\n        // Binary types\n        ColumnType::Binary(_) | ColumnType::VarBinary(_) => arrow_to_bytes(array, row),\n        // Decimal types\n        ColumnType::Decimal(_) | ColumnType::Money(_) => arrow_to_decimal(array, row),\n        // Date/time types: delegate to feature-gated helpers.\n        // Prefer chrono when available; fall back to time crate.\n        #[cfg(feature = \"with-chrono\")]\n        ColumnType::Date => arrow_to_chrono_date(array, row),\n        #[cfg(feature = \"with-chrono\")]\n        ColumnType::Time => arrow_to_chrono_time(array, row),\n        #[cfg(feature = \"with-chrono\")]\n        ColumnType::DateTime | ColumnType::Timestamp => arrow_to_chrono_datetime(array, row),\n        #[cfg(feature = \"with-chrono\")]\n        ColumnType::TimestampWithTimeZone => arrow_to_chrono_datetime_utc(array, row),\n\n        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n        ColumnType::Date => arrow_to_time_date(array, row),\n        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n        ColumnType::Time => arrow_to_time_time(array, row),\n        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n        ColumnType::DateTime | ColumnType::Timestamp => arrow_to_time_datetime(array, row),\n        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n        ColumnType::TimestampWithTimeZone => arrow_to_time_datetime_tz(array, row),\n\n        _ => Err(ArrowError::Unsupported(format!(\n            \"Unsupported column type for Arrow conversion: {col_type:?}\"\n        ))),\n    }\n}\n\n/// When both `with-chrono` and `with-time` are enabled, this provides the\n/// time-crate alternative for date/time columns. Called as a fallback when\n/// the chrono Value variant doesn't match the model's field type.\n#[cfg(all(feature = \"with-chrono\", feature = \"with-time\"))]\npub fn arrow_array_to_value_alt(\n    array: &dyn Array,\n    col_type: &ColumnType,\n    row: usize,\n) -> Result<Option<Value>, ArrowError> {\n    if array.is_null(row) {\n        return Ok(Some(null_value_for_type_time(col_type)));\n    }\n    match col_type {\n        ColumnType::Date => arrow_to_time_date(array, row).map(Some),\n        ColumnType::Time => arrow_to_time_time(array, row).map(Some),\n        ColumnType::DateTime | ColumnType::Timestamp => {\n            arrow_to_time_datetime(array, row).map(Some)\n        }\n        ColumnType::TimestampWithTimeZone => arrow_to_time_datetime_tz(array, row).map(Some),\n        _ => Ok(None),\n    }\n}\n\n/// Returns true for ColumnTypes that may need a chrono->time fallback.\npub fn is_datetime_column(col_type: &ColumnType) -> bool {\n    matches!(\n        col_type,\n        ColumnType::Date\n            | ColumnType::Time\n            | ColumnType::DateTime\n            | ColumnType::Timestamp\n            | ColumnType::TimestampWithTimeZone\n    )\n}\n\n// ---------------------------------------------------------------------------\n// Binary helpers\n// ---------------------------------------------------------------------------\n\nfn arrow_to_bytes(array: &dyn Array, row: usize) -> Result<Value, ArrowError> {\n    if let Some(arr) = array.as_any().downcast_ref::<BinaryArray>() {\n        return Ok(Value::Bytes(Some(arr.value(row).to_vec())));\n    }\n    if let Some(arr) = array.as_any().downcast_ref::<LargeBinaryArray>() {\n        return Ok(Value::Bytes(Some(arr.value(row).to_vec())));\n    }\n    if let Some(arr) = array.as_any().downcast_ref::<FixedSizeBinaryArray>() {\n        return Ok(Value::Bytes(Some(arr.value(row).to_vec())));\n    }\n    Err(type_err(\n        \"BinaryArray, LargeBinaryArray, or FixedSizeBinaryArray\",\n        \"Binary/VarBinary\",\n        array,\n    ))\n}\n\n// ---------------------------------------------------------------------------\n// Decimal helpers\n// ---------------------------------------------------------------------------\n\n/// Convert Arrow Decimal128Array or Decimal256Array to a decimal Value.\n/// Prefers rust_decimal when available and precision fits, otherwise bigdecimal.\nfn arrow_to_decimal(array: &dyn Array, row: usize) -> Result<Value, ArrowError> {\n    if let Some(arr) = array.as_any().downcast_ref::<Decimal128Array>() {\n        let value = arr.value(row);\n        let precision = arr.precision();\n        let scale = arr.scale();\n        return decimal128_to_value(value, precision, scale);\n    }\n\n    if let Some(arr) = array.as_any().downcast_ref::<Decimal64Array>() {\n        let value = arr.value(row);\n        let precision = arr.precision();\n        let scale = arr.scale();\n        return decimal64_to_value(value, precision, scale);\n    }\n\n    if let Some(arr) = array.as_any().downcast_ref::<Decimal256Array>() {\n        let value = arr.value(row);\n        let precision = arr.precision();\n        let scale = arr.scale();\n        return decimal256_to_value(value, precision, scale);\n    }\n\n    Err(type_err(\n        \"Decimal64Array, Decimal128Array, or Decimal256Array\",\n        \"Decimal\",\n        array,\n    ))\n}\n\n#[cfg(feature = \"with-rust_decimal\")]\nfn decimal64_to_value(value: i64, _precision: u8, scale: i8) -> Result<Value, ArrowError> {\n    use sea_query::prelude::Decimal;\n\n    if scale < 0 {\n        #[cfg(feature = \"with-bigdecimal\")]\n        return decimal64_to_bigdecimal(value, scale);\n\n        #[cfg(not(feature = \"with-bigdecimal\"))]\n        return Err(ArrowError::Unsupported(format!(\n            \"Decimal64 with negative scale={scale} not supported by rust_decimal. \\\n             Enable 'with-bigdecimal' feature.\"\n        )));\n    }\n\n    let decimal = Decimal::from_i128_with_scale(value as i128, scale as u32);\n    Ok(Value::Decimal(Some(decimal)))\n}\n\n#[cfg(not(feature = \"with-rust_decimal\"))]\nfn decimal64_to_value(_value: i64, _precision: u8, _scale: i8) -> Result<Value, ArrowError> {\n    #[cfg(feature = \"with-bigdecimal\")]\n    return decimal64_to_bigdecimal(_value, _scale);\n\n    #[cfg(not(feature = \"with-bigdecimal\"))]\n    Err(ArrowError::Unsupported(\n        \"Decimal64Array requires 'with-rust_decimal' or 'with-bigdecimal' feature\".into(),\n    ))\n}\n\n#[cfg(feature = \"with-bigdecimal\")]\nfn decimal64_to_bigdecimal(value: i64, scale: i8) -> Result<Value, ArrowError> {\n    use sea_query::prelude::bigdecimal::{BigDecimal, num_bigint::BigInt};\n\n    let bigint = BigInt::from(value);\n    let decimal = BigDecimal::new(bigint, scale as i64);\n    Ok(Value::BigDecimal(Some(Box::new(decimal))))\n}\n\n#[cfg(feature = \"with-rust_decimal\")]\nfn decimal128_to_value(value: i128, precision: u8, scale: i8) -> Result<Value, ArrowError> {\n    use sea_query::prelude::Decimal;\n\n    if precision > 28 || scale > 28 || scale < 0 {\n        #[cfg(feature = \"with-bigdecimal\")]\n        return decimal128_to_bigdecimal(value, scale);\n\n        #[cfg(not(feature = \"with-bigdecimal\"))]\n        return Err(ArrowError::Unsupported(format!(\n            \"Decimal128 with precision={precision}, scale={scale} exceeds rust_decimal limits \\\n             (max precision=28, scale=0-28). Enable 'with-bigdecimal' feature for arbitrary precision.\"\n        )));\n    }\n\n    let decimal = Decimal::from_i128_with_scale(value, scale as u32);\n    Ok(Value::Decimal(Some(decimal)))\n}\n\n#[cfg(not(feature = \"with-rust_decimal\"))]\nfn decimal128_to_value(_value: i128, _precision: u8, _scale: i8) -> Result<Value, ArrowError> {\n    #[cfg(feature = \"with-bigdecimal\")]\n    return decimal128_to_bigdecimal(_value, _scale);\n\n    #[cfg(not(feature = \"with-bigdecimal\"))]\n    Err(ArrowError::Unsupported(\n        \"Decimal128Array requires 'with-rust_decimal' or 'with-bigdecimal' feature\".into(),\n    ))\n}\n\n#[cfg(feature = \"with-bigdecimal\")]\nfn decimal128_to_bigdecimal(value: i128, scale: i8) -> Result<Value, ArrowError> {\n    use sea_query::prelude::bigdecimal::{BigDecimal, num_bigint::BigInt};\n\n    let bigint = BigInt::from(value);\n    let decimal = BigDecimal::new(bigint, scale as i64);\n    Ok(Value::BigDecimal(Some(Box::new(decimal))))\n}\n\nfn decimal256_to_value(_value: i256, _precision: u8, _scale: i8) -> Result<Value, ArrowError> {\n    #[cfg(feature = \"with-bigdecimal\")]\n    {\n        use sea_query::prelude::bigdecimal::{\n            BigDecimal,\n            num_bigint::{BigInt, Sign},\n        };\n\n        let bytes = _value.to_be_bytes();\n\n        let (sign, magnitude) = if _value.is_negative() {\n            let mut abs_bytes = [0u8; 32];\n            let mut carry = true;\n\n            for i in (0..32).rev() {\n                abs_bytes[i] = !bytes[i];\n                if carry {\n                    if abs_bytes[i] == 255 {\n                        abs_bytes[i] = 0;\n                    } else {\n                        abs_bytes[i] += 1;\n                        carry = false;\n                    }\n                }\n            }\n\n            (Sign::Minus, abs_bytes.to_vec())\n        } else if _value == i256::ZERO {\n            (Sign::NoSign, vec![0])\n        } else {\n            let first_nonzero = bytes.iter().position(|&b| b != 0).unwrap_or(31);\n            (Sign::Plus, bytes[first_nonzero..].to_vec())\n        };\n\n        let bigint = BigInt::from_bytes_be(sign, &magnitude);\n        let decimal = BigDecimal::new(bigint, _scale as i64);\n        return Ok(Value::BigDecimal(Some(Box::new(decimal))));\n    }\n\n    #[cfg(not(feature = \"with-bigdecimal\"))]\n    Err(ArrowError::Unsupported(\n        \"Decimal256Array requires 'with-bigdecimal' feature for arbitrary precision support\".into(),\n    ))\n}\n\n// ---------------------------------------------------------------------------\n// Chrono date/time helpers\n// ---------------------------------------------------------------------------\n\n#[cfg(feature = \"with-chrono\")]\nfn arrow_to_chrono_date(array: &dyn Array, row: usize) -> Result<Value, ArrowError> {\n    use sea_query::prelude::chrono::NaiveDate;\n    let epoch = NaiveDate::from_ymd_opt(1970, 1, 1).expect(\"valid date\");\n\n    if let Some(arr) = array.as_any().downcast_ref::<Date32Array>() {\n        let days = arr.value(row);\n        let date = epoch\n            .checked_add_signed(sea_query::prelude::chrono::Duration::days(days as i64))\n            .ok_or_else(|| ArrowError::OutOfRange(format!(\"Date32 value {days} out of range\")))?;\n        Ok(Value::ChronoDate(Some(date)))\n    } else if let Some(arr) = array.as_any().downcast_ref::<Date64Array>() {\n        let ms = arr.value(row);\n        let date = epoch\n            .checked_add_signed(sea_query::prelude::chrono::Duration::milliseconds(ms))\n            .ok_or_else(|| ArrowError::OutOfRange(format!(\"Date64 value {ms} out of range\")))?;\n        Ok(Value::ChronoDate(Some(date)))\n    } else {\n        Err(type_err(\"Date32Array or Date64Array\", \"Date\", array))\n    }\n}\n\n#[cfg(feature = \"with-chrono\")]\nfn arrow_to_chrono_time(array: &dyn Array, row: usize) -> Result<Value, ArrowError> {\n    use sea_query::prelude::chrono::NaiveTime;\n\n    if let Some(arr) = array.as_any().downcast_ref::<Time32SecondArray>() {\n        let secs = arr.value(row) as u32;\n        let t = NaiveTime::from_num_seconds_from_midnight_opt(secs, 0).ok_or_else(|| {\n            ArrowError::OutOfRange(format!(\"Time32Second value {secs} out of range\"))\n        })?;\n        Ok(Value::ChronoTime(Some(t)))\n    } else if let Some(arr) = array.as_any().downcast_ref::<Time32MillisecondArray>() {\n        let ms = arr.value(row);\n        let secs = (ms / 1_000) as u32;\n        let nanos = ((ms % 1_000) * 1_000_000) as u32;\n        let t = NaiveTime::from_num_seconds_from_midnight_opt(secs, nanos).ok_or_else(|| {\n            ArrowError::OutOfRange(format!(\"Time32Millisecond value {ms} out of range\"))\n        })?;\n        Ok(Value::ChronoTime(Some(t)))\n    } else if let Some(arr) = array.as_any().downcast_ref::<Time64MicrosecondArray>() {\n        let us = arr.value(row);\n        let secs = (us / 1_000_000) as u32;\n        let nanos = ((us % 1_000_000) * 1_000) as u32;\n        let t = NaiveTime::from_num_seconds_from_midnight_opt(secs, nanos).ok_or_else(|| {\n            ArrowError::OutOfRange(format!(\"Time64Microsecond value {us} out of range\"))\n        })?;\n        Ok(Value::ChronoTime(Some(t)))\n    } else if let Some(arr) = array.as_any().downcast_ref::<Time64NanosecondArray>() {\n        let ns = arr.value(row);\n        let secs = (ns / 1_000_000_000) as u32;\n        let nanos = (ns % 1_000_000_000) as u32;\n        let t = NaiveTime::from_num_seconds_from_midnight_opt(secs, nanos).ok_or_else(|| {\n            ArrowError::OutOfRange(format!(\"Time64Nanosecond value {ns} out of range\"))\n        })?;\n        Ok(Value::ChronoTime(Some(t)))\n    } else {\n        Err(type_err(\"Time32/Time64 Array\", \"Time\", array))\n    }\n}\n\n#[cfg(feature = \"with-chrono\")]\nfn arrow_timestamp_to_utc(\n    array: &dyn Array,\n    row: usize,\n) -> Result<sea_query::prelude::chrono::DateTime<sea_query::prelude::chrono::Utc>, ArrowError> {\n    use sea_query::prelude::chrono::{DateTime, Utc};\n\n    if let Some(arr) = array.as_any().downcast_ref::<TimestampSecondArray>() {\n        DateTime::<Utc>::from_timestamp(arr.value(row), 0)\n            .ok_or_else(|| ArrowError::OutOfRange(\"Timestamp seconds out of range\".into()))\n    } else if let Some(arr) = array.as_any().downcast_ref::<TimestampMillisecondArray>() {\n        DateTime::<Utc>::from_timestamp_millis(arr.value(row))\n            .ok_or_else(|| ArrowError::OutOfRange(\"Timestamp milliseconds out of range\".into()))\n    } else if let Some(arr) = array.as_any().downcast_ref::<TimestampMicrosecondArray>() {\n        DateTime::<Utc>::from_timestamp_micros(arr.value(row))\n            .ok_or_else(|| ArrowError::OutOfRange(\"Timestamp microseconds out of range\".into()))\n    } else if let Some(arr) = array.as_any().downcast_ref::<TimestampNanosecondArray>() {\n        let nanos = arr.value(row);\n        let secs = nanos.div_euclid(1_000_000_000);\n        let nsec = nanos.rem_euclid(1_000_000_000) as u32;\n        DateTime::<Utc>::from_timestamp(secs, nsec)\n            .ok_or_else(|| ArrowError::OutOfRange(\"Timestamp nanoseconds out of range\".into()))\n    } else {\n        Err(type_err(\n            \"TimestampSecond/Millisecond/Microsecond/NanosecondArray\",\n            \"DateTime/Timestamp\",\n            array,\n        ))\n    }\n}\n\n#[cfg(feature = \"with-chrono\")]\nfn arrow_to_chrono_datetime(array: &dyn Array, row: usize) -> Result<Value, ArrowError> {\n    let dt = arrow_timestamp_to_utc(array, row)?;\n    Ok(Value::ChronoDateTime(Some(dt.naive_utc())))\n}\n\n#[cfg(feature = \"with-chrono\")]\nfn arrow_to_chrono_datetime_utc(array: &dyn Array, row: usize) -> Result<Value, ArrowError> {\n    let dt = arrow_timestamp_to_utc(array, row)?;\n    Ok(Value::ChronoDateTimeUtc(Some(dt)))\n}\n\n// ---------------------------------------------------------------------------\n// Time-crate date/time helpers\n// ---------------------------------------------------------------------------\n\n#[cfg(feature = \"with-time\")]\nfn arrow_to_time_date(array: &dyn Array, row: usize) -> Result<Value, ArrowError> {\n    const EPOCH_JULIAN: i32 = 2_440_588;\n\n    if let Some(arr) = array.as_any().downcast_ref::<Date32Array>() {\n        let days = arr.value(row);\n        let date =\n            sea_query::prelude::time::Date::from_julian_day(EPOCH_JULIAN + days).map_err(|e| {\n                ArrowError::OutOfRange(format!(\"Date32 value {days} out of range: {e}\"))\n            })?;\n        Ok(Value::TimeDate(Some(date)))\n    } else if let Some(arr) = array.as_any().downcast_ref::<Date64Array>() {\n        let ms = arr.value(row);\n        let days = (ms / 86_400_000) as i32;\n        let date = sea_query::prelude::time::Date::from_julian_day(EPOCH_JULIAN + days)\n            .map_err(|e| ArrowError::OutOfRange(format!(\"Date64 value {ms} out of range: {e}\")))?;\n        Ok(Value::TimeDate(Some(date)))\n    } else {\n        Err(type_err(\"Date32Array or Date64Array\", \"Date\", array))\n    }\n}\n\n#[cfg(feature = \"with-time\")]\nfn arrow_to_time_time(array: &dyn Array, row: usize) -> Result<Value, ArrowError> {\n    if let Some(arr) = array.as_any().downcast_ref::<Time32SecondArray>() {\n        let secs = arr.value(row);\n        let t = sea_query::prelude::time::Time::from_hms(\n            (secs / 3600) as u8,\n            ((secs % 3600) / 60) as u8,\n            (secs % 60) as u8,\n        )\n        .map_err(|e| {\n            ArrowError::OutOfRange(format!(\"Time32Second value {secs} out of range: {e}\"))\n        })?;\n        Ok(Value::TimeTime(Some(t)))\n    } else if let Some(arr) = array.as_any().downcast_ref::<Time32MillisecondArray>() {\n        let ms = arr.value(row);\n        let total_secs = ms / 1_000;\n        let nanos = ((ms % 1_000) * 1_000_000) as u32;\n        let t = sea_query::prelude::time::Time::from_hms_nano(\n            (total_secs / 3600) as u8,\n            ((total_secs % 3600) / 60) as u8,\n            (total_secs % 60) as u8,\n            nanos,\n        )\n        .map_err(|e| {\n            ArrowError::OutOfRange(format!(\"Time32Millisecond value {ms} out of range: {e}\"))\n        })?;\n        Ok(Value::TimeTime(Some(t)))\n    } else if let Some(arr) = array.as_any().downcast_ref::<Time64MicrosecondArray>() {\n        let us = arr.value(row);\n        let total_secs = us / 1_000_000;\n        let nanos = ((us % 1_000_000) * 1_000) as u32;\n        let t = sea_query::prelude::time::Time::from_hms_nano(\n            (total_secs / 3600) as u8,\n            ((total_secs % 3600) / 60) as u8,\n            (total_secs % 60) as u8,\n            nanos,\n        )\n        .map_err(|e| {\n            ArrowError::OutOfRange(format!(\"Time64Microsecond value {us} out of range: {e}\"))\n        })?;\n        Ok(Value::TimeTime(Some(t)))\n    } else if let Some(arr) = array.as_any().downcast_ref::<Time64NanosecondArray>() {\n        let ns = arr.value(row);\n        let total_secs = ns / 1_000_000_000;\n        let nanos = (ns % 1_000_000_000) as u32;\n        let t = sea_query::prelude::time::Time::from_hms_nano(\n            (total_secs / 3600) as u8,\n            ((total_secs % 3600) / 60) as u8,\n            (total_secs % 60) as u8,\n            nanos,\n        )\n        .map_err(|e| {\n            ArrowError::OutOfRange(format!(\"Time64Nanosecond value {ns} out of range: {e}\"))\n        })?;\n        Ok(Value::TimeTime(Some(t)))\n    } else {\n        Err(type_err(\"Time32/Time64 Array\", \"Time\", array))\n    }\n}\n\n#[cfg(feature = \"with-time\")]\nfn arrow_timestamp_to_offset_dt(\n    array: &dyn Array,\n    row: usize,\n) -> Result<sea_query::prelude::time::OffsetDateTime, ArrowError> {\n    if let Some(arr) = array.as_any().downcast_ref::<TimestampSecondArray>() {\n        sea_query::prelude::time::OffsetDateTime::from_unix_timestamp(arr.value(row))\n            .map_err(|e| ArrowError::OutOfRange(format!(\"Timestamp seconds out of range: {e}\")))\n    } else if let Some(arr) = array.as_any().downcast_ref::<TimestampMillisecondArray>() {\n        let ms = arr.value(row);\n        sea_query::prelude::time::OffsetDateTime::from_unix_timestamp_nanos(ms as i128 * 1_000_000)\n            .map_err(|e| {\n                ArrowError::OutOfRange(format!(\"Timestamp milliseconds out of range: {e}\"))\n            })\n    } else if let Some(arr) = array.as_any().downcast_ref::<TimestampMicrosecondArray>() {\n        let us = arr.value(row);\n        sea_query::prelude::time::OffsetDateTime::from_unix_timestamp_nanos(us as i128 * 1_000)\n            .map_err(|e| {\n                ArrowError::OutOfRange(format!(\"Timestamp microseconds out of range: {e}\"))\n            })\n    } else if let Some(arr) = array.as_any().downcast_ref::<TimestampNanosecondArray>() {\n        sea_query::prelude::time::OffsetDateTime::from_unix_timestamp_nanos(arr.value(row) as i128)\n            .map_err(|e| ArrowError::OutOfRange(format!(\"Timestamp nanoseconds out of range: {e}\")))\n    } else {\n        Err(type_err(\n            \"TimestampSecond/Millisecond/Microsecond/NanosecondArray\",\n            \"DateTime/Timestamp\",\n            array,\n        ))\n    }\n}\n\n#[cfg(feature = \"with-time\")]\nfn arrow_to_time_datetime(array: &dyn Array, row: usize) -> Result<Value, ArrowError> {\n    let odt = arrow_timestamp_to_offset_dt(array, row)?;\n    Ok(Value::TimeDateTime(Some(\n        sea_query::prelude::time::PrimitiveDateTime::new(odt.date(), odt.time()),\n    )))\n}\n\n#[cfg(feature = \"with-time\")]\nfn arrow_to_time_datetime_tz(array: &dyn Array, row: usize) -> Result<Value, ArrowError> {\n    let odt = arrow_timestamp_to_offset_dt(array, row)?;\n    Ok(Value::TimeDateTimeWithTimeZone(Some(odt)))\n}\n\n// ---------------------------------------------------------------------------\n// Null value helpers\n// ---------------------------------------------------------------------------\n\nfn null_value_for_type(col_type: &ColumnType) -> Value {\n    match col_type {\n        ColumnType::TinyInteger => Value::TinyInt(None),\n        ColumnType::SmallInteger => Value::SmallInt(None),\n        ColumnType::Integer => Value::Int(None),\n        ColumnType::BigInteger => Value::BigInt(None),\n        ColumnType::TinyUnsigned => Value::TinyUnsigned(None),\n        ColumnType::SmallUnsigned => Value::SmallUnsigned(None),\n        ColumnType::Unsigned => Value::Unsigned(None),\n        ColumnType::BigUnsigned => Value::BigUnsigned(None),\n        ColumnType::Float => Value::Float(None),\n        ColumnType::Double => Value::Double(None),\n        ColumnType::String(_) | ColumnType::Text | ColumnType::Char(_) => Value::String(None),\n        ColumnType::Binary(_) | ColumnType::VarBinary(_) => Value::Bytes(None),\n        ColumnType::Boolean => Value::Bool(None),\n        #[cfg(feature = \"with-rust_decimal\")]\n        ColumnType::Decimal(_) | ColumnType::Money(_) => Value::Decimal(None),\n        #[cfg(all(feature = \"with-bigdecimal\", not(feature = \"with-rust_decimal\")))]\n        ColumnType::Decimal(_) | ColumnType::Money(_) => Value::BigDecimal(None),\n        #[cfg(feature = \"with-chrono\")]\n        ColumnType::Date => Value::ChronoDate(None),\n        #[cfg(feature = \"with-chrono\")]\n        ColumnType::Time => Value::ChronoTime(None),\n        #[cfg(feature = \"with-chrono\")]\n        ColumnType::DateTime | ColumnType::Timestamp => Value::ChronoDateTime(None),\n        #[cfg(feature = \"with-chrono\")]\n        ColumnType::TimestampWithTimeZone => Value::ChronoDateTimeUtc(None),\n        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n        ColumnType::Date => Value::TimeDate(None),\n        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n        ColumnType::Time => Value::TimeTime(None),\n        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n        ColumnType::DateTime | ColumnType::Timestamp => Value::TimeDateTime(None),\n        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n        ColumnType::TimestampWithTimeZone => Value::TimeDateTimeWithTimeZone(None),\n        _ => Value::Int(None),\n    }\n}\n\n/// Null values for the time crate variants, used by the alt-value fallback path.\n#[cfg(all(feature = \"with-chrono\", feature = \"with-time\"))]\nfn null_value_for_type_time(col_type: &ColumnType) -> Value {\n    match col_type {\n        ColumnType::Date => Value::TimeDate(None),\n        ColumnType::Time => Value::TimeTime(None),\n        ColumnType::DateTime | ColumnType::Timestamp => Value::TimeDateTime(None),\n        ColumnType::TimestampWithTimeZone => Value::TimeDateTimeWithTimeZone(None),\n        _ => null_value_for_type(col_type),\n    }\n}\n\n// ---------------------------------------------------------------------------\n// Value -> Arrow\n// ---------------------------------------------------------------------------\n\n/// Convert a slice of [`Value`]s to an Arrow array matching the\n/// target [`DataType`](arrow::datatypes::DataType).\n///\n/// `Value::Variant(None)` (SQL NULL) entries become null in the array.\npub fn values_to_arrow_array(\n    values: &[Value],\n    data_type: &arrow::datatypes::DataType,\n) -> Result<std::sync::Arc<dyn Array>, ArrowError> {\n    use arrow::datatypes::{DataType, TimeUnit};\n    use std::sync::Arc;\n\n    match data_type {\n        DataType::Int8 => {\n            let arr: Int8Array = values\n                .iter()\n                .map(|v| match v {\n                    Value::TinyInt(inner) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Int16 => {\n            let arr: Int16Array = values\n                .iter()\n                .map(|v| match v {\n                    Value::SmallInt(inner) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Int32 => {\n            let arr: Int32Array = values\n                .iter()\n                .map(|v| match v {\n                    Value::Int(inner) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Int64 => {\n            let arr: Int64Array = values\n                .iter()\n                .map(|v| match v {\n                    Value::BigInt(inner) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::UInt8 => {\n            let arr: UInt8Array = values\n                .iter()\n                .map(|v| match v {\n                    Value::TinyUnsigned(inner) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::UInt16 => {\n            let arr: UInt16Array = values\n                .iter()\n                .map(|v| match v {\n                    Value::SmallUnsigned(inner) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::UInt32 => {\n            let arr: UInt32Array = values\n                .iter()\n                .map(|v| match v {\n                    Value::Unsigned(inner) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::UInt64 => {\n            let arr: UInt64Array = values\n                .iter()\n                .map(|v| match v {\n                    Value::BigUnsigned(inner) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Float32 => {\n            let arr: Float32Array = values\n                .iter()\n                .map(|v| match v {\n                    Value::Float(inner) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Float64 => {\n            let arr: Float64Array = values\n                .iter()\n                .map(|v| match v {\n                    Value::Double(inner) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Boolean => {\n            let arr: BooleanArray = values\n                .iter()\n                .map(|v| match v {\n                    Value::Bool(inner) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Utf8 => {\n            let strs: Vec<Option<&str>> = values\n                .iter()\n                .map(|v| match v {\n                    Value::String(Some(s)) => Some(s.as_str()),\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(StringArray::from(strs)))\n        }\n        DataType::LargeUtf8 => {\n            let strs: Vec<Option<&str>> = values\n                .iter()\n                .map(|v| match v {\n                    Value::String(Some(s)) => Some(s.as_str()),\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(LargeStringArray::from(strs)))\n        }\n        DataType::Binary => {\n            let bufs: Vec<Option<&[u8]>> = values\n                .iter()\n                .map(|v| match v {\n                    Value::Bytes(Some(b)) => Some(b.as_slice()),\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(BinaryArray::from(bufs)))\n        }\n        DataType::LargeBinary => {\n            let bufs: Vec<Option<&[u8]>> = values\n                .iter()\n                .map(|v| match v {\n                    Value::Bytes(Some(b)) => Some(b.as_slice()),\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(LargeBinaryArray::from(bufs)))\n        }\n        DataType::FixedSizeBinary(byte_width) => {\n            let mut builder = FixedSizeBinaryBuilder::with_capacity(values.len(), *byte_width);\n            for v in values {\n                match v {\n                    Value::Bytes(Some(b)) => builder.append_value(b.as_slice()).map_err(|e| {\n                        ArrowError::Unsupported(format!(\"FixedSizeBinary append error: {e}\"))\n                    })?,\n                    _ => builder.append_null(),\n                }\n            }\n            Ok(Arc::new(builder.finish()))\n        }\n        DataType::Date32 => {\n            let arr: Date32Array = values.iter().map(extract_date32).collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Time32(unit) => {\n            let vals: Vec<Option<i32>> = values.iter().map(|v| extract_time32(v, unit)).collect();\n            let arr: Arc<dyn Array> = match unit {\n                TimeUnit::Second => Arc::new(Time32SecondArray::from(vals)),\n                TimeUnit::Millisecond => Arc::new(Time32MillisecondArray::from(vals)),\n                _ => {\n                    return Err(ArrowError::Unsupported(format!(\n                        \"Unsupported Time32 unit: {unit:?}\"\n                    )));\n                }\n            };\n            Ok(arr)\n        }\n        DataType::Time64(unit) => {\n            let vals: Vec<Option<i64>> = values.iter().map(|v| extract_time64(v, unit)).collect();\n            let arr: Arc<dyn Array> = match unit {\n                TimeUnit::Microsecond => Arc::new(Time64MicrosecondArray::from(vals)),\n                TimeUnit::Nanosecond => Arc::new(Time64NanosecondArray::from(vals)),\n                _ => {\n                    return Err(ArrowError::Unsupported(format!(\n                        \"Unsupported Time64 unit: {unit:?}\"\n                    )));\n                }\n            };\n            Ok(arr)\n        }\n        DataType::Timestamp(unit, tz) => {\n            let vals: Vec<Option<i64>> =\n                values.iter().map(|v| extract_timestamp(v, unit)).collect();\n            let arr: Arc<dyn Array> = match unit {\n                TimeUnit::Second => {\n                    let mut a = TimestampSecondArray::from(vals);\n                    if let Some(tz) = tz {\n                        a = a.with_timezone(tz.as_ref());\n                    }\n                    Arc::new(a)\n                }\n                TimeUnit::Millisecond => {\n                    let mut a = TimestampMillisecondArray::from(vals);\n                    if let Some(tz) = tz {\n                        a = a.with_timezone(tz.as_ref());\n                    }\n                    Arc::new(a)\n                }\n                TimeUnit::Microsecond => {\n                    let mut a = TimestampMicrosecondArray::from(vals);\n                    if let Some(tz) = tz {\n                        a = a.with_timezone(tz.as_ref());\n                    }\n                    Arc::new(a)\n                }\n                TimeUnit::Nanosecond => {\n                    let mut a = TimestampNanosecondArray::from(vals);\n                    if let Some(tz) = tz {\n                        a = a.with_timezone(tz.as_ref());\n                    }\n                    Arc::new(a)\n                }\n            };\n            Ok(arr)\n        }\n        DataType::Decimal64(precision, scale) => {\n            let arr: Decimal64Array = values\n                .iter()\n                .map(|v| extract_decimal64(v, *scale))\n                .collect();\n            let arr = arr\n                .with_precision_and_scale(*precision, *scale)\n                .map_err(|e| {\n                    ArrowError::Unsupported(format!(\"Invalid Decimal64 precision/scale: {e}\"))\n                })?;\n            Ok(Arc::new(arr))\n        }\n        DataType::Decimal128(precision, scale) => {\n            let arr: Decimal128Array = values\n                .iter()\n                .map(|v| extract_decimal128(v, *scale))\n                .collect();\n            let arr = arr\n                .with_precision_and_scale(*precision, *scale)\n                .map_err(|e| {\n                    ArrowError::Unsupported(format!(\"Invalid Decimal128 precision/scale: {e}\"))\n                })?;\n            Ok(Arc::new(arr))\n        }\n        DataType::Decimal256(precision, scale) => {\n            let arr: Decimal256Array = values\n                .iter()\n                .map(|v| extract_decimal256(v, *scale))\n                .collect();\n            let arr = arr\n                .with_precision_and_scale(*precision, *scale)\n                .map_err(|e| {\n                    ArrowError::Unsupported(format!(\"Invalid Decimal256 precision/scale: {e}\"))\n                })?;\n            Ok(Arc::new(arr))\n        }\n        _ => Err(ArrowError::Unsupported(format!(\n            \"Unsupported Arrow DataType for to_arrow: {data_type:?}\"\n        ))),\n    }\n}\n\n/// Convert a slice of optional [`Value`]s to an Arrow array matching the\n/// target [`DataType`](arrow::datatypes::DataType).\n///\n/// `None` entries (from `ActiveValue::NotSet`) become null in the array.\n/// `Some(Value::Variant(None))` (SQL NULL) also become null.\npub fn option_values_to_arrow_array(\n    values: &[Option<Value>],\n    data_type: &arrow::datatypes::DataType,\n) -> Result<std::sync::Arc<dyn Array>, ArrowError> {\n    use arrow::datatypes::{DataType, TimeUnit};\n    use std::sync::Arc;\n\n    match data_type {\n        DataType::Int8 => {\n            let arr: Int8Array = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::TinyInt(inner)) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Int16 => {\n            let arr: Int16Array = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::SmallInt(inner)) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Int32 => {\n            let arr: Int32Array = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::Int(inner)) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Int64 => {\n            let arr: Int64Array = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::BigInt(inner)) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::UInt8 => {\n            let arr: UInt8Array = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::TinyUnsigned(inner)) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::UInt16 => {\n            let arr: UInt16Array = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::SmallUnsigned(inner)) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::UInt32 => {\n            let arr: UInt32Array = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::Unsigned(inner)) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::UInt64 => {\n            let arr: UInt64Array = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::BigUnsigned(inner)) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Float32 => {\n            let arr: Float32Array = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::Float(inner)) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Float64 => {\n            let arr: Float64Array = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::Double(inner)) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Boolean => {\n            let arr: BooleanArray = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::Bool(inner)) => *inner,\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Utf8 => {\n            let strs: Vec<Option<&str>> = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::String(Some(s))) => Some(s.as_str()),\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(StringArray::from(strs)))\n        }\n        DataType::LargeUtf8 => {\n            let strs: Vec<Option<&str>> = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::String(Some(s))) => Some(s.as_str()),\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(LargeStringArray::from(strs)))\n        }\n        DataType::Binary => {\n            let bufs: Vec<Option<&[u8]>> = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::Bytes(Some(b))) => Some(b.as_slice()),\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(BinaryArray::from(bufs)))\n        }\n        DataType::LargeBinary => {\n            let bufs: Vec<Option<&[u8]>> = values\n                .iter()\n                .map(|v| match v {\n                    Some(Value::Bytes(Some(b))) => Some(b.as_slice()),\n                    _ => None,\n                })\n                .collect();\n            Ok(Arc::new(LargeBinaryArray::from(bufs)))\n        }\n        DataType::FixedSizeBinary(byte_width) => {\n            let mut builder = FixedSizeBinaryBuilder::with_capacity(values.len(), *byte_width);\n            for v in values {\n                match v {\n                    Some(Value::Bytes(Some(b))) => {\n                        builder.append_value(b.as_slice()).map_err(|e| {\n                            ArrowError::Unsupported(format!(\"FixedSizeBinary append error: {e}\"))\n                        })?\n                    }\n                    _ => builder.append_null(),\n                }\n            }\n            Ok(Arc::new(builder.finish()))\n        }\n        DataType::Date32 => {\n            let arr: Date32Array = values.iter().map(extract_date32_option).collect();\n            Ok(Arc::new(arr))\n        }\n        DataType::Time32(unit) => {\n            let vals: Vec<Option<i32>> = values\n                .iter()\n                .map(|v| extract_time32_option(v, unit))\n                .collect();\n            let arr: Arc<dyn Array> = match unit {\n                TimeUnit::Second => Arc::new(Time32SecondArray::from(vals)),\n                TimeUnit::Millisecond => Arc::new(Time32MillisecondArray::from(vals)),\n                _ => {\n                    return Err(ArrowError::Unsupported(format!(\n                        \"Unsupported Time32 unit: {unit:?}\"\n                    )));\n                }\n            };\n            Ok(arr)\n        }\n        DataType::Time64(unit) => {\n            let vals: Vec<Option<i64>> = values\n                .iter()\n                .map(|v| extract_time64_option(v, unit))\n                .collect();\n            let arr: Arc<dyn Array> = match unit {\n                TimeUnit::Microsecond => Arc::new(Time64MicrosecondArray::from(vals)),\n                TimeUnit::Nanosecond => Arc::new(Time64NanosecondArray::from(vals)),\n                _ => {\n                    return Err(ArrowError::Unsupported(format!(\n                        \"Unsupported Time64 unit: {unit:?}\"\n                    )));\n                }\n            };\n            Ok(arr)\n        }\n        DataType::Timestamp(unit, tz) => {\n            let vals: Vec<Option<i64>> = values\n                .iter()\n                .map(|v| extract_timestamp_option(v, unit))\n                .collect();\n            let arr: Arc<dyn Array> = match unit {\n                TimeUnit::Second => {\n                    let mut a = TimestampSecondArray::from(vals);\n                    if let Some(tz) = tz {\n                        a = a.with_timezone(tz.as_ref());\n                    }\n                    Arc::new(a)\n                }\n                TimeUnit::Millisecond => {\n                    let mut a = TimestampMillisecondArray::from(vals);\n                    if let Some(tz) = tz {\n                        a = a.with_timezone(tz.as_ref());\n                    }\n                    Arc::new(a)\n                }\n                TimeUnit::Microsecond => {\n                    let mut a = TimestampMicrosecondArray::from(vals);\n                    if let Some(tz) = tz {\n                        a = a.with_timezone(tz.as_ref());\n                    }\n                    Arc::new(a)\n                }\n                TimeUnit::Nanosecond => {\n                    let mut a = TimestampNanosecondArray::from(vals);\n                    if let Some(tz) = tz {\n                        a = a.with_timezone(tz.as_ref());\n                    }\n                    Arc::new(a)\n                }\n            };\n            Ok(arr)\n        }\n        DataType::Decimal64(precision, scale) => {\n            let arr: Decimal64Array = values\n                .iter()\n                .map(|v| extract_decimal64_option(v, *scale))\n                .collect();\n            let arr = arr\n                .with_precision_and_scale(*precision, *scale)\n                .map_err(|e| {\n                    ArrowError::Unsupported(format!(\"Invalid Decimal64 precision/scale: {e}\"))\n                })?;\n            Ok(Arc::new(arr))\n        }\n        DataType::Decimal128(precision, scale) => {\n            let arr: Decimal128Array = values\n                .iter()\n                .map(|v| extract_decimal128_option(v, *scale))\n                .collect();\n            let arr = arr\n                .with_precision_and_scale(*precision, *scale)\n                .map_err(|e| {\n                    ArrowError::Unsupported(format!(\"Invalid Decimal128 precision/scale: {e}\"))\n                })?;\n            Ok(Arc::new(arr))\n        }\n        DataType::Decimal256(precision, scale) => {\n            let arr: Decimal256Array = values\n                .iter()\n                .map(|v| extract_decimal256_option(v, *scale))\n                .collect();\n            let arr = arr\n                .with_precision_and_scale(*precision, *scale)\n                .map_err(|e| {\n                    ArrowError::Unsupported(format!(\"Invalid Decimal256 precision/scale: {e}\"))\n                })?;\n            Ok(Arc::new(arr))\n        }\n        _ => Err(ArrowError::Unsupported(format!(\n            \"Unsupported Arrow DataType for to_arrow: {data_type:?}\"\n        ))),\n    }\n}\n\n// ---------------------------------------------------------------------------\n// Date extraction helpers\n// ---------------------------------------------------------------------------\n\nfn extract_date32_option(v: &Option<Value>) -> Option<i32> {\n    extract_date32(v.as_ref()?)\n}\n\nfn extract_date32(v: &Value) -> Option<i32> {\n    #[cfg(feature = \"with-chrono\")]\n    if let Value::ChronoDate(Some(d)) = v {\n        let epoch = sea_query::prelude::chrono::NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();\n        return Some((*d - epoch).num_days() as i32);\n    }\n    #[cfg(feature = \"with-time\")]\n    if let Value::TimeDate(Some(d)) = v {\n        return Some(d.to_julian_day() - 2_440_588);\n    }\n    let _ = v;\n    None\n}\n\n// ---------------------------------------------------------------------------\n// Time extraction helpers\n// ---------------------------------------------------------------------------\n\nfn extract_time32_option(v: &Option<Value>, unit: &arrow::datatypes::TimeUnit) -> Option<i32> {\n    extract_time32(v.as_ref()?, unit)\n}\n\nfn extract_time32(v: &Value, unit: &arrow::datatypes::TimeUnit) -> Option<i32> {\n    #[cfg(any(feature = \"with-chrono\", feature = \"with-time\"))]\n    use arrow::datatypes::TimeUnit;\n\n    #[cfg(feature = \"with-chrono\")]\n    if let Value::ChronoTime(Some(t)) = v {\n        use sea_query::prelude::chrono::Timelike;\n        let secs = t.num_seconds_from_midnight() as i32;\n        return match unit {\n            TimeUnit::Second => Some(secs),\n            TimeUnit::Millisecond => {\n                let ms = (t.nanosecond() / 1_000_000) as i32;\n                Some(secs * 1_000 + ms)\n            }\n            _ => None,\n        };\n    }\n    #[cfg(feature = \"with-time\")]\n    if let Value::TimeTime(Some(t)) = v {\n        let secs = (t.hour() as i32) * 3600 + (t.minute() as i32) * 60 + (t.second() as i32);\n        return match unit {\n            TimeUnit::Second => Some(secs),\n            TimeUnit::Millisecond => {\n                let ms = (t.nanosecond() / 1_000_000) as i32;\n                Some(secs * 1_000 + ms)\n            }\n            _ => None,\n        };\n    }\n    let _ = (v, unit);\n    None\n}\n\nfn extract_time64_option(v: &Option<Value>, unit: &arrow::datatypes::TimeUnit) -> Option<i64> {\n    extract_time64(v.as_ref()?, unit)\n}\n\nfn extract_time64(v: &Value, unit: &arrow::datatypes::TimeUnit) -> Option<i64> {\n    #[cfg(any(feature = \"with-chrono\", feature = \"with-time\"))]\n    use arrow::datatypes::TimeUnit;\n\n    #[cfg(feature = \"with-chrono\")]\n    if let Value::ChronoTime(Some(t)) = v {\n        use sea_query::prelude::chrono::Timelike;\n        let secs = t.num_seconds_from_midnight() as i64;\n        let nanos = (t.nanosecond() % 1_000_000_000) as i64;\n        return match unit {\n            TimeUnit::Microsecond => Some(secs * 1_000_000 + nanos / 1_000),\n            TimeUnit::Nanosecond => Some(secs * 1_000_000_000 + nanos),\n            _ => None,\n        };\n    }\n    #[cfg(feature = \"with-time\")]\n    if let Value::TimeTime(Some(t)) = v {\n        let secs = (t.hour() as i64) * 3600 + (t.minute() as i64) * 60 + (t.second() as i64);\n        let nanos = t.nanosecond() as i64;\n        return match unit {\n            TimeUnit::Microsecond => Some(secs * 1_000_000 + nanos / 1_000),\n            TimeUnit::Nanosecond => Some(secs * 1_000_000_000 + nanos),\n            _ => None,\n        };\n    }\n    let _ = (v, unit);\n    None\n}\n\n// ---------------------------------------------------------------------------\n// Timestamp extraction helpers\n// ---------------------------------------------------------------------------\n\nfn extract_timestamp_option(v: &Option<Value>, unit: &arrow::datatypes::TimeUnit) -> Option<i64> {\n    extract_timestamp(v.as_ref()?, unit)\n}\n\nfn extract_timestamp(v: &Value, unit: &arrow::datatypes::TimeUnit) -> Option<i64> {\n    #[cfg(any(feature = \"with-chrono\", feature = \"with-time\"))]\n    use arrow::datatypes::TimeUnit;\n\n    #[cfg(feature = \"with-chrono\")]\n    {\n        if let Value::ChronoDateTime(Some(dt)) = v {\n            let utc = dt.and_utc();\n            return Some(match unit {\n                TimeUnit::Second => utc.timestamp(),\n                TimeUnit::Millisecond => utc.timestamp_millis(),\n                TimeUnit::Microsecond => utc.timestamp_micros(),\n                TimeUnit::Nanosecond => utc.timestamp_nanos_opt().unwrap_or(0),\n            });\n        }\n        if let Value::ChronoDateTimeUtc(Some(dt)) = v {\n            return Some(match unit {\n                TimeUnit::Second => dt.timestamp(),\n                TimeUnit::Millisecond => dt.timestamp_millis(),\n                TimeUnit::Microsecond => dt.timestamp_micros(),\n                TimeUnit::Nanosecond => dt.timestamp_nanos_opt().unwrap_or(0),\n            });\n        }\n    }\n    #[cfg(feature = \"with-time\")]\n    {\n        if let Value::TimeDateTime(Some(dt)) = v {\n            let odt = dt.assume_utc();\n            return Some(offset_dt_to_timestamp(&odt, unit));\n        }\n        if let Value::TimeDateTimeWithTimeZone(Some(dt)) = v {\n            return Some(offset_dt_to_timestamp(dt, unit));\n        }\n    }\n    let _ = (v, unit);\n    None\n}\n\n#[cfg(feature = \"with-time\")]\nfn offset_dt_to_timestamp(\n    dt: &sea_query::prelude::time::OffsetDateTime,\n    unit: &arrow::datatypes::TimeUnit,\n) -> i64 {\n    use arrow::datatypes::TimeUnit;\n    match unit {\n        TimeUnit::Second => dt.unix_timestamp(),\n        TimeUnit::Millisecond => (dt.unix_timestamp_nanos() / 1_000_000) as i64,\n        TimeUnit::Microsecond => (dt.unix_timestamp_nanos() / 1_000) as i64,\n        TimeUnit::Nanosecond => dt.unix_timestamp_nanos() as i64,\n    }\n}\n\n// ---------------------------------------------------------------------------\n// Decimal extraction helpers\n// ---------------------------------------------------------------------------\n\nfn extract_decimal64_option(v: &Option<Value>, target_scale: i8) -> Option<i64> {\n    extract_decimal64(v.as_ref()?, target_scale)\n}\n\nfn extract_decimal64(v: &Value, target_scale: i8) -> Option<i64> {\n    #[cfg(feature = \"with-rust_decimal\")]\n    if let Value::Decimal(Some(d)) = v {\n        let mantissa = d.mantissa();\n        let current_scale = d.scale() as i8;\n        let scale_diff = target_scale - current_scale;\n        let scaled = if scale_diff >= 0 {\n            mantissa * 10i128.pow(scale_diff as u32)\n        } else {\n            mantissa / 10i128.pow((-scale_diff) as u32)\n        };\n        return i64::try_from(scaled).ok();\n    }\n    #[cfg(feature = \"with-bigdecimal\")]\n    if let Value::BigDecimal(Some(d)) = v {\n        return bigdecimal_to_i64(d, target_scale);\n    }\n    let _ = (v, target_scale);\n    None\n}\n\n#[cfg(feature = \"with-bigdecimal\")]\nfn bigdecimal_to_i64(\n    d: &sea_query::prelude::bigdecimal::BigDecimal,\n    target_scale: i8,\n) -> Option<i64> {\n    use sea_query::prelude::bigdecimal::ToPrimitive;\n\n    let rescaled = d.clone().with_scale(target_scale as i64);\n    let (digits, _) = rescaled.into_bigint_and_exponent();\n    digits.to_i64()\n}\n\nfn extract_decimal128_option(v: &Option<Value>, target_scale: i8) -> Option<i128> {\n    extract_decimal128(v.as_ref()?, target_scale)\n}\n\nfn extract_decimal128(v: &Value, target_scale: i8) -> Option<i128> {\n    #[cfg(feature = \"with-rust_decimal\")]\n    if let Value::Decimal(Some(d)) = v {\n        let mantissa = d.mantissa();\n        let current_scale = d.scale() as i8;\n        let scale_diff = target_scale - current_scale;\n        return if scale_diff >= 0 {\n            Some(mantissa * 10i128.pow(scale_diff as u32))\n        } else {\n            Some(mantissa / 10i128.pow((-scale_diff) as u32))\n        };\n    }\n    #[cfg(feature = \"with-bigdecimal\")]\n    if let Value::BigDecimal(Some(d)) = v {\n        return bigdecimal_to_i128(d, target_scale);\n    }\n    let _ = (v, target_scale);\n    None\n}\n\n#[cfg(feature = \"with-bigdecimal\")]\nfn bigdecimal_to_i128(\n    d: &sea_query::prelude::bigdecimal::BigDecimal,\n    target_scale: i8,\n) -> Option<i128> {\n    use sea_query::prelude::bigdecimal::ToPrimitive;\n\n    let rescaled = d.clone().with_scale(target_scale as i64);\n    let (digits, _) = rescaled.into_bigint_and_exponent();\n    digits.to_i128()\n}\n\nfn extract_decimal256_option(v: &Option<Value>, target_scale: i8) -> Option<i256> {\n    extract_decimal256(v.as_ref()?, target_scale)\n}\n\nfn extract_decimal256(v: &Value, target_scale: i8) -> Option<i256> {\n    #[cfg(feature = \"with-bigdecimal\")]\n    if let Value::BigDecimal(Some(d)) = v {\n        return bigdecimal_to_i256(d, target_scale);\n    }\n    #[cfg(feature = \"with-rust_decimal\")]\n    if let Value::Decimal(Some(d)) = v {\n        let mantissa = d.mantissa();\n        let current_scale = d.scale() as i8;\n        let scale_diff = target_scale - current_scale;\n        let scaled = if scale_diff >= 0 {\n            mantissa * 10i128.pow(scale_diff as u32)\n        } else {\n            mantissa / 10i128.pow((-scale_diff) as u32)\n        };\n        return Some(i256::from_i128(scaled));\n    }\n    let _ = (v, target_scale);\n    None\n}\n\n#[cfg(feature = \"with-bigdecimal\")]\nfn bigdecimal_to_i256(\n    d: &sea_query::prelude::bigdecimal::BigDecimal,\n    target_scale: i8,\n) -> Option<i256> {\n    let rescaled = d.clone().with_scale(target_scale as i64);\n    let (digits, _) = rescaled.into_bigint_and_exponent();\n    bigint_to_i256(&digits)\n}\n\n#[cfg(feature = \"with-bigdecimal\")]\nfn bigint_to_i256(bi: &sea_query::prelude::bigdecimal::num_bigint::BigInt) -> Option<i256> {\n    use sea_query::prelude::bigdecimal::num_bigint::Sign;\n\n    let (sign, bytes) = bi.to_bytes_be();\n    if bytes.len() > 32 {\n        return None;\n    }\n\n    let mut buf = [0u8; 32];\n    let start = 32 - bytes.len();\n    buf[start..].copy_from_slice(&bytes);\n\n    let val = i256::from_be_bytes(buf);\n    match sign {\n        Sign::Minus => Some(val.wrapping_neg()),\n        _ => Some(val),\n    }\n}\n"
  },
  {
    "path": "sea-orm-cli/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nauthors = [\n    \"Chris Tsang <chris.2y3@outlook.com>\",\n    \"Billy Chan <ccw.billy.123@gmail.com>\",\n]\ncategories = [\"database\"]\ndefault-run = \"sea-orm-cli\"\ndescription = \"Command line utility for SeaORM\"\ndocumentation = \"https://docs.rs/sea-orm\"\nedition = \"2024\"\nhomepage = \"https://www.sea-ql.org/SeaORM\"\nkeywords = [\"async\", \"orm\", \"mysql\", \"postgres\", \"sqlite\"]\nlicense = \"MIT OR Apache-2.0\"\nname = \"sea-orm-cli\"\nrepository = \"https://github.com/SeaQL/sea-orm\"\nrust-version = \"1.85.0\"\nversion = \"2.0.0-rc.37\"\n\n[lib]\nname = \"sea_orm_cli\"\npath = \"src/lib.rs\"\n\n[[bin]]\nname              = \"sea-orm-cli\"\npath              = \"src/bin/main.rs\"\nrequired-features = [\"cli\", \"codegen\"]\n\n[[bin]]\nname              = \"sea\"\npath              = \"src/bin/main.rs\"\nrequired-features = [\"cli\", \"codegen\"]\n\n[dependencies]\nasync-std = { version = \"1.9\", default-features = false, features = [\n    \"attributes\",\n    \"tokio1\",\n], optional = true }\nchrono = { version = \"0.4.20\", default-features = false, features = [\n    \"clock\",\n] }\nclap = { version = \"4.3\", features = [\"env\", \"derive\"], optional = true }\ndotenvy = { version = \"0.15\", default-features = false, optional = true }\nglob = { version = \"0.3\", default-features = false }\nindoc = \"2.0.6\"\nregex = { version = \"1.11.2\" }\nsea-orm-codegen = { version = \"=2.0.0-rc.37\", path = \"../sea-orm-codegen\", default-features = false, optional = true }\nsea-schema = { version = \"0.17.0-rc.1\", default-features = false, features = [\n    \"discovery\",\n    \"writer\",\n    \"probe\",\n], optional = true }\nsqlx = { version = \"0.8.4\", default-features = false, optional = true }\ntokio = { version = \"1.38.2\", default-features = false, features = [\n    \"rt-multi-thread\",\n    \"macros\",\n], optional = true }\ntracing = { version = \"0.1\", default-features = false }\ntracing-subscriber = { version = \"0.3.17\", default-features = false, features = [\n    \"env-filter\",\n    \"fmt\",\n] }\nurl = { version = \"2.2\", default-features = false }\n\n[dev-dependencies]\nsmol = \"1.2.5\"\n\n[features]\ncli = [\"clap\", \"dotenvy\"]\ncodegen = [\"cli\", \"sqlx\", \"sea-schema\", \"sea-orm-codegen\"]\ndefault = [\n    \"codegen\",\n    \"sqlx-mysql\",\n    \"sqlx-postgres\",\n    \"sqlx-sqlite\",\n    \"runtime-tokio-native-tls\",\n]\npostgres-vector = [\"sea-schema/postgres-vector\"]\nsqlx-mysql = [\n    \"sqlx?/sqlx-mysql\",\n    \"sea-schema?/sqlx-mysql\",\n    \"sea-schema?/mysql\",\n]\nsqlx-postgres = [\n    \"sqlx?/sqlx-postgres\",\n    \"sea-schema?/sqlx-postgres\",\n    \"sea-schema?/postgres\",\n]\nsqlx-sqlite = [\n    \"sqlx?/sqlx-sqlite\",\n    \"sea-schema?/sqlx-sqlite\",\n    \"sea-schema?/sqlite\",\n]\n\nruntime-actix            = [\"runtime-tokio\"]\nruntime-actix-native-tls = [\"runtime-tokio-native-tls\"]\nruntime-actix-rustls     = [\"runtime-tokio-rustls\"]\n\nruntime-async-std = [\n    \"async-std\",\n    \"sqlx?/runtime-async-std\",\n    \"sea-schema?/runtime-async-std\",\n]\nruntime-async-std-native-tls = [\n    \"async-std\",\n    \"sqlx?/runtime-async-std-native-tls\",\n    \"sea-schema?/runtime-async-std-native-tls\",\n]\nruntime-async-std-rustls = [\n    \"async-std\",\n    \"sqlx?/runtime-async-std-rustls\",\n    \"sea-schema?/runtime-async-std-rustls\",\n]\n\nruntime-tokio = [\"tokio\", \"sqlx?/runtime-tokio\", \"sea-schema?/runtime-tokio\"]\nruntime-tokio-native-tls = [\n    \"tokio\",\n    \"sqlx?/runtime-tokio-native-tls\",\n    \"sea-schema?/runtime-tokio-native-tls\",\n]\nruntime-tokio-rustls = [\n    \"tokio\",\n    \"sqlx?/runtime-tokio-rustls\",\n    \"sea-schema?/runtime-tokio-rustls\",\n]\n\n# This allows us to develop using an overridden version of sea-query\n[patch.crates-io]\n# sea-query = { path = \"../sea-query\" }\n# sea-query = { git = \"https://github.com/SeaQL/sea-query\", branch = \"master\" }\n"
  },
  {
    "path": "sea-orm-cli/README.md",
    "content": "# SeaORM CLI\n\nInstall and Usage: \n\n```sh\n> cargo install sea-orm-cli \n> sea-orm-cli help\n```\n\nOr: \n\n```sh\n> cargo install --bin sea\n> sea help\n```\n\nGetting Help:\n\n```sh\ncargo run -- -h\n```\n\n## Running Entity Generator:\n\n```sh\n# MySQL (`--database-schema` option is ignored)\ncargo run -- generate entity -u mysql://sea:sea@localhost/bakery -o out\n\n# SQLite (`--database-schema` option is ignored)\ncargo run -- generate entity -u sqlite://bakery.db -o out\n\n# PostgreSQL\ncargo run -- generate entity -u postgres://sea:sea@localhost/bakery -s public -o out\n```\n\n## Running Migration:\n\n- Initialize migration directory\n    ```sh\n    cargo run -- migrate init\n    ```\n- Generate a new migration file\n    ```sh\n    cargo run -- migrate generate MIGRATION_NAME\n    ```\n- Apply all pending migrations\n    ```sh\n    cargo run -- migrate\n    ```\n    ```sh\n    cargo run -- migrate up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- migrate up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- migrate down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- migrate down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- migrate fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- migrate refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- migrate reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- migrate status\n    ```\n\n"
  },
  {
    "path": "sea-orm-cli/src/bin/main.rs",
    "content": "#[cfg_attr(\n    any(\n        feature = \"runtime-async-std\",\n        feature = \"runtime-async-std-native-tls\",\n        feature = \"runtime-async-std-rustls\"\n    ),\n    async_std::main\n)]\n#[cfg_attr(\n    any(\n        feature = \"runtime-tokio\",\n        feature = \"runtime-tokio-native-tls\",\n        feature = \"runtime-tokio-rustls\",\n    ),\n    tokio::main\n)]\nasync fn main() {\n    sea_orm_cli::main().await\n}\n"
  },
  {
    "path": "sea-orm-cli/src/cli.rs",
    "content": "use clap::{ArgAction, ArgGroup, Parser, Subcommand, ValueEnum};\n#[cfg(feature = \"codegen\")]\nuse dotenvy::dotenv;\nuse std::ffi::OsStr;\n\n#[cfg(feature = \"codegen\")]\nuse crate::{handle_error, run_generate_command, run_migrate_command};\n\n#[derive(Parser, Debug)]\n#[command(\n    version,\n    author,\n    help_template = r#\"{before-help}{name} {version}\n{about-with-newline}\n\n{usage-heading} {usage}\n\n{all-args}{after-help}\n\n\"#,\n    about = r#\"\n   ____                 ___   ____   __  __        /\\\n  / ___|   ___   __ _  / _ \\ |  _ \\ |  \\/  |      {.-}\n  \\___ \\  / _ \\ / _` || | | || |_) || |\\/| |     ;_.-'\\\n   ___) ||  __/| (_| || |_| ||  _ < | |  | |    {    _.}_\n  |____/  \\___| \\__,_| \\___/ |_| \\_\\|_|  |_|     \\.-' /  `,\n                                                  \\  |    /\n  An async & dynamic ORM for Rust                  \\ |  ,/\n  ===============================                   \\|_/\n\n  Getting Started\n    - Documentation: https://www.sea-ql.org/SeaORM\n    - Tutorial: https://www.sea-ql.org/sea-orm-tutorial\n    - Examples: https://github.com/SeaQL/sea-orm/tree/master/examples\n    - Cookbook: https://www.sea-ql.org/sea-orm-cookbook\n\n  Join our Discord server to chat with others in the SeaQL community!\n    - Invitation: https://discord.com/invite/uCPdDXzbdv\n\n  SeaQL Community Survey 2025\n    - Link: https://www.sea-ql.org/community-survey/\n\n  If you like what we do, consider starring, sharing and contributing!\n\"#\n)]\npub struct Cli {\n    #[arg(global = true, short, long, help = \"Show debug messages\")]\n    pub verbose: bool,\n\n    #[command(subcommand)]\n    pub command: Commands,\n}\n\n#[allow(clippy::large_enum_variant)]\n#[derive(Subcommand, PartialEq, Eq, Debug)]\npub enum Commands {\n    #[command(\n        about = \"Codegen related commands\",\n        arg_required_else_help = true,\n        display_order = 10\n    )]\n    Generate {\n        #[command(subcommand)]\n        command: GenerateSubcommands,\n    },\n    #[command(about = \"Migration related commands\", display_order = 20)]\n    Migrate {\n        #[arg(\n            global = true,\n            short = 'd',\n            long,\n            env = \"MIGRATION_DIR\",\n            help = \"Migration script directory.\nIf your migrations are in their own crate,\nyou can provide the root of that crate.\nIf your migrations are in a submodule of your app,\nyou should provide the directory of that submodule.\",\n            default_value = \"./migration\"\n        )]\n        migration_dir: String,\n\n        #[arg(\n            global = true,\n            short = 's',\n            long,\n            env = \"DATABASE_SCHEMA\",\n            long_help = \"Database schema\\n \\\n                        - For MySQL and SQLite, this argument is ignored.\\n \\\n                        - For PostgreSQL, this argument is optional with default value 'public'.\\n\"\n        )]\n        database_schema: Option<String>,\n\n        #[arg(\n            global = true,\n            short = 'u',\n            long,\n            env = \"DATABASE_URL\",\n            help = \"Database URL\",\n            hide_env_values = true\n        )]\n        database_url: Option<String>,\n\n        #[command(subcommand)]\n        command: Option<MigrateSubcommands>,\n    },\n}\n\n#[derive(Subcommand, PartialEq, Eq, Debug)]\npub enum MigrateSubcommands {\n    #[command(about = \"Initialize migration directory\", display_order = 10)]\n    Init,\n    #[command(about = \"Generate a new, empty migration\", display_order = 20)]\n    Generate {\n        #[arg(required = true, help = \"Name of the new migration\")]\n        migration_name: String,\n\n        #[arg(\n            long,\n            default_value = \"true\",\n            help = \"Generate migration file based on Utc time\",\n            conflicts_with = \"local_time\",\n            display_order = 1001\n        )]\n        universal_time: bool,\n\n        #[arg(\n            long,\n            help = \"Generate migration file based on Local time\",\n            conflicts_with = \"universal_time\",\n            display_order = 1002\n        )]\n        local_time: bool,\n    },\n    #[command(\n        about = \"Drop all tables from the database, then reapply all migrations\",\n        display_order = 30\n    )]\n    Fresh,\n    #[command(\n        about = \"Rollback all applied migrations, then reapply all migrations\",\n        display_order = 40\n    )]\n    Refresh,\n    #[command(about = \"Rollback all applied migrations\", display_order = 50)]\n    Reset,\n    #[command(about = \"Check the status of all migrations\", display_order = 60)]\n    Status,\n    #[command(about = \"Apply pending migrations\", display_order = 70)]\n    Up {\n        #[arg(short, long, help = \"Number of pending migrations to apply\")]\n        num: Option<u32>,\n    },\n    #[command(about = \"Rollback applied migrations\", display_order = 80)]\n    Down {\n        #[arg(\n            short,\n            long,\n            default_value = \"1\",\n            help = \"Number of applied migrations to be rolled back\",\n            display_order = 90\n        )]\n        num: u32,\n    },\n}\n\n#[derive(Subcommand, PartialEq, Eq, Debug)]\npub enum GenerateSubcommands {\n    #[command(about = \"Generate entity\")]\n    #[command(group(ArgGroup::new(\"formats\").args(&[\"compact_format\", \"expanded_format\", \"frontend_format\"])))]\n    #[command(group(ArgGroup::new(\"group-tables\").args(&[\"tables\", \"include_hidden_tables\"])))]\n    Entity {\n        #[arg(long, help = \"Which format to generate entity files in\")]\n        entity_format: Option<String>,\n\n        #[arg(long, help = \"Generate entity file of compact format\")]\n        compact_format: bool,\n\n        #[arg(long, help = \"Generate entity file of expanded format\")]\n        expanded_format: bool,\n\n        #[arg(long, help = \"Generate entity file of frontend format\")]\n        frontend_format: bool,\n\n        #[arg(\n            long,\n            help = \"Generate entity file for hidden tables (i.e. table name starts with an underscore)\"\n        )]\n        include_hidden_tables: bool,\n\n        #[arg(\n            short = 't',\n            long,\n            value_delimiter = ',',\n            help = \"Generate entity file for specified tables only (comma separated)\"\n        )]\n        tables: Vec<String>,\n\n        #[arg(\n            long,\n            value_delimiter = ',',\n            default_value = \"seaql_migrations\",\n            help = \"Skip generating entity file for specified tables (comma separated)\"\n        )]\n        ignore_tables: Vec<String>,\n\n        #[arg(\n            long,\n            default_value = \"1\",\n            help = \"The maximum amount of connections to use when connecting to the database.\"\n        )]\n        max_connections: u32,\n\n        #[arg(\n            long,\n            default_value = \"30\",\n            long_help = \"Acquire timeout in seconds of the connection used for schema discovery\"\n        )]\n        acquire_timeout: u64,\n\n        #[arg(\n            short = 'o',\n            long,\n            default_value = \"./\",\n            help = \"Entity file output directory\"\n        )]\n        output_dir: String,\n\n        #[arg(\n            short = 's',\n            long,\n            env = \"DATABASE_SCHEMA\",\n            long_help = \"Database schema\\n \\\n                        - For MySQL, this argument is ignored.\\n \\\n                        - For PostgreSQL, this argument is optional with default value 'public'.\"\n        )]\n        database_schema: Option<String>,\n\n        #[arg(\n            short = 'u',\n            long,\n            env = \"DATABASE_URL\",\n            help = \"Database URL\",\n            hide_env_values = true\n        )]\n        database_url: String,\n\n        #[arg(\n            long,\n            default_value = \"all\",\n            help = \"Generate prelude.rs file (all, none, all-allow-unused-imports)\"\n        )]\n        with_prelude: String,\n\n        #[arg(\n            long,\n            default_value = \"none\",\n            help = \"Automatically derive serde Serialize / Deserialize traits for the entity (none, \\\n                serialize, deserialize, both)\"\n        )]\n        with_serde: String,\n\n        #[arg(\n            long,\n            help = \"Generate a serde field attribute, '#[serde(skip_deserializing)]', for the primary key fields to skip them during deserialization, this flag will be affective only when '--with-serde' is 'both' or 'deserialize'\"\n        )]\n        serde_skip_deserializing_primary_key: bool,\n\n        #[arg(\n            long,\n            default_value = \"false\",\n            help = \"Opt-in to add skip attributes to hidden columns (i.e. when 'with-serde' enabled and column name starts with an underscore)\"\n        )]\n        serde_skip_hidden_column: bool,\n\n        #[arg(\n            long,\n            default_value = \"false\",\n            long_help = \"Automatically derive the Copy trait on generated enums.\\n\\\n            Enums generated from a database don't have associated data by default, and as such can \\\n            derive Copy.\n            \"\n        )]\n        with_copy_enums: bool,\n\n        #[arg(\n            long,\n            default_value_t,\n            value_enum,\n            help = \"The datetime crate to use for generating entities.\"\n        )]\n        date_time_crate: DateTimeCrate,\n\n        #[arg(\n            long,\n            default_value_t,\n            value_enum,\n            help = \"The primitive type to use for big integer.\"\n        )]\n        big_integer_type: BigIntegerType,\n\n        #[arg(\n            long,\n            short = 'l',\n            default_value = \"false\",\n            help = \"Generate index file as `lib.rs` instead of `mod.rs`.\"\n        )]\n        lib: bool,\n\n        #[arg(\n            long,\n            value_delimiter = ',',\n            help = \"Add extra derive macros to generated model struct (comma separated), e.g. `--model-extra-derives 'ts_rs::Ts','CustomDerive'`\"\n        )]\n        model_extra_derives: Vec<String>,\n\n        #[arg(\n            long,\n            value_delimiter = ',',\n            help = r#\"Add extra attributes to generated model struct, no need for `#[]` (comma separated), e.g. `--model-extra-attributes 'serde(rename_all = \"camelCase\")','ts(export)'`\"#\n        )]\n        model_extra_attributes: Vec<String>,\n\n        #[arg(\n            long,\n            value_delimiter = ',',\n            help = \"Add extra derive macros to generated enums (comma separated), e.g. `--enum-extra-derives 'ts_rs::Ts','CustomDerive'`\"\n        )]\n        enum_extra_derives: Vec<String>,\n\n        #[arg(\n            long,\n            value_delimiter = ',',\n            help = r#\"Add extra attributes to generated enums, no need for `#[]` (comma separated), e.g. `--enum-extra-attributes 'serde(rename_all = \"camelCase\")','ts(export)'`\"#\n        )]\n        enum_extra_attributes: Vec<String>,\n\n        #[arg(\n            long,\n            value_delimiter = ',',\n            help = \"Add extra derive macros to generated column enum (comma separated), e.g. `--column-extra-derives 'async_graphql::Enum','CustomDerive'`\"\n        )]\n        column_extra_derives: Vec<String>,\n\n        #[arg(\n            long,\n            default_value = \"false\",\n            long_help = \"Generate helper Enumerations that are used by Seaography.\"\n        )]\n        seaography: bool,\n\n        #[arg(\n            long,\n            default_value = \"true\",\n            default_missing_value = \"true\",\n            num_args = 0..=1,\n            require_equals = true,\n            action = ArgAction::Set,\n            long_help = \"Generate empty ActiveModelBehavior impls.\"\n        )]\n        impl_active_model_behavior: bool,\n\n        #[arg(\n            long = \"experimental-preserve-user-modifications\",\n            alias = \"preserve-user-modifications\",\n            default_value = \"false\",\n            default_missing_value = \"true\",\n            num_args = 0..=1,\n            require_equals = true,\n            action = ArgAction::Set,\n            long_help = indoc::indoc! { \"\n                Experimental!: Preserve user modifications when regenerating entity files.\n                Only supports:\n                    - Extra derives and attributes of `Model` and `Relation`\n                    - Impl blocks of `ActiveModelBehavior`\n                Deprecated alias: `--preserve-user-modifications`\"\n            }\n        )]\n        preserve_user_modifications: bool,\n\n        #[arg(\n            long,\n            default_value_t,\n            value_enum,\n            help = \"Control how the codegen version is displayed in the top banner of the generated file.\"\n        )]\n        banner_version: BannerVersion,\n\n        #[arg(\n            long,\n            default_value = \"false\",\n            help = \"Also generate a Mermaid ER diagram as `entities.mermaid` in the output directory\"\n        )]\n        er_diagram: bool,\n    },\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum, Default)]\npub enum DateTimeCrate {\n    #[default]\n    Chrono,\n    Time,\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum, Default)]\npub enum BigIntegerType {\n    #[default]\n    I64,\n    I32,\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, ValueEnum, Default)]\npub enum BannerVersion {\n    Off,\n    Major,\n    #[default]\n    Minor,\n    Patch,\n}\n\nfn is_deprecated_preserve_user_modifications_flag(arg: &OsStr) -> bool {\n    arg.to_str()\n        .is_some_and(|arg| arg.starts_with(\"--preserve-user-modifications\"))\n}\n\n/// Use this to build a local, version-controlled `sea-orm-cli` in dependent projects\n/// (see [example use case](https://github.com/SeaQL/sea-orm/discussions/1889)).\n#[cfg(feature = \"codegen\")]\npub async fn main() {\n    dotenv().ok();\n\n    let deprecated_preserve_user_modifications_flag_used = std::env::args_os()\n        .skip(1)\n        .any(|arg| is_deprecated_preserve_user_modifications_flag(&arg));\n\n    let cli = Cli::parse();\n    if deprecated_preserve_user_modifications_flag_used {\n        eprintln!(\n            \"warning: `--preserve-user-modifications` is deprecated; use `--experimental-preserve-user-modifications` instead.\"\n        );\n    }\n    let verbose = cli.verbose;\n\n    match cli.command {\n        Commands::Generate { command } => {\n            run_generate_command(command, verbose)\n                .await\n                .unwrap_or_else(handle_error);\n        }\n        Commands::Migrate {\n            migration_dir,\n            database_schema,\n            database_url,\n            command,\n        } => run_migrate_command(\n            command,\n            &migration_dir,\n            database_schema,\n            database_url,\n            verbose,\n        )\n        .unwrap_or_else(handle_error),\n    }\n}\n"
  },
  {
    "path": "sea-orm-cli/src/commands/generate.rs",
    "content": "use crate::{BannerVersion, BigIntegerType, DateTimeCrate, GenerateSubcommands};\nuse core::time;\nuse sea_orm_codegen::{\n    BannerVersion as CodegenBannerVersion, BigIntegerType as CodegenBigIntegerType,\n    DateTimeCrate as CodegenDateTimeCrate, EntityFormat, EntityTransformer, EntityWriterContext,\n    MergeReport, OutputFile, WithPrelude, WithSerde, merge_entity_files,\n};\nuse std::{error::Error, fs, path::Path, process::Command, str::FromStr};\nuse tracing_subscriber::{EnvFilter, prelude::*};\nuse url::Url;\n\npub async fn run_generate_command(\n    command: GenerateSubcommands,\n    verbose: bool,\n) -> Result<(), Box<dyn Error>> {\n    match command {\n        GenerateSubcommands::Entity {\n            entity_format,\n            compact_format: _,\n            expanded_format,\n            frontend_format,\n            include_hidden_tables,\n            tables,\n            ignore_tables,\n            max_connections,\n            acquire_timeout,\n            output_dir,\n            database_schema,\n            database_url,\n            with_prelude,\n            with_serde,\n            serde_skip_deserializing_primary_key,\n            serde_skip_hidden_column,\n            with_copy_enums,\n            date_time_crate,\n            big_integer_type,\n            lib,\n            model_extra_derives,\n            model_extra_attributes,\n            enum_extra_derives,\n            enum_extra_attributes,\n            column_extra_derives,\n            seaography,\n            impl_active_model_behavior,\n            preserve_user_modifications,\n            banner_version,\n            er_diagram,\n        } => {\n            if verbose {\n                let _ = tracing_subscriber::fmt()\n                    .with_max_level(tracing::Level::DEBUG)\n                    .with_test_writer()\n                    .try_init();\n            } else {\n                let filter_layer = EnvFilter::try_new(\"sea_orm_codegen=info\").unwrap();\n                let fmt_layer = tracing_subscriber::fmt::layer()\n                    .with_target(false)\n                    .with_level(false)\n                    .without_time();\n\n                let _ = tracing_subscriber::registry()\n                    .with(filter_layer)\n                    .with(fmt_layer)\n                    .try_init();\n            }\n\n            // The database should be a valid URL that can be parsed\n            // protocol://username:password@host/database_name\n            let url = Url::parse(&database_url)?;\n\n            // Make sure we have all the required url components\n            //\n            // Missing scheme will have been caught by the Url::parse() call\n            // above\n            let is_sqlite = url.scheme() == \"sqlite\";\n\n            // Closures for filtering tables\n            let filter_tables =\n                |table: &String| -> bool { tables.is_empty() || tables.contains(table) };\n\n            let filter_hidden_tables = |table: &str| -> bool {\n                if include_hidden_tables {\n                    true\n                } else {\n                    !table.starts_with('_')\n                }\n            };\n\n            let filter_skip_tables = |table: &String| -> bool { !ignore_tables.contains(table) };\n\n            let _database_name = if !is_sqlite {\n                // The database name should be the first element of the path string\n                //\n                // Throwing an error if there is no database name since it might be\n                // accepted by the database without it, while we're looking to dump\n                // information from a particular database\n                let database_name = url\n                    .path_segments()\n                    .unwrap_or_else(|| {\n                        panic!(\n                            \"There is no database name as part of the url path: {}\",\n                            url.as_str()\n                        )\n                    })\n                    .next()\n                    .unwrap();\n\n                // An empty string as the database name is also an error\n                if database_name.is_empty() {\n                    panic!(\n                        \"There is no database name as part of the url path: {}\",\n                        url.as_str()\n                    );\n                }\n\n                database_name\n            } else {\n                Default::default()\n            };\n\n            let (schema_name, table_stmts) = match url.scheme() {\n                \"mysql\" => {\n                    #[cfg(not(feature = \"sqlx-mysql\"))]\n                    {\n                        panic!(\"mysql feature is off\")\n                    }\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    {\n                        use sea_schema::mysql::discovery::SchemaDiscovery;\n                        use sqlx::MySql;\n\n                        println!(\"Connecting to MySQL ...\");\n                        let connection = sqlx_connect::<MySql>(\n                            max_connections,\n                            acquire_timeout,\n                            url.as_str(),\n                            None,\n                        )\n                        .await?;\n                        println!(\"Discovering schema ...\");\n                        let schema_discovery = SchemaDiscovery::new(connection, _database_name);\n                        let schema = schema_discovery.discover().await?;\n                        let table_stmts = schema\n                            .tables\n                            .into_iter()\n                            .filter(|schema| filter_tables(&schema.info.name))\n                            .filter(|schema| filter_hidden_tables(&schema.info.name))\n                            .filter(|schema| filter_skip_tables(&schema.info.name))\n                            .map(|schema| schema.write())\n                            .collect();\n                        (None, table_stmts)\n                    }\n                }\n                \"sqlite\" => {\n                    #[cfg(not(feature = \"sqlx-sqlite\"))]\n                    {\n                        panic!(\"sqlite feature is off\")\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    {\n                        use sea_schema::sqlite::discovery::SchemaDiscovery;\n                        use sqlx::Sqlite;\n\n                        println!(\"Connecting to SQLite ...\");\n                        let connection = sqlx_connect::<Sqlite>(\n                            max_connections,\n                            acquire_timeout,\n                            url.as_str(),\n                            None,\n                        )\n                        .await?;\n                        println!(\"Discovering schema ...\");\n                        let schema_discovery = SchemaDiscovery::new(connection);\n                        let schema = schema_discovery\n                            .discover()\n                            .await?\n                            .merge_indexes_into_table();\n                        let table_stmts = schema\n                            .tables\n                            .into_iter()\n                            .filter(|schema| filter_tables(&schema.name))\n                            .filter(|schema| filter_hidden_tables(&schema.name))\n                            .filter(|schema| filter_skip_tables(&schema.name))\n                            .map(|schema| schema.write())\n                            .collect();\n                        (None, table_stmts)\n                    }\n                }\n                \"postgres\" | \"postgresql\" => {\n                    #[cfg(not(feature = \"sqlx-postgres\"))]\n                    {\n                        panic!(\"postgres feature is off\")\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    {\n                        use sea_schema::postgres::discovery::SchemaDiscovery;\n                        use sqlx::Postgres;\n\n                        println!(\"Connecting to Postgres ...\");\n                        let schema = database_schema.as_deref().unwrap_or(\"public\");\n                        let connection = sqlx_connect::<Postgres>(\n                            max_connections,\n                            acquire_timeout,\n                            url.as_str(),\n                            Some(schema),\n                        )\n                        .await?;\n                        println!(\"Discovering schema ...\");\n                        let schema_discovery = SchemaDiscovery::new(connection, schema);\n                        let schema = schema_discovery.discover().await?;\n                        let table_stmts = schema\n                            .tables\n                            .into_iter()\n                            .filter(|schema| filter_tables(&schema.info.name))\n                            .filter(|schema| filter_hidden_tables(&schema.info.name))\n                            .filter(|schema| filter_skip_tables(&schema.info.name))\n                            .map(|schema| schema.write())\n                            .collect();\n                        (database_schema, table_stmts)\n                    }\n                }\n                _ => unimplemented!(\"{} is not supported\", url.scheme()),\n            };\n            println!(\"... discovered.\");\n\n            let writer_context = EntityWriterContext::new(\n                if expanded_format {\n                    EntityFormat::Expanded\n                } else if frontend_format {\n                    EntityFormat::Frontend\n                } else if let Some(entity_format) = entity_format {\n                    EntityFormat::from_str(&entity_format).expect(\"Invalid entity-format option\")\n                } else {\n                    EntityFormat::default()\n                },\n                WithPrelude::from_str(&with_prelude).expect(\"Invalid prelude option\"),\n                WithSerde::from_str(&with_serde).expect(\"Invalid serde derive option\"),\n                with_copy_enums,\n                date_time_crate.into(),\n                big_integer_type.into(),\n                schema_name,\n                lib,\n                serde_skip_deserializing_primary_key,\n                serde_skip_hidden_column,\n                model_extra_derives,\n                model_extra_attributes,\n                enum_extra_derives,\n                enum_extra_attributes,\n                column_extra_derives,\n                seaography,\n                impl_active_model_behavior,\n                banner_version.into(),\n            );\n            let entity_writer = EntityTransformer::transform(table_stmts)?;\n\n            let dir = Path::new(&output_dir);\n            fs::create_dir_all(dir)?;\n\n            if er_diagram {\n                let diagram = entity_writer.generate_er_diagram();\n                let diagram_path = dir.join(\"entities.mermaid\");\n                fs::write(&diagram_path, &diagram)?;\n                println!(\"Writing {}\", diagram_path.display());\n            }\n\n            let output = entity_writer.generate(&writer_context);\n\n            let mut merge_fallback_files: Vec<String> = Vec::new();\n\n            for OutputFile { name, content } in output.files.iter() {\n                let file_path = dir.join(name);\n                println!(\"Writing {}\", file_path.display());\n\n                if !matches!(\n                    name.as_str(),\n                    \"mod.rs\" | \"lib.rs\" | \"prelude.rs\" | \"sea_orm_active_enums.rs\"\n                ) && file_path.exists()\n                    && preserve_user_modifications\n                {\n                    let prev_content = fs::read_to_string(&file_path)?;\n                    match merge_entity_files(&prev_content, content) {\n                        Ok(merged) => {\n                            fs::write(file_path, merged)?;\n                        }\n                        Err(MergeReport {\n                            output,\n                            warnings,\n                            fallback_applied,\n                        }) => {\n                            for message in warnings {\n                                eprintln!(\"{message}\");\n                            }\n                            fs::write(file_path, output)?;\n                            if fallback_applied {\n                                merge_fallback_files.push(name.clone());\n                            }\n                        }\n                    }\n                } else {\n                    fs::write(file_path, content)?;\n                };\n            }\n\n            // Format each of the files\n            for OutputFile { name, .. } in output.files.iter() {\n                let exit_status = Command::new(\"rustfmt\").arg(dir.join(name)).status()?; // Get the status code\n                if !exit_status.success() {\n                    // Propagate the error if any\n                    return Err(format!(\"Fail to format file `{name}`\").into());\n                }\n            }\n\n            if merge_fallback_files.is_empty() {\n                println!(\"... Done.\");\n            } else {\n                return Err(format!(\n                    \"Merge fallback applied for {} file(s): \\n{}\",\n                    merge_fallback_files.len(),\n                    merge_fallback_files.join(\"\\n\")\n                )\n                .into());\n            }\n        }\n    }\n\n    Ok(())\n}\n\nasync fn sqlx_connect<DB>(\n    max_connections: u32,\n    acquire_timeout: u64,\n    url: &str,\n    schema: Option<&str>,\n) -> Result<sqlx::Pool<DB>, Box<dyn Error>>\nwhere\n    DB: sqlx::Database,\n    for<'a> &'a mut <DB as sqlx::Database>::Connection: sqlx::Executor<'a>,\n{\n    let mut pool_options = sqlx::pool::PoolOptions::<DB>::new()\n        .max_connections(max_connections)\n        .acquire_timeout(time::Duration::from_secs(acquire_timeout));\n    // Set search_path for Postgres, E.g. Some(\"public\") by default\n    // MySQL & SQLite connection initialize with schema `None`\n    if let Some(schema) = schema {\n        let sql = format!(\"SET search_path = '{schema}'\");\n        pool_options = pool_options.after_connect(move |conn, _| {\n            let sql = sql.clone();\n            Box::pin(async move {\n                sqlx::Executor::execute(conn, sql.as_str())\n                    .await\n                    .map(|_| ())\n            })\n        });\n    }\n    pool_options.connect(url).await.map_err(Into::into)\n}\n\nimpl From<DateTimeCrate> for CodegenDateTimeCrate {\n    fn from(date_time_crate: DateTimeCrate) -> CodegenDateTimeCrate {\n        match date_time_crate {\n            DateTimeCrate::Chrono => CodegenDateTimeCrate::Chrono,\n            DateTimeCrate::Time => CodegenDateTimeCrate::Time,\n        }\n    }\n}\n\nimpl From<BigIntegerType> for CodegenBigIntegerType {\n    fn from(date_time_crate: BigIntegerType) -> CodegenBigIntegerType {\n        match date_time_crate {\n            BigIntegerType::I64 => CodegenBigIntegerType::I64,\n            BigIntegerType::I32 => CodegenBigIntegerType::I32,\n        }\n    }\n}\n\nimpl From<BannerVersion> for CodegenBannerVersion {\n    fn from(banner_version: BannerVersion) -> CodegenBannerVersion {\n        match banner_version {\n            BannerVersion::Off => CodegenBannerVersion::Off,\n            BannerVersion::Major => CodegenBannerVersion::Major,\n            BannerVersion::Minor => CodegenBannerVersion::Minor,\n            BannerVersion::Patch => CodegenBannerVersion::Patch,\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use clap::Parser;\n\n    use super::*;\n    use crate::{Cli, Commands};\n\n    #[test]\n    #[should_panic(\n        expected = \"called `Result::unwrap()` on an `Err` value: RelativeUrlWithoutBase\"\n    )]\n    fn test_generate_entity_no_protocol() {\n        let cli = Cli::parse_from([\n            \"sea-orm-cli\",\n            \"generate\",\n            \"entity\",\n            \"--database-url\",\n            \"://root:root@localhost:3306/database\",\n        ]);\n\n        match cli.command {\n            Commands::Generate { command } => {\n                smol::block_on(run_generate_command(command, cli.verbose)).unwrap();\n            }\n            _ => unreachable!(),\n        }\n    }\n\n    #[test]\n    #[should_panic(\n        expected = \"There is no database name as part of the url path: postgresql://root:root@localhost:3306\"\n    )]\n    fn test_generate_entity_no_database_section() {\n        let cli = Cli::parse_from([\n            \"sea-orm-cli\",\n            \"generate\",\n            \"entity\",\n            \"--database-url\",\n            \"postgresql://root:root@localhost:3306\",\n        ]);\n\n        match cli.command {\n            Commands::Generate { command } => {\n                smol::block_on(run_generate_command(command, cli.verbose)).unwrap();\n            }\n            _ => unreachable!(),\n        }\n    }\n\n    #[test]\n    #[should_panic(\n        expected = \"There is no database name as part of the url path: mysql://root:root@localhost:3306/\"\n    )]\n    fn test_generate_entity_no_database_path() {\n        let cli = Cli::parse_from([\n            \"sea-orm-cli\",\n            \"generate\",\n            \"entity\",\n            \"--database-url\",\n            \"mysql://root:root@localhost:3306/\",\n        ]);\n\n        match cli.command {\n            Commands::Generate { command } => {\n                smol::block_on(run_generate_command(command, cli.verbose)).unwrap();\n            }\n            _ => unreachable!(),\n        }\n    }\n\n    #[test]\n    #[should_panic(expected = \"called `Result::unwrap()` on an `Err` value: EmptyHost\")]\n    fn test_generate_entity_no_host() {\n        let cli = Cli::parse_from([\n            \"sea-orm-cli\",\n            \"generate\",\n            \"entity\",\n            \"--database-url\",\n            \"postgres://root:root@/database\",\n        ]);\n\n        match cli.command {\n            Commands::Generate { command } => {\n                smol::block_on(run_generate_command(command, cli.verbose)).unwrap();\n            }\n            _ => unreachable!(),\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-cli/src/commands/migrate.rs",
    "content": "use chrono::{Local, Utc};\nuse regex::Regex;\nuse std::{\n    error::Error,\n    fmt::Display,\n    fs,\n    io::Write,\n    path::{Path, PathBuf},\n    process::Command,\n};\n\n#[cfg(feature = \"cli\")]\nuse crate::MigrateSubcommands;\n\n#[cfg(feature = \"cli\")]\npub fn run_migrate_command(\n    command: Option<MigrateSubcommands>,\n    migration_dir: &str,\n    database_schema: Option<String>,\n    database_url: Option<String>,\n    verbose: bool,\n) -> Result<(), Box<dyn Error>> {\n    match command {\n        Some(MigrateSubcommands::Init) => run_migrate_init(migration_dir)?,\n        Some(MigrateSubcommands::Generate {\n            migration_name,\n            universal_time: _,\n            local_time,\n        }) => run_migrate_generate(migration_dir, &migration_name, !local_time)?,\n        _ => {\n            let (subcommand, migration_dir, steps, verbose) = match command {\n                Some(MigrateSubcommands::Fresh) => (\"fresh\", migration_dir, None, verbose),\n                Some(MigrateSubcommands::Refresh) => (\"refresh\", migration_dir, None, verbose),\n                Some(MigrateSubcommands::Reset) => (\"reset\", migration_dir, None, verbose),\n                Some(MigrateSubcommands::Status) => (\"status\", migration_dir, None, verbose),\n                Some(MigrateSubcommands::Up { num }) => (\"up\", migration_dir, num, verbose),\n                Some(MigrateSubcommands::Down { num }) => {\n                    (\"down\", migration_dir, Some(num), verbose)\n                }\n                _ => (\"up\", migration_dir, None, verbose),\n            };\n\n            // Construct the `--manifest-path`\n            let manifest_path = if migration_dir.ends_with('/') {\n                format!(\"{migration_dir}Cargo.toml\")\n            } else {\n                format!(\"{migration_dir}/Cargo.toml\")\n            };\n            // Construct the arguments that will be supplied to `cargo` command\n            let mut args = vec![\"run\", \"--manifest-path\", &manifest_path, \"--\", subcommand];\n            let mut envs = vec![];\n\n            let mut num: String = \"\".to_string();\n            if let Some(steps) = steps {\n                num = steps.to_string();\n            }\n            if !num.is_empty() {\n                args.extend([\"-n\", &num])\n            }\n            if let Some(database_url) = &database_url {\n                envs.push((\"DATABASE_URL\", database_url));\n            }\n            if let Some(database_schema) = &database_schema {\n                envs.push((\"DATABASE_SCHEMA\", database_schema));\n            }\n            if verbose {\n                args.push(\"-v\");\n            }\n            // Run migrator CLI on user's behalf\n            println!(\"Running `cargo {}`\", args.join(\" \"));\n            let exit_status = Command::new(\"cargo\").args(args).envs(envs).status()?; // Get the status code\n            if !exit_status.success() {\n                // Propagate the error if any\n                return Err(\"Fail to run migration\".into());\n            }\n        }\n    }\n\n    Ok(())\n}\n\npub fn run_migrate_init(migration_dir: &str) -> Result<(), Box<dyn Error>> {\n    let migration_dir = match migration_dir.ends_with('/') {\n        true => migration_dir.to_string(),\n        false => format!(\"{migration_dir}/\"),\n    };\n    println!(\"Initializing migration directory...\");\n    macro_rules! write_file {\n        ($filename: literal) => {\n            let fn_content = |content: String| content;\n            write_file!($filename, $filename, fn_content);\n        };\n        ($filename: literal, $template: literal) => {\n            let fn_content = |content: String| content;\n            write_file!($filename, $template, fn_content);\n        };\n        ($filename: literal, $template: literal, $fn_content: expr) => {\n            let filepath = [&migration_dir, $filename].join(\"\");\n            println!(\"Creating file `{}`\", filepath);\n            let path = Path::new(&filepath);\n            let prefix = path.parent().unwrap();\n            fs::create_dir_all(prefix).unwrap();\n            let mut file = fs::File::create(path)?;\n            let content = include_str!(concat!(\"../../template/migration/\", $template));\n            let content = $fn_content(content.to_string());\n            file.write_all(content.as_bytes())?;\n        };\n    }\n    write_file!(\"src/lib.rs\");\n    write_file!(\"src/m20220101_000001_create_table.rs\");\n    write_file!(\"src/main.rs\");\n    write_file!(\"Cargo.toml\", \"_Cargo.toml\", |content: String| {\n        let ver = format!(\n            \"{}.{}.0\",\n            env!(\"CARGO_PKG_VERSION_MAJOR\"),\n            env!(\"CARGO_PKG_VERSION_MINOR\")\n        );\n        content.replace(\"<sea-orm-migration-version>\", &ver)\n    });\n    write_file!(\"README.md\");\n    if glob::glob(&format!(\"{migration_dir}**/.git\"))?.count() > 0 {\n        write_file!(\".gitignore\", \"_gitignore\");\n    }\n    println!(\"Done!\");\n\n    Ok(())\n}\n\npub fn run_migrate_generate(\n    migration_dir: &str,\n    migration_name: &str,\n    universal_time: bool,\n) -> Result<(), Box<dyn Error>> {\n    // Make sure the migration name doesn't contain any characters that\n    // are invalid module names in Rust.\n    if migration_name.contains('-') {\n        return Err(Box::new(MigrationCommandError::InvalidName(\n            \"Hyphen `-` cannot be used in migration name\".to_string(),\n        )));\n    }\n\n    println!(\"Generating new migration...\");\n\n    // build new migration filename\n    const FMT: &str = \"%Y%m%d_%H%M%S\";\n    let formatted_now = if universal_time {\n        Utc::now().format(FMT)\n    } else {\n        Local::now().format(FMT)\n    };\n\n    let migration_name = migration_name.trim().replace(' ', \"_\");\n    let migration_name = format!(\"m{formatted_now}_{migration_name}\");\n\n    create_new_migration(&migration_name, migration_dir)?;\n    update_migrator(&migration_name, migration_dir)?;\n\n    Ok(())\n}\n\n/// `get_full_migration_dir` looks for a `src` directory\n/// inside of `migration_dir` and appends that to the returned path if found.\n///\n/// Otherwise, `migration_dir` can point directly to a directory containing the\n/// migrations. In that case, nothing is appended.\n///\n/// This way, `src` doesn't need to be appended in the standard case where\n/// migrations are in their own crate. If the migrations are in a submodule\n/// of another crate, `migration_dir` can point directly to that module.\nfn get_full_migration_dir(migration_dir: &str) -> PathBuf {\n    let without_src = Path::new(migration_dir).to_owned();\n    let with_src = without_src.join(\"src\");\n    match () {\n        _ if with_src.is_dir() => with_src,\n        _ => without_src,\n    }\n}\n\nfn create_new_migration(migration_name: &str, migration_dir: &str) -> Result<(), Box<dyn Error>> {\n    let migration_filepath =\n        get_full_migration_dir(migration_dir).join(format!(\"{}.rs\", &migration_name));\n    println!(\"Creating migration file `{}`\", migration_filepath.display());\n    // TODO: make OS agnostic\n    let migration_template =\n        include_str!(\"../../template/migration/src/m20220101_000001_create_table.rs\");\n    let mut migration_file = fs::File::create(migration_filepath)?;\n    migration_file.write_all(migration_template.as_bytes())?;\n    Ok(())\n}\n\n/// `get_migrator_filepath` looks for a file `migration_dir/src/lib.rs`\n/// and returns that path if found.\n///\n/// If `src` is not found, it will look directly in `migration_dir` for `lib.rs`.\n///\n/// If `lib.rs` is not found, it will look for `mod.rs` instead,\n/// e.g. `migration_dir/mod.rs`.\n///\n/// This way, `src` doesn't need to be appended in the standard case where\n/// migrations are in their own crate (with a file `lib.rs`). If the\n/// migrations are in a submodule of another crate (with a file `mod.rs`),\n/// `migration_dir` can point directly to that module.\nfn get_migrator_filepath(migration_dir: &str) -> PathBuf {\n    let full_migration_dir = get_full_migration_dir(migration_dir);\n    let with_lib = full_migration_dir.join(\"lib.rs\");\n    match () {\n        _ if with_lib.is_file() => with_lib,\n        _ => full_migration_dir.join(\"mod.rs\"),\n    }\n}\n\nfn update_migrator(migration_name: &str, migration_dir: &str) -> Result<(), Box<dyn Error>> {\n    let migrator_filepath = get_migrator_filepath(migration_dir);\n    println!(\n        \"Adding migration `{}` to `{}`\",\n        migration_name,\n        migrator_filepath.display()\n    );\n    let migrator_content = fs::read_to_string(&migrator_filepath)?;\n    let mut updated_migrator_content = migrator_content.clone();\n\n    // create a backup of the migrator file in case something goes wrong\n    let migrator_backup_filepath = migrator_filepath.with_extension(\"rs.bak\");\n    fs::copy(&migrator_filepath, &migrator_backup_filepath)?;\n    let mut migrator_file = fs::File::create(&migrator_filepath)?;\n\n    // find existing mod declarations, add new line\n    let mod_regex = Regex::new(r\"mod\\s+(?P<name>m\\d{8}_\\d{6}_\\w+);\")?;\n    let mods: Vec<_> = mod_regex.captures_iter(&migrator_content).collect();\n    let mods_end = if let Some(last_match) = mods.last() {\n        last_match.get(0).unwrap().end() + 1\n    } else {\n        migrator_content.len()\n    };\n    updated_migrator_content.insert_str(mods_end, format!(\"mod {migration_name};\\n\").as_str());\n\n    // build new vector from declared migration modules\n    let mut migrations: Vec<&str> = mods\n        .iter()\n        .map(|cap| cap.name(\"name\").unwrap().as_str())\n        .collect();\n    migrations.push(migration_name);\n    let mut boxed_migrations = migrations\n        .iter()\n        .map(|migration| format!(\"            Box::new({migration}::Migration),\"))\n        .collect::<Vec<String>>()\n        .join(\"\\n\");\n    boxed_migrations.push('\\n');\n    let boxed_migrations = format!(\"vec![\\n{boxed_migrations}        ]\\n\");\n    let vec_regex = Regex::new(r\"vec!\\[[\\s\\S]+\\]\\n\")?;\n    let updated_migrator_content = vec_regex.replace(&updated_migrator_content, &boxed_migrations);\n\n    migrator_file.write_all(updated_migrator_content.as_bytes())?;\n    fs::remove_file(&migrator_backup_filepath)?;\n    Ok(())\n}\n\n#[derive(Debug)]\nenum MigrationCommandError {\n    InvalidName(String),\n}\n\nimpl Display for MigrationCommandError {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            MigrationCommandError::InvalidName(name) => {\n                write!(f, \"Invalid migration name: {name}\")\n            }\n        }\n    }\n}\n\nimpl Error for MigrationCommandError {}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_create_new_migration() {\n        let migration_name = \"test_name\";\n        let migration_dir = \"/tmp/sea_orm_cli_test_new_migration/\";\n        fs::create_dir_all(format!(\"{migration_dir}src\")).unwrap();\n        create_new_migration(migration_name, migration_dir).unwrap();\n        let migration_filepath = Path::new(migration_dir)\n            .join(\"src\")\n            .join(format!(\"{migration_name}.rs\"));\n        assert!(migration_filepath.exists());\n        let migration_content = fs::read_to_string(migration_filepath).unwrap();\n        assert_eq!(\n            &migration_content,\n            include_str!(\"../../template/migration/src/m20220101_000001_create_table.rs\")\n        );\n        fs::remove_dir_all(\"/tmp/sea_orm_cli_test_new_migration/\").unwrap();\n    }\n\n    #[test]\n    fn test_update_migrator() {\n        let migration_name = \"test_name\";\n        let migration_dir = \"/tmp/sea_orm_cli_test_update_migrator/\";\n        fs::create_dir_all(format!(\"{migration_dir}src\")).unwrap();\n        let migrator_filepath = Path::new(migration_dir).join(\"src\").join(\"lib.rs\");\n        fs::copy(\"./template/migration/src/lib.rs\", &migrator_filepath).unwrap();\n        update_migrator(migration_name, migration_dir).unwrap();\n        assert!(&migrator_filepath.exists());\n        let migrator_content = fs::read_to_string(&migrator_filepath).unwrap();\n        let mod_regex = Regex::new(r\"mod (?P<name>\\w+);\").unwrap();\n        let migrations: Vec<&str> = mod_regex\n            .captures_iter(&migrator_content)\n            .map(|cap| cap.name(\"name\").unwrap().as_str())\n            .collect();\n        assert_eq!(migrations.len(), 2);\n        assert_eq!(\n            *migrations.first().unwrap(),\n            \"m20220101_000001_create_table\"\n        );\n        assert_eq!(migrations.last().unwrap(), &migration_name);\n        let boxed_regex = Regex::new(r\"Box::new\\((?P<name>\\S+)::Migration\\)\").unwrap();\n        let migrations: Vec<&str> = boxed_regex\n            .captures_iter(&migrator_content)\n            .map(|cap| cap.name(\"name\").unwrap().as_str())\n            .collect();\n        assert_eq!(migrations.len(), 2);\n        assert_eq!(\n            *migrations.first().unwrap(),\n            \"m20220101_000001_create_table\"\n        );\n        assert_eq!(migrations.last().unwrap(), &migration_name);\n        fs::remove_dir_all(\"/tmp/sea_orm_cli_test_update_migrator/\").unwrap();\n    }\n}\n"
  },
  {
    "path": "sea-orm-cli/src/commands/mod.rs",
    "content": "use std::fmt::Display;\n\n#[cfg(feature = \"codegen\")]\npub mod generate;\npub mod migrate;\n\n#[cfg(feature = \"codegen\")]\npub use generate::*;\npub use migrate::*;\n\npub fn handle_error<E>(error: E)\nwhere\n    E: Display,\n{\n    eprintln!(\"{error}\");\n    ::std::process::exit(1);\n}\n"
  },
  {
    "path": "sea-orm-cli/src/lib.rs",
    "content": "#[cfg(feature = \"cli\")]\npub mod cli;\npub mod commands;\n\n#[cfg(feature = \"cli\")]\npub use cli::*;\npub use commands::*;\n"
  },
  {
    "path": "sea-orm-cli/template/migration/README.md",
    "content": "# Running Migrator CLI\n\n- Generate a new migration file\n    ```sh\n    cargo run -- generate MIGRATION_NAME\n    ```\n- Apply all pending migrations\n    ```sh\n    cargo run\n    ```\n    ```sh\n    cargo run -- up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- status\n    ```\n"
  },
  {
    "path": "sea-orm-cli/template/migration/_Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"migration\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[lib]\nname = \"migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\ntokio = { version = \"1\", features = [\"macros\", \"rt\", \"rt-multi-thread\"] }\n\n[dependencies.sea-orm-migration]\nfeatures = [\n    # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI.\n    # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime.\n    # e.g.\n    # \"runtime-tokio-rustls\",  # `ASYNC_RUNTIME` feature\n    # \"sqlx-postgres\",         # `DATABASE_DRIVER` feature\n]\nversion = \"<sea-orm-migration-version>\"\n"
  },
  {
    "path": "sea-orm-cli/template/migration/_gitignore",
    "content": "/target"
  },
  {
    "path": "sea-orm-cli/template/migration/src/lib.rs",
    "content": "pub use sea_orm_migration::prelude::*;\n\nmod m20220101_000001_create_table;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![Box::new(m20220101_000001_create_table::Migration)]\n    }\n}\n"
  },
  {
    "path": "sea-orm-cli/template/migration/src/m20220101_000001_create_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        // Replace the sample below with your own migration scripts\n        todo!();\n\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"post\")\n                    .if_not_exists()\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"title\"))\n                    .col(string(\"text\"))\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        // Replace the sample below with your own migration scripts\n        todo!();\n\n        manager\n            .drop_table(Table::drop().table(\"post\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "sea-orm-cli/template/migration/src/main.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[tokio::main]\nasync fn main() {\n    cli::run_cli(migration::Migrator).await;\n}\n"
  },
  {
    "path": "sea-orm-codegen/Cargo.toml",
    "content": "[package]\nauthors       = [\"Billy Chan <ccw.billy.123@gmail.com>\"]\ncategories    = [\"database\"]\ndescription   = \"Code Generator for SeaORM\"\ndocumentation = \"https://docs.rs/sea-orm\"\nedition       = \"2024\"\nhomepage      = \"https://www.sea-ql.org/SeaORM\"\nkeywords      = [\"sql\", \"mysql\", \"postgres\", \"sqlite\"]\nlicense       = \"MIT OR Apache-2.0\"\nname          = \"sea-orm-codegen\"\nrepository    = \"https://github.com/SeaQL/sea-orm\"\nrust-version  = \"1.85.0\"\nversion       = \"2.0.0-rc.37\"\n\n[lib]\nname = \"sea_orm_codegen\"\npath = \"src/lib.rs\"\n\n[dependencies]\nheck = { version = \"0.5\", default-features = false }\npluralizer = { version = \"0.5\" }\nprettyplease = { version = \"0.2\", default-features = false, features = [\n    \"verbatim\",\n] }\nproc-macro2 = { version = \"1\", default-features = false }\nquote = { version = \"1\", default-features = false }\nsea-query = { version = \"1.0.0-rc.1\", default-features = false, features = [\n    \"thread-safe\",\n] }\nsyn = { version = \"2\", default-features = false, features = [\n    \"parsing\",\n    \"proc-macro\",\n    \"derive\",\n    \"printing\",\n    \"clone-impls\",\n    \"extra-traits\",\n    \"full\",\n    \"visit\",\n    \"visit-mut\",\n    \"fold\",\n] }\ntracing = { version = \"0.1\", default-features = false, features = [\"log\"] }\n\n[dev-dependencies]\nindoc             = \"2.0.6\"\npretty_assertions = { version = \"0.7\" }\nsea-orm           = { path = \"../\", default-features = false, features = [\"macros\"] }\n"
  },
  {
    "path": "sea-orm-codegen/README.md",
    "content": "# SeaORM Codegen\n"
  },
  {
    "path": "sea-orm-codegen/rustfmt.toml",
    "content": "ignore = [\n    \"tests/compact/*.rs\",\n    \"tests/expanded/*.rs\",\n    \"tests_cfg\",\n]\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/active_enum.rs",
    "content": "use heck::ToUpperCamelCase;\nuse proc_macro2::TokenStream;\nuse quote::{format_ident, quote};\nuse sea_query::DynIden;\n\nuse crate::{EntityFormat, WithSerde};\n\n#[derive(Clone, Debug)]\npub struct ActiveEnum {\n    pub(crate) enum_name: DynIden,\n    pub(crate) values: Vec<DynIden>,\n}\n\nimpl ActiveEnum {\n    pub fn impl_active_enum(\n        &self,\n        with_serde: &WithSerde,\n        with_copy_enums: bool,\n        extra_derives: &TokenStream,\n        extra_attributes: &TokenStream,\n        entity_format: EntityFormat,\n    ) -> TokenStream {\n        let enum_name = &self.enum_name.to_string();\n        let enum_iden = format_ident!(\"{}\", enum_name.to_upper_camel_case());\n        let values: Vec<String> = self.values.iter().map(|v| v.to_string()).collect();\n\n        let variants = values.iter().map(|v| v.trim()).map(|v| {\n            if v.is_empty() {\n                println!(\"Warning: item in the enumeration '{enum_name}' is an empty string, it will be converted to `__EmptyString`. You can modify it later as needed.\");\n                return format_ident!(\"__EmptyString\");\n            }\n\n            let is_leading_digit = v.chars().next().is_some_and(|c| c.is_ascii_digit());\n            let is_valid_char = |c: char| c.is_ascii_alphanumeric() || c == '_';\n            let is_passthrough = |c: char| matches!(c, '-' | ' ');\n            let needs_utf8_escape = |c: char| !is_valid_char(c) && !is_passthrough(c);\n\n            if v.chars().any(needs_utf8_escape) {\n                println!(\"Warning: item '{v}' in the enumeration '{enum_name}' cannot be converted into a valid Rust enum member name. It will be converted to its corresponding UTF-8 encoding. You can modify it later as needed.\");\n\n                let mut buf = String::new();\n\n                if is_leading_digit {\n                    buf.push('_');\n                }\n\n                for c in v.chars() {\n                    if is_passthrough(c) {\n                        continue;\n                    } else if is_valid_char(c) || c.len_utf8() > 1 {\n                        buf.push(c);\n                    } else {\n                        buf.push_str(&format!(\"U{:04X}\", c as u32));\n                    }\n                }\n\n                return format_ident!(\"{buf}\");\n            }\n\n            if is_leading_digit {\n                let sanitized = v.chars().filter(|&c| is_valid_char(c)).collect::<String>();\n                format_ident!(\"_{sanitized}\")\n            } else {\n                format_ident!(\"{}\", v.to_upper_camel_case())\n            }\n        });\n\n        let serde_derive = with_serde.extra_derive();\n        let copy_derive = if with_copy_enums {\n            quote! { , Copy }\n        } else {\n            quote! {}\n        };\n\n        if entity_format == EntityFormat::Frontend {\n            quote! {\n                #[derive(Debug, Clone, PartialEq, Eq #copy_derive #serde_derive #extra_derives)]\n                #extra_attributes\n                pub enum #enum_iden {\n                    #(\n                        #variants,\n                    )*\n                }\n            }\n        } else {\n            quote! {\n                #[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum #copy_derive #serde_derive #extra_derives)]\n                #[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = #enum_name)]\n                #extra_attributes\n                pub enum #enum_iden {\n                    #(\n                        #[sea_orm(string_value = #values)]\n                        #variants,\n                    )*\n                }\n            }\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::entity::writer::{bonus_attributes, bonus_derive};\n    use pretty_assertions::assert_eq;\n    use sea_query::{Alias, IntoIden};\n\n    #[test]\n    fn test_enum_variant_starts_with_empty_string() {\n        assert_eq!(\n            ActiveEnum {\n                enum_name: Alias::new(\"media_type\").into_iden(),\n                values: vec![\"\"]\n                    .into_iter()\n                    .map(|variant| Alias::new(variant).into_iden())\n                    .collect(),\n            }\n            .impl_active_enum(\n                &WithSerde::None,\n                true,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                EntityFormat::Compact,\n            )\n            .to_string(),\n            quote!(\n                #[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Copy)]\n                #[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"media_type\")]\n                pub enum MediaType {\n                    #[sea_orm(string_value = \"\")]\n                    __EmptyString,\n                }\n            )\n            .to_string()\n        )\n    }\n\n    #[test]\n    fn test_enum_variant_starts_with_number() {\n        assert_eq!(\n            ActiveEnum {\n                enum_name: Alias::new(\"media_type\").into_iden(),\n                values: vec![\n                    \"UNKNOWN\",\n                    \"BITMAP\",\n                    \"DRAWING\",\n                    \"AUDIO\",\n                    \"VIDEO\",\n                    \"MULTIMEDIA\",\n                    \"OFFICE\",\n                    \"TEXT\",\n                    \"EXECUTABLE\",\n                    \"ARCHIVE\",\n                    \"3D\",\n                    \"2-D\"\n                ]\n                .into_iter()\n                .map(|variant| Alias::new(variant).into_iden())\n                .collect(),\n            }\n            .impl_active_enum(\n                &WithSerde::None,\n                true,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                EntityFormat::Compact,\n            )\n            .to_string(),\n            quote!(\n                #[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Copy)]\n                #[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"media_type\")]\n                pub enum MediaType {\n                    #[sea_orm(string_value = \"UNKNOWN\")]\n                    Unknown,\n                    #[sea_orm(string_value = \"BITMAP\")]\n                    Bitmap,\n                    #[sea_orm(string_value = \"DRAWING\")]\n                    Drawing,\n                    #[sea_orm(string_value = \"AUDIO\")]\n                    Audio,\n                    #[sea_orm(string_value = \"VIDEO\")]\n                    Video,\n                    #[sea_orm(string_value = \"MULTIMEDIA\")]\n                    Multimedia,\n                    #[sea_orm(string_value = \"OFFICE\")]\n                    Office,\n                    #[sea_orm(string_value = \"TEXT\")]\n                    Text,\n                    #[sea_orm(string_value = \"EXECUTABLE\")]\n                    Executable,\n                    #[sea_orm(string_value = \"ARCHIVE\")]\n                    Archive,\n                    #[sea_orm(string_value = \"3D\")]\n                    _3D,\n                    #[sea_orm(string_value = \"2-D\")]\n                    _2D,\n                }\n            )\n            .to_string()\n        )\n    }\n\n    #[test]\n    fn test_enum_extra_derives() {\n        assert_eq!(\n            ActiveEnum {\n                enum_name: Alias::new(\"media_type\").into_iden(),\n                values: vec![\"UNKNOWN\", \"BITMAP\",]\n                    .into_iter()\n                    .map(|variant| Alias::new(variant).into_iden())\n                    .collect(),\n            }\n            .impl_active_enum(\n                &WithSerde::None,\n                true,\n                &bonus_derive([\"specta::Type\", \"ts_rs::TS\"]),\n                &TokenStream::new(),\n                EntityFormat::Compact,\n            )\n            .to_string(),\n            build_generated_enum(),\n        );\n\n        #[rustfmt::skip]\n        fn build_generated_enum() -> String {\n            quote!(\n                #[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Copy, specta :: Type, ts_rs :: TS)]\n                #[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"media_type\")]\n                pub enum MediaType {\n                    #[sea_orm(string_value = \"UNKNOWN\")]\n                    Unknown,\n                    #[sea_orm(string_value = \"BITMAP\")]\n                    Bitmap,\n                }\n            )\n            .to_string()\n        }\n    }\n\n    #[test]\n    fn test_enum_extra_attributes() {\n        assert_eq!(\n            ActiveEnum {\n                enum_name: Alias::new(\"coinflip_result_type\").into_iden(),\n                values: vec![\"HEADS\", \"TAILS\"]\n                    .into_iter()\n                    .map(|variant| Alias::new(variant).into_iden())\n                    .collect(),\n            }\n            .impl_active_enum(\n                &WithSerde::None,\n                true,\n                &TokenStream::new(),\n                &bonus_attributes([r#\"serde(rename_all = \"camelCase\")\"#]),\n                EntityFormat::Compact,\n            )\n            .to_string(),\n            quote!(\n                #[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Copy)]\n                #[sea_orm(\n                    rs_type = \"String\",\n                    db_type = \"Enum\",\n                    enum_name = \"coinflip_result_type\"\n                )]\n                #[serde(rename_all = \"camelCase\")]\n                pub enum CoinflipResultType {\n                    #[sea_orm(string_value = \"HEADS\")]\n                    Heads,\n                    #[sea_orm(string_value = \"TAILS\")]\n                    Tails,\n                }\n            )\n            .to_string()\n        );\n        assert_eq!(\n            ActiveEnum {\n                enum_name: Alias::new(\"coinflip_result_type\").into_iden(),\n                values: vec![\"HEADS\", \"TAILS\"]\n                    .into_iter()\n                    .map(|variant| Alias::new(variant).into_iden())\n                    .collect(),\n            }\n            .impl_active_enum(\n                &WithSerde::None,\n                true,\n                &TokenStream::new(),\n                &bonus_attributes([r#\"serde(rename_all = \"camelCase\")\"#, \"ts(export)\"]),\n                EntityFormat::Compact,\n            )\n            .to_string(),\n            quote!(\n                #[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Copy)]\n                #[sea_orm(\n                    rs_type = \"String\",\n                    db_type = \"Enum\",\n                    enum_name = \"coinflip_result_type\"\n                )]\n                #[serde(rename_all = \"camelCase\")]\n                #[ts(export)]\n                pub enum CoinflipResultType {\n                    #[sea_orm(string_value = \"HEADS\")]\n                    Heads,\n                    #[sea_orm(string_value = \"TAILS\")]\n                    Tails,\n                }\n            )\n            .to_string()\n        )\n    }\n\n    #[test]\n    fn test_enum_variant_utf8_encode() {\n        assert_eq!(\n            ActiveEnum {\n                enum_name: Alias::new(\"ty\").into_iden(),\n                values: vec![\n                    \"Question\",\n                    \"QuestionsAdditional\",\n                    \"Answer\",\n                    \"Other\",\n                    \"/\",\n                    \"//\",\n                    \"A-B-C\",\n                    \"你好\",\n                    \"0/\",\n                    \"0//\",\n                    \"0A-B-C\",\n                    \"0你好\",\n                ]\n                .into_iter()\n                .map(|variant| Alias::new(variant).into_iden())\n                .collect(),\n            }\n            .impl_active_enum(\n                &WithSerde::None,\n                true,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                EntityFormat::Compact,\n            )\n            .to_string(),\n            quote!(\n                #[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Copy)]\n                #[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"ty\")]\n                pub enum Ty {\n                    #[sea_orm(string_value = \"Question\")]\n                    Question,\n                    #[sea_orm(string_value = \"QuestionsAdditional\")]\n                    QuestionsAdditional,\n                    #[sea_orm(string_value = \"Answer\")]\n                    Answer,\n                    #[sea_orm(string_value = \"Other\")]\n                    Other,\n                    #[sea_orm(string_value = \"/\")]\n                    U002F,\n                    #[sea_orm(string_value = \"//\")]\n                    U002FU002F,\n                    #[sea_orm(string_value = \"A-B-C\")]\n                    ABC,\n                    #[sea_orm(string_value = \"你好\")]\n                    你好,\n                    #[sea_orm(string_value = \"0/\")]\n                    _0U002F,\n                    #[sea_orm(string_value = \"0//\")]\n                    _0U002FU002F,\n                    #[sea_orm(string_value = \"0A-B-C\")]\n                    _0ABC,\n                    #[sea_orm(string_value = \"0你好\")]\n                    _0你好,\n                }\n            )\n            .to_string()\n        )\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/base_entity.rs",
    "content": "use heck::{ToSnakeCase, ToUpperCamelCase};\nuse proc_macro2::{Ident, TokenStream};\nuse quote::format_ident;\nuse quote::quote;\nuse sea_query::ColumnType;\n\nuse crate::{\n    Column, ColumnOption, ConjunctRelation, PrimaryKey, Relation, util::escape_rust_keyword,\n};\n\n#[derive(Clone, Debug)]\npub struct Entity {\n    pub(crate) table_name: String,\n    pub(crate) columns: Vec<Column>,\n    pub(crate) relations: Vec<Relation>,\n    pub(crate) conjunct_relations: Vec<ConjunctRelation>,\n    pub(crate) primary_keys: Vec<PrimaryKey>,\n}\n\nimpl Entity {\n    pub fn get_table_name_snake_case(&self) -> String {\n        self.table_name.to_snake_case()\n    }\n\n    pub fn get_table_name_camel_case(&self) -> String {\n        self.table_name.to_upper_camel_case()\n    }\n\n    pub fn get_table_name_snake_case_ident(&self) -> Ident {\n        format_ident!(\"{}\", escape_rust_keyword(self.get_table_name_snake_case()))\n    }\n\n    pub fn get_table_name_camel_case_ident(&self) -> Ident {\n        format_ident!(\"{}\", escape_rust_keyword(self.get_table_name_camel_case()))\n    }\n\n    pub fn get_column_names_snake_case(&self) -> Vec<Ident> {\n        self.columns\n            .iter()\n            .map(|col| col.get_name_snake_case())\n            .collect()\n    }\n\n    pub fn get_column_names_camel_case(&self) -> Vec<Ident> {\n        self.columns\n            .iter()\n            .map(|col| col.get_name_camel_case())\n            .collect()\n    }\n\n    pub fn get_column_rs_types(&self, opt: &ColumnOption) -> Vec<TokenStream> {\n        self.columns\n            .clone()\n            .into_iter()\n            .map(|col| col.get_rs_type(opt))\n            .collect()\n    }\n\n    pub fn get_column_defs(&self) -> Vec<TokenStream> {\n        self.columns\n            .clone()\n            .into_iter()\n            .map(|col| col.get_def())\n            .collect()\n    }\n\n    pub fn get_primary_key_names_snake_case(&self) -> Vec<Ident> {\n        self.primary_keys\n            .iter()\n            .map(|pk| pk.get_name_snake_case())\n            .collect()\n    }\n\n    pub fn get_primary_key_names_camel_case(&self) -> Vec<Ident> {\n        self.primary_keys\n            .iter()\n            .map(|pk| pk.get_name_camel_case())\n            .collect()\n    }\n\n    pub fn get_relation_module_name(&self) -> Vec<Option<Ident>> {\n        self.relations\n            .iter()\n            .map(|rel| rel.get_module_name())\n            .collect()\n    }\n\n    pub fn get_relation_enum_name(&self) -> Vec<Ident> {\n        self.relations\n            .iter()\n            .map(|rel| rel.get_enum_name())\n            .collect()\n    }\n\n    /// Used to generate the names for the `enum RelatedEntity` that is useful to the Seaography project\n    pub fn get_related_entity_enum_name(&self) -> Vec<Ident> {\n        // 1st step get conjunct relations data\n        let conjunct_related_names = self.get_conjunct_relations_to_upper_camel_case();\n\n        // 2nd step get reverse self relations data\n        let self_relations_reverse = self\n            .relations\n            .iter()\n            .filter(|rel| rel.self_referencing)\n            .map(|rel| format_ident!(\"{}Reverse\", rel.get_enum_name()));\n\n        // 3rd step get normal relations data\n        self.get_relation_enum_name()\n            .into_iter()\n            .chain(self_relations_reverse)\n            .chain(conjunct_related_names)\n            .collect()\n    }\n\n    pub fn get_relation_defs(&self) -> Vec<TokenStream> {\n        self.relations.iter().map(|rel| rel.get_def()).collect()\n    }\n\n    pub fn get_relation_attrs(&self) -> Vec<TokenStream> {\n        self.relations.iter().map(|rel| rel.get_attrs()).collect()\n    }\n\n    /// Trimmed get_related_entity_attrs down to just the entity module\n    pub fn get_related_entity_modules(&self) -> Vec<Ident> {\n        // 1st step get conjunct relations data\n        let conjunct_related_attrs = self\n            .conjunct_relations\n            .iter()\n            .map(|conj| conj.get_to_snake_case());\n\n        // helper function that generates attributes for `Relation` data\n        let produce_relation_attrs = |rel: &Relation, _reverse: bool| match rel.get_module_name() {\n            Some(module_name) => module_name,\n            None => format_ident!(\"self\"),\n        };\n\n        // 2nd step get reverse self relations data\n        let self_relations_reverse_attrs = self\n            .relations\n            .iter()\n            .filter(|rel| rel.self_referencing)\n            .map(|rel| produce_relation_attrs(rel, true));\n\n        // 3rd step get normal relations data\n        self.relations\n            .iter()\n            .map(|rel| produce_relation_attrs(rel, false))\n            .chain(self_relations_reverse_attrs)\n            .chain(conjunct_related_attrs)\n            .collect()\n    }\n\n    /// Used to generate the attributes for the `enum RelatedEntity` that is useful to the Seaography project\n    pub fn get_related_entity_attrs(&self) -> Vec<TokenStream> {\n        // 1st step get conjunct relations data\n        let conjunct_related_attrs = self.conjunct_relations.iter().map(|conj| {\n            let entity = format!(\"super::{}::Entity\", conj.get_to_snake_case());\n\n            quote! {\n                #[sea_orm(\n                    entity = #entity\n                )]\n            }\n        });\n\n        // helper function that generates attributes for `Relation` data\n        let produce_relation_attrs = |rel: &Relation, reverse: bool| {\n            let entity = match rel.get_module_name() {\n                Some(module_name) => format!(\"super::{module_name}::Entity\"),\n                None => String::from(\"Entity\"),\n            };\n\n            if rel.self_referencing || !rel.impl_related || rel.num_suffix > 0 {\n                let def = if reverse {\n                    format!(\"Relation::{}.def().rev()\", rel.get_enum_name())\n                } else {\n                    format!(\"Relation::{}.def()\", rel.get_enum_name())\n                };\n\n                quote! {\n                    #[sea_orm(\n                        entity = #entity,\n                        def = #def\n                    )]\n                }\n            } else {\n                quote! {\n                    #[sea_orm(\n                        entity = #entity\n                    )]\n                }\n            }\n        };\n\n        // 2nd step get reverse self relations data\n        let self_relations_reverse_attrs = self\n            .relations\n            .iter()\n            .filter(|rel| rel.self_referencing)\n            .map(|rel| produce_relation_attrs(rel, true));\n\n        // 3rd step get normal relations data\n        self.relations\n            .iter()\n            .map(|rel| produce_relation_attrs(rel, false))\n            .chain(self_relations_reverse_attrs)\n            .chain(conjunct_related_attrs)\n            .collect()\n    }\n\n    pub fn get_primary_key_auto_increment(&self) -> Ident {\n        let auto_increment = self.columns.iter().any(|col| col.auto_increment);\n        format_ident!(\"{}\", auto_increment)\n    }\n\n    pub fn get_primary_key_rs_type(&self, opt: &ColumnOption) -> TokenStream {\n        let types = self\n            .primary_keys\n            .iter()\n            .map(|primary_key| {\n                self.columns\n                    .iter()\n                    .find(|col| col.name.eq(&primary_key.name))\n                    .unwrap()\n                    .get_rs_type(opt)\n                    .to_string()\n            })\n            .collect::<Vec<_>>();\n        if !types.is_empty() {\n            let value_type = if types.len() > 1 {\n                vec![\"(\".to_owned(), types.join(\", \"), \")\".to_owned()]\n            } else {\n                types\n            };\n            value_type.join(\"\").parse().unwrap()\n        } else {\n            TokenStream::new()\n        }\n    }\n\n    pub fn get_conjunct_relations_via_snake_case(&self) -> Vec<Ident> {\n        self.conjunct_relations\n            .iter()\n            .map(|con_rel| con_rel.get_via_snake_case())\n            .collect()\n    }\n\n    pub fn get_conjunct_relations_to_snake_case(&self) -> Vec<Ident> {\n        self.conjunct_relations\n            .iter()\n            .map(|con_rel| con_rel.get_to_snake_case())\n            .collect()\n    }\n\n    pub fn get_conjunct_relations_to_upper_camel_case(&self) -> Vec<Ident> {\n        self.conjunct_relations\n            .iter()\n            .map(|con_rel| con_rel.get_to_upper_camel_case())\n            .collect()\n    }\n\n    pub fn get_eq_needed(&self) -> TokenStream {\n        fn is_floats(col_type: &ColumnType) -> bool {\n            match col_type {\n                ColumnType::Float | ColumnType::Double => true,\n                ColumnType::Array(col_type) => is_floats(col_type),\n                ColumnType::Vector(_) => true,\n                _ => false,\n            }\n        }\n        self.columns\n            .iter()\n            .find(|column| is_floats(&column.col_type))\n            // check if float or double exist.\n            // if exist, return nothing\n            .map_or(quote! {, Eq}, |_| quote! {})\n    }\n\n    pub fn get_column_serde_attributes(\n        &self,\n        serde_skip_deserializing_primary_key: bool,\n        serde_skip_hidden_column: bool,\n    ) -> Vec<TokenStream> {\n        self.columns\n            .iter()\n            .map(|col| {\n                let is_primary_key = self.primary_keys.iter().any(|pk| pk.name == col.name);\n                col.get_serde_attribute(\n                    is_primary_key,\n                    serde_skip_deserializing_primary_key,\n                    serde_skip_hidden_column,\n                )\n            })\n            .collect()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use quote::{format_ident, quote};\n    use sea_query::{ColumnType, ForeignKeyAction, StringLen};\n\n    use crate::{Column, ColumnOption, Entity, PrimaryKey, Relation, RelationType};\n\n    fn setup() -> Entity {\n        Entity {\n            table_name: \"special_cake\".to_owned(),\n            columns: vec![\n                Column {\n                    name: \"id\".to_owned(),\n                    col_type: ColumnType::Integer,\n                    auto_increment: false,\n                    not_null: false,\n                    unique: false,\n                    unique_key: None,\n                },\n                Column {\n                    name: \"name\".to_owned(),\n                    col_type: ColumnType::String(StringLen::None),\n                    auto_increment: false,\n                    not_null: false,\n                    unique: false,\n                    unique_key: None,\n                },\n            ],\n            relations: vec![\n                Relation {\n                    ref_table: \"fruit\".to_owned(),\n                    columns: vec![\"id\".to_owned()],\n                    ref_columns: vec![\"cake_id\".to_owned()],\n                    rel_type: RelationType::HasOne,\n                    on_delete: Some(ForeignKeyAction::Cascade),\n                    on_update: Some(ForeignKeyAction::Cascade),\n                    self_referencing: false,\n                    num_suffix: 0,\n                    impl_related: true,\n                },\n                Relation {\n                    ref_table: \"filling\".to_owned(),\n                    columns: vec![\"id\".to_owned()],\n                    ref_columns: vec![\"cake_id\".to_owned()],\n                    rel_type: RelationType::HasOne,\n                    on_delete: Some(ForeignKeyAction::Cascade),\n                    on_update: Some(ForeignKeyAction::Cascade),\n                    self_referencing: false,\n                    num_suffix: 0,\n                    impl_related: true,\n                },\n            ],\n            conjunct_relations: vec![],\n            primary_keys: vec![PrimaryKey {\n                name: \"id\".to_owned(),\n            }],\n        }\n    }\n\n    #[test]\n    fn test_get_table_name_snake_case() {\n        let entity = setup();\n\n        assert_eq!(\n            entity.get_table_name_snake_case(),\n            \"special_cake\".to_owned()\n        );\n    }\n\n    #[test]\n    fn test_get_table_name_camel_case() {\n        let entity = setup();\n\n        assert_eq!(entity.get_table_name_camel_case(), \"SpecialCake\".to_owned());\n    }\n\n    #[test]\n    fn test_get_table_name_snake_case_ident() {\n        let entity = setup();\n\n        assert_eq!(\n            entity.get_table_name_snake_case_ident(),\n            format_ident!(\"{}\", \"special_cake\")\n        );\n    }\n\n    #[test]\n    fn test_get_table_name_camel_case_ident() {\n        let entity = setup();\n\n        assert_eq!(\n            entity.get_table_name_camel_case_ident(),\n            format_ident!(\"{}\", \"SpecialCake\")\n        );\n    }\n\n    #[test]\n    fn test_get_column_names_snake_case() {\n        let entity = setup();\n\n        for (i, elem) in entity.get_column_names_snake_case().into_iter().enumerate() {\n            assert_eq!(elem, entity.columns[i].get_name_snake_case());\n        }\n    }\n\n    #[test]\n    fn test_get_column_names_camel_case() {\n        let entity = setup();\n\n        for (i, elem) in entity.get_column_names_camel_case().into_iter().enumerate() {\n            assert_eq!(elem, entity.columns[i].get_name_camel_case());\n        }\n    }\n\n    #[test]\n    fn test_get_column_rs_types() {\n        let entity = setup();\n        let opt = ColumnOption::default();\n\n        for (i, elem) in entity.get_column_rs_types(&opt).into_iter().enumerate() {\n            assert_eq!(\n                elem.to_string(),\n                entity.columns[i].get_rs_type(&opt).to_string()\n            );\n        }\n    }\n\n    #[test]\n    fn test_get_column_defs() {\n        let entity = setup();\n\n        for (i, elem) in entity.get_column_defs().into_iter().enumerate() {\n            assert_eq!(elem.to_string(), entity.columns[i].get_def().to_string());\n        }\n    }\n\n    #[test]\n    fn test_get_primary_key_names_snake_case() {\n        let entity = setup();\n\n        for (i, elem) in entity\n            .get_primary_key_names_snake_case()\n            .into_iter()\n            .enumerate()\n        {\n            assert_eq!(elem, entity.primary_keys[i].get_name_snake_case());\n        }\n    }\n\n    #[test]\n    fn test_get_primary_key_names_camel_case() {\n        let entity = setup();\n\n        for (i, elem) in entity\n            .get_primary_key_names_camel_case()\n            .into_iter()\n            .enumerate()\n        {\n            assert_eq!(elem, entity.primary_keys[i].get_name_camel_case());\n        }\n    }\n\n    #[test]\n    fn test_get_relation_module_name() {\n        let entity = setup();\n\n        for (i, elem) in entity.get_relation_module_name().into_iter().enumerate() {\n            assert_eq!(elem, entity.relations[i].get_module_name());\n        }\n    }\n\n    #[test]\n    fn test_get_relation_enum_name() {\n        let entity = setup();\n\n        for (i, elem) in entity.get_relation_enum_name().into_iter().enumerate() {\n            assert_eq!(elem, entity.relations[i].get_enum_name());\n        }\n    }\n\n    #[test]\n    fn test_get_relation_defs() {\n        let entity = setup();\n\n        for (i, elem) in entity.get_relation_defs().into_iter().enumerate() {\n            assert_eq!(elem.to_string(), entity.relations[i].get_def().to_string());\n        }\n    }\n\n    #[test]\n    fn test_get_relation_attrs() {\n        let entity = setup();\n\n        for (i, elem) in entity.get_relation_attrs().into_iter().enumerate() {\n            assert_eq!(\n                elem.to_string(),\n                entity.relations[i].get_attrs().to_string()\n            );\n        }\n    }\n\n    #[test]\n    fn test_get_primary_key_auto_increment() {\n        let mut entity = setup();\n\n        assert_eq!(\n            entity.get_primary_key_auto_increment(),\n            format_ident!(\"{}\", false)\n        );\n\n        entity.columns[0].auto_increment = true;\n        assert_eq!(\n            entity.get_primary_key_auto_increment(),\n            format_ident!(\"{}\", true)\n        );\n    }\n\n    #[test]\n    fn test_get_primary_key_rs_type() {\n        let entity = setup();\n        let opt = Default::default();\n\n        assert_eq!(\n            entity.get_primary_key_rs_type(&opt).to_string(),\n            entity.columns[0].get_rs_type(&opt).to_string()\n        );\n    }\n\n    #[test]\n    fn test_get_conjunct_relations_via_snake_case() {\n        let entity = setup();\n\n        for (i, elem) in entity\n            .get_conjunct_relations_via_snake_case()\n            .into_iter()\n            .enumerate()\n        {\n            assert_eq!(elem, entity.conjunct_relations[i].get_via_snake_case());\n        }\n    }\n\n    #[test]\n    fn test_get_conjunct_relations_to_snake_case() {\n        let entity = setup();\n\n        for (i, elem) in entity\n            .get_conjunct_relations_to_snake_case()\n            .into_iter()\n            .enumerate()\n        {\n            assert_eq!(elem, entity.conjunct_relations[i].get_to_snake_case());\n        }\n    }\n\n    #[test]\n    fn test_get_conjunct_relations_to_upper_camel_case() {\n        let entity = setup();\n\n        for (i, elem) in entity\n            .get_conjunct_relations_to_upper_camel_case()\n            .into_iter()\n            .enumerate()\n        {\n            assert_eq!(elem, entity.conjunct_relations[i].get_to_upper_camel_case());\n        }\n    }\n\n    #[test]\n    fn test_get_eq_needed() {\n        let entity = setup();\n        let expected = quote! {, Eq};\n\n        assert_eq!(entity.get_eq_needed().to_string(), expected.to_string());\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/column.rs",
    "content": "use crate::{BigIntegerType, DateTimeCrate, util::escape_rust_keyword};\nuse heck::{ToSnakeCase, ToUpperCamelCase};\nuse proc_macro2::{Ident, TokenStream};\nuse quote::{format_ident, quote};\nuse sea_query::{ColumnDef, ColumnType, StringLen};\nuse std::fmt::Write as FmtWrite;\n\n#[derive(Debug, Clone)]\npub struct Column {\n    pub(crate) name: String,\n    pub(crate) col_type: ColumnType,\n    pub(crate) auto_increment: bool,\n    pub(crate) not_null: bool,\n    pub(crate) unique: bool,\n    pub(crate) unique_key: Option<String>,\n}\n\n#[derive(Debug, Default, Copy, Clone)]\npub struct ColumnOption {\n    pub(crate) date_time_crate: DateTimeCrate,\n    pub(crate) big_integer_type: BigIntegerType,\n}\n\nimpl Column {\n    pub fn get_name_snake_case(&self) -> Ident {\n        format_ident!(\"{}\", escape_rust_keyword(self.name.to_snake_case()))\n    }\n\n    pub fn get_name_camel_case(&self) -> Ident {\n        format_ident!(\"{}\", escape_rust_keyword(self.name.to_upper_camel_case()))\n    }\n\n    pub fn is_snake_case_name(&self) -> bool {\n        self.name.to_snake_case() == self.name\n    }\n\n    pub fn get_rs_type(&self, opt: &ColumnOption) -> TokenStream {\n        fn write_rs_type(col_type: &ColumnType, opt: &ColumnOption) -> String {\n            #[allow(unreachable_patterns)]\n            match col_type {\n                ColumnType::Char(_)\n                | ColumnType::String(_)\n                | ColumnType::Text\n                | ColumnType::Custom(_) => \"String\".to_owned(),\n                ColumnType::TinyInteger => \"i8\".to_owned(),\n                ColumnType::SmallInteger => \"i16\".to_owned(),\n                ColumnType::Integer => \"i32\".to_owned(),\n                ColumnType::BigInteger => match opt.big_integer_type {\n                    BigIntegerType::I64 => \"i64\",\n                    BigIntegerType::I32 => \"i32\",\n                }\n                .to_owned(),\n                ColumnType::TinyUnsigned => \"u8\".to_owned(),\n                ColumnType::SmallUnsigned => \"u16\".to_owned(),\n                ColumnType::Unsigned => \"u32\".to_owned(),\n                ColumnType::BigUnsigned => \"u64\".to_owned(),\n                ColumnType::Float => \"f32\".to_owned(),\n                ColumnType::Double => \"f64\".to_owned(),\n                ColumnType::Json | ColumnType::JsonBinary => \"Json\".to_owned(),\n                ColumnType::Date => match opt.date_time_crate {\n                    DateTimeCrate::Chrono => \"Date\".to_owned(),\n                    DateTimeCrate::Time => \"TimeDate\".to_owned(),\n                },\n                ColumnType::Time => match opt.date_time_crate {\n                    DateTimeCrate::Chrono => \"Time\".to_owned(),\n                    DateTimeCrate::Time => \"TimeTime\".to_owned(),\n                },\n                ColumnType::DateTime => match opt.date_time_crate {\n                    DateTimeCrate::Chrono => \"DateTime\".to_owned(),\n                    DateTimeCrate::Time => \"TimeDateTime\".to_owned(),\n                },\n                ColumnType::Timestamp => match opt.date_time_crate {\n                    DateTimeCrate::Chrono => \"DateTimeUtc\".to_owned(),\n                    DateTimeCrate::Time => \"TimeDateTime\".to_owned(),\n                },\n                ColumnType::TimestampWithTimeZone => match opt.date_time_crate {\n                    DateTimeCrate::Chrono => \"DateTimeWithTimeZone\".to_owned(),\n                    DateTimeCrate::Time => \"TimeDateTimeWithTimeZone\".to_owned(),\n                },\n                ColumnType::Decimal(_) | ColumnType::Money(_) => \"Decimal\".to_owned(),\n                ColumnType::Uuid => \"Uuid\".to_owned(),\n                ColumnType::Binary(_) | ColumnType::VarBinary(_) | ColumnType::Blob => {\n                    \"Vec<u8>\".to_owned()\n                }\n                ColumnType::Boolean => \"bool\".to_owned(),\n                ColumnType::Enum { name, .. } => name.to_string().to_upper_camel_case(),\n                ColumnType::Array(column_type) => {\n                    format!(\"Vec<{}>\", write_rs_type(column_type, opt))\n                }\n                ColumnType::Vector(_) => \"PgVector\".to_owned(),\n                ColumnType::Bit(None | Some(1)) => \"bool\".to_owned(),\n                ColumnType::Bit(_) | ColumnType::VarBit(_) => \"Vec<u8>\".to_owned(),\n                ColumnType::Year => \"i32\".to_owned(),\n                ColumnType::Cidr | ColumnType::Inet => \"IpNetwork\".to_owned(),\n                ColumnType::Interval(_, _) | ColumnType::MacAddr | ColumnType::LTree => {\n                    \"String\".to_owned()\n                }\n                _ => unimplemented!(),\n            }\n        }\n        let ident: TokenStream = write_rs_type(&self.col_type, opt).parse().unwrap();\n        match self.not_null {\n            true => quote! { #ident },\n            false => quote! { Option<#ident> },\n        }\n    }\n\n    pub fn get_col_type_attrs(&self) -> Option<TokenStream> {\n        let col_type = match &self.col_type {\n            ColumnType::Float => Some(\"Float\".to_owned()),\n            ColumnType::Double => Some(\"Double\".to_owned()),\n            ColumnType::Decimal(Some((p, s))) => Some(format!(\"Decimal(Some(({p}, {s})))\")),\n            ColumnType::Money(Some((p, s))) => Some(format!(\"Money(Some({p}, {s}))\")),\n            ColumnType::Text => Some(\"Text\".to_owned()),\n            ColumnType::JsonBinary => Some(\"JsonBinary\".to_owned()),\n            ColumnType::Custom(iden) => {\n                let ty = format!(\"custom(\\\"{iden}\\\")\");\n                return Some(quote! ( ignore, column_type = #ty, select_as = \"text\" ));\n            }\n            ColumnType::Binary(s) => Some(format!(\"Binary({s})\")),\n            ColumnType::VarBinary(s) => match s {\n                StringLen::N(s) => Some(format!(\"VarBinary(StringLen::N({s}))\")),\n                StringLen::None => Some(\"VarBinary(StringLen::None)\".to_owned()),\n                StringLen::Max => Some(\"VarBinary(StringLen::Max)\".to_owned()),\n            },\n            ColumnType::Blob => Some(\"Blob\".to_owned()),\n            ColumnType::Cidr => Some(\"Cidr\".to_owned()),\n            _ => None,\n        };\n        col_type.map(|ty| quote! { column_type = #ty })\n    }\n\n    pub fn get_def(&self) -> TokenStream {\n        fn write_col_def(col_type: &ColumnType) -> TokenStream {\n            match col_type {\n                ColumnType::Char(s) => match s {\n                    Some(s) => quote! { ColumnType::Char(Some(#s)) },\n                    None => quote! { ColumnType::Char(None) },\n                },\n                ColumnType::String(s) => match s {\n                    StringLen::N(s) => quote! { ColumnType::String(StringLen::N(#s)) },\n                    StringLen::None => quote! { ColumnType::String(StringLen::None) },\n                    StringLen::Max => quote! { ColumnType::String(StringLen::Max) },\n                },\n                ColumnType::Text => quote! { ColumnType::Text },\n                ColumnType::TinyInteger => quote! { ColumnType::TinyInteger },\n                ColumnType::SmallInteger => quote! { ColumnType::SmallInteger },\n                ColumnType::Integer => quote! { ColumnType::Integer },\n                ColumnType::BigInteger => quote! { ColumnType::BigInteger },\n                ColumnType::TinyUnsigned => quote! { ColumnType::TinyUnsigned },\n                ColumnType::SmallUnsigned => quote! { ColumnType::SmallUnsigned },\n                ColumnType::Unsigned => quote! { ColumnType::Unsigned },\n                ColumnType::BigUnsigned => quote! { ColumnType::BigUnsigned },\n                ColumnType::Float => quote! { ColumnType::Float },\n                ColumnType::Double => quote! { ColumnType::Double },\n                ColumnType::Decimal(s) => match s {\n                    Some((s1, s2)) => quote! { ColumnType::Decimal(Some((#s1, #s2))) },\n                    None => quote! { ColumnType::Decimal(None) },\n                },\n                ColumnType::DateTime => quote! { ColumnType::DateTime },\n                ColumnType::Timestamp => quote! { ColumnType::Timestamp },\n                ColumnType::TimestampWithTimeZone => {\n                    quote! { ColumnType::TimestampWithTimeZone }\n                }\n                ColumnType::Time => quote! { ColumnType::Time },\n                ColumnType::Date => quote! { ColumnType::Date },\n                ColumnType::Binary(s) => {\n                    quote! { ColumnType::Binary(#s) }\n                }\n                ColumnType::VarBinary(s) => match s {\n                    StringLen::N(s) => quote! { ColumnType::VarBinary(StringLen::N(#s)) },\n                    StringLen::None => quote! { ColumnType::VarBinary(StringLen::None) },\n                    StringLen::Max => quote! { ColumnType::VarBinary(StringLen::Max) },\n                },\n                ColumnType::Blob => quote! { ColumnType::Blob },\n                ColumnType::Boolean => quote! { ColumnType::Boolean },\n                ColumnType::Money(s) => match s {\n                    Some((s1, s2)) => quote! { ColumnType::Money(Some((#s1, #s2))) },\n                    None => quote! { ColumnType::Money(None) },\n                },\n                ColumnType::Json => quote! { ColumnType::Json },\n                ColumnType::JsonBinary => quote! { ColumnType::JsonBinary },\n                ColumnType::Uuid => quote! { ColumnType::Uuid },\n                ColumnType::Cidr => quote! { ColumnType::Cidr },\n                ColumnType::Inet => quote! { ColumnType::Inet },\n                ColumnType::Custom(s) => {\n                    let s = s.to_string();\n                    quote! { ColumnType::custom(#s) }\n                }\n                ColumnType::Enum { name, .. } => {\n                    let enum_ident = format_ident!(\"{}\", name.to_string().to_upper_camel_case());\n                    quote! {\n                        #enum_ident::db_type()\n                            .get_column_type()\n                            .to_owned()\n                    }\n                }\n                ColumnType::Array(column_type) => {\n                    let column_type = write_col_def(column_type);\n                    quote! { ColumnType::Array(RcOrArc::new(#column_type)) }\n                }\n                ColumnType::Vector(size) => match size {\n                    Some(size) => quote! { ColumnType::Vector(Some(#size)) },\n                    None => quote! { ColumnType::Vector(None) },\n                },\n                #[allow(unreachable_patterns)]\n                _ => unimplemented!(),\n            }\n        }\n        let mut col_def = write_col_def(&self.col_type);\n        col_def.extend(quote! {\n            .def()\n        });\n        if !self.not_null {\n            col_def.extend(quote! {\n                .null()\n            });\n        }\n        if self.unique {\n            col_def.extend(quote! {\n                .unique()\n            });\n        }\n        col_def\n    }\n\n    pub fn get_info(&self, opt: &ColumnOption) -> String {\n        let mut info = String::new();\n        let type_info = self.get_rs_type(opt).to_string().replace(' ', \"\");\n        let col_info = self.col_info();\n        write!(\n            &mut info,\n            \"Column `{}`: {}{}\",\n            self.name, type_info, col_info\n        )\n        .unwrap();\n        info\n    }\n\n    fn col_info(&self) -> String {\n        let mut info = String::new();\n        if self.auto_increment {\n            write!(&mut info, \", auto_increment\").unwrap();\n        }\n        if self.not_null {\n            write!(&mut info, \", not_null\").unwrap();\n        }\n        if self.unique {\n            write!(&mut info, \", unique\").unwrap();\n        }\n        info\n    }\n\n    pub fn get_serde_attribute(\n        &self,\n        is_primary_key: bool,\n        serde_skip_deserializing_primary_key: bool,\n        serde_skip_hidden_column: bool,\n    ) -> TokenStream {\n        if self.name.starts_with('_') && serde_skip_hidden_column {\n            quote! {\n                #[serde(skip)]\n            }\n        } else if serde_skip_deserializing_primary_key && is_primary_key {\n            quote! {\n                #[serde(skip_deserializing)]\n            }\n        } else {\n            quote! {}\n        }\n    }\n\n    pub fn get_inner_col_type(&self) -> &ColumnType {\n        match &self.col_type {\n            ColumnType::Array(inner_col_type) => inner_col_type.as_ref(),\n            _ => &self.col_type,\n        }\n    }\n}\n\nimpl From<ColumnDef> for Column {\n    fn from(col_def: ColumnDef) -> Self {\n        (&col_def).into()\n    }\n}\n\nimpl From<&ColumnDef> for Column {\n    fn from(col_def: &ColumnDef) -> Self {\n        let name = col_def.get_column_name();\n        let col_type = match col_def.get_column_type() {\n            Some(ty) => ty.clone(),\n            None => panic!(\"ColumnType should not be empty\"),\n        };\n        let auto_increment = col_def.get_column_spec().auto_increment;\n        let not_null = match col_def.get_column_spec().nullable {\n            Some(nullable) => !nullable,\n            None => false,\n        };\n        let unique = col_def.get_column_spec().unique;\n        Self {\n            name,\n            col_type,\n            auto_increment,\n            not_null,\n            unique,\n            unique_key: None,\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{Column, ColumnOption, DateTimeCrate};\n    use proc_macro2::TokenStream;\n    use quote::quote;\n    use sea_query::{Alias, ColumnDef, ColumnType, SeaRc, StringLen};\n\n    fn date_time_crate_chrono() -> ColumnOption {\n        ColumnOption {\n            date_time_crate: DateTimeCrate::Chrono,\n            big_integer_type: Default::default(),\n        }\n    }\n\n    fn date_time_crate_time() -> ColumnOption {\n        ColumnOption {\n            date_time_crate: DateTimeCrate::Time,\n            big_integer_type: Default::default(),\n        }\n    }\n\n    fn setup() -> Vec<Column> {\n        macro_rules! make_col {\n            ($name:expr, $col_type:expr) => {\n                Column {\n                    name: $name.to_owned(),\n                    col_type: $col_type,\n                    auto_increment: false,\n                    not_null: false,\n                    unique: false,\n                    unique_key: None,\n                }\n            };\n        }\n        vec![\n            make_col!(\"id\", ColumnType::String(StringLen::N(255))),\n            make_col!(\"id\", ColumnType::String(StringLen::None)),\n            make_col!(\n                \"cake_id\",\n                ColumnType::Custom(SeaRc::new(Alias::new(\"cus_col\")))\n            ),\n            make_col!(\"CakeId\", ColumnType::TinyInteger),\n            make_col!(\"CakeId\", ColumnType::TinyUnsigned),\n            make_col!(\"CakeId\", ColumnType::SmallInteger),\n            make_col!(\"CakeId\", ColumnType::SmallUnsigned),\n            make_col!(\"CakeId\", ColumnType::Integer),\n            make_col!(\"CakeId\", ColumnType::Unsigned),\n            make_col!(\"CakeFillingId\", ColumnType::BigInteger),\n            make_col!(\"CakeFillingId\", ColumnType::BigUnsigned),\n            make_col!(\"cake-filling-id\", ColumnType::Float),\n            make_col!(\"CAKE_FILLING_ID\", ColumnType::Double),\n            make_col!(\"CAKE-FILLING-ID\", ColumnType::Binary(10)),\n            make_col!(\"CAKE-FILLING-ID\", ColumnType::VarBinary(StringLen::None)),\n            make_col!(\"CAKE-FILLING-ID\", ColumnType::VarBinary(StringLen::N(10))),\n            make_col!(\"CAKE-FILLING-ID\", ColumnType::VarBinary(StringLen::Max)),\n            make_col!(\"CAKE\", ColumnType::Boolean),\n            make_col!(\"date\", ColumnType::Date),\n            make_col!(\"time\", ColumnType::Time),\n            make_col!(\"date_time\", ColumnType::DateTime),\n            make_col!(\"timestamp\", ColumnType::Timestamp),\n            make_col!(\"timestamp_tz\", ColumnType::TimestampWithTimeZone),\n        ]\n    }\n\n    #[test]\n    fn test_get_name_snake_case() {\n        let columns = setup();\n        let snack_cases = vec![\n            \"id\",\n            \"id\",\n            \"cake_id\",\n            \"cake_id\",\n            \"cake_id\",\n            \"cake_id\",\n            \"cake_id\",\n            \"cake_id\",\n            \"cake_id\",\n            \"cake_filling_id\",\n            \"cake_filling_id\",\n            \"cake_filling_id\",\n            \"cake_filling_id\",\n            \"cake_filling_id\",\n            \"cake_filling_id\",\n            \"cake_filling_id\",\n            \"cake_filling_id\",\n            \"cake\",\n            \"date\",\n            \"time\",\n            \"date_time\",\n            \"timestamp\",\n            \"timestamp_tz\",\n        ];\n        for (col, snack_case) in columns.into_iter().zip(snack_cases) {\n            assert_eq!(col.get_name_snake_case().to_string(), snack_case);\n        }\n    }\n\n    #[test]\n    fn test_get_name_camel_case() {\n        let columns = setup();\n        let camel_cases = vec![\n            \"Id\",\n            \"Id\",\n            \"CakeId\",\n            \"CakeId\",\n            \"CakeId\",\n            \"CakeId\",\n            \"CakeId\",\n            \"CakeId\",\n            \"CakeId\",\n            \"CakeFillingId\",\n            \"CakeFillingId\",\n            \"CakeFillingId\",\n            \"CakeFillingId\",\n            \"CakeFillingId\",\n            \"CakeFillingId\",\n            \"CakeFillingId\",\n            \"CakeFillingId\",\n            \"Cake\",\n            \"Date\",\n            \"Time\",\n            \"DateTime\",\n            \"Timestamp\",\n            \"TimestampTz\",\n        ];\n        for (col, camel_case) in columns.into_iter().zip(camel_cases) {\n            assert_eq!(col.get_name_camel_case().to_string(), camel_case);\n        }\n    }\n\n    #[test]\n    fn test_get_rs_type_with_chrono() {\n        let columns = setup();\n        let rs_types = vec![\n            \"String\",\n            \"String\",\n            \"String\",\n            \"i8\",\n            \"u8\",\n            \"i16\",\n            \"u16\",\n            \"i32\",\n            \"u32\",\n            \"i64\",\n            \"u64\",\n            \"f32\",\n            \"f64\",\n            \"Vec<u8>\",\n            \"Vec<u8>\",\n            \"Vec<u8>\",\n            \"Vec<u8>\",\n            \"bool\",\n            \"Date\",\n            \"Time\",\n            \"DateTime\",\n            \"DateTimeUtc\",\n            \"DateTimeWithTimeZone\",\n        ];\n        for (mut col, rs_type) in columns.into_iter().zip(rs_types) {\n            let rs_type: TokenStream = rs_type.parse().unwrap();\n\n            col.not_null = true;\n            assert_eq!(\n                col.get_rs_type(&date_time_crate_chrono()).to_string(),\n                quote!(#rs_type).to_string()\n            );\n\n            col.not_null = false;\n            assert_eq!(\n                col.get_rs_type(&date_time_crate_chrono()).to_string(),\n                quote!(Option<#rs_type>).to_string()\n            );\n        }\n    }\n\n    #[test]\n    fn test_get_rs_type_with_time() {\n        let columns = setup();\n        let rs_types = vec![\n            \"String\",\n            \"String\",\n            \"String\",\n            \"i8\",\n            \"u8\",\n            \"i16\",\n            \"u16\",\n            \"i32\",\n            \"u32\",\n            \"i64\",\n            \"u64\",\n            \"f32\",\n            \"f64\",\n            \"Vec<u8>\",\n            \"Vec<u8>\",\n            \"Vec<u8>\",\n            \"Vec<u8>\",\n            \"bool\",\n            \"TimeDate\",\n            \"TimeTime\",\n            \"TimeDateTime\",\n            \"TimeDateTime\",\n            \"TimeDateTimeWithTimeZone\",\n        ];\n        for (mut col, rs_type) in columns.into_iter().zip(rs_types) {\n            let rs_type: TokenStream = rs_type.parse().unwrap();\n\n            col.not_null = true;\n            assert_eq!(\n                col.get_rs_type(&date_time_crate_time()).to_string(),\n                quote!(#rs_type).to_string()\n            );\n\n            col.not_null = false;\n            assert_eq!(\n                col.get_rs_type(&date_time_crate_time()).to_string(),\n                quote!(Option<#rs_type>).to_string()\n            );\n        }\n    }\n\n    #[test]\n    fn test_get_def() {\n        let columns = setup();\n        let col_defs = vec![\n            \"ColumnType::String(StringLen::N(255u32)).def()\",\n            \"ColumnType::String(StringLen::None).def()\",\n            \"ColumnType::custom(\\\"cus_col\\\").def()\",\n            \"ColumnType::TinyInteger.def()\",\n            \"ColumnType::TinyUnsigned.def()\",\n            \"ColumnType::SmallInteger.def()\",\n            \"ColumnType::SmallUnsigned.def()\",\n            \"ColumnType::Integer.def()\",\n            \"ColumnType::Unsigned.def()\",\n            \"ColumnType::BigInteger.def()\",\n            \"ColumnType::BigUnsigned.def()\",\n            \"ColumnType::Float.def()\",\n            \"ColumnType::Double.def()\",\n            \"ColumnType::Binary(10u32).def()\",\n            \"ColumnType::VarBinary(StringLen::None).def()\",\n            \"ColumnType::VarBinary(StringLen::N(10u32)).def()\",\n            \"ColumnType::VarBinary(StringLen::Max).def()\",\n            \"ColumnType::Boolean.def()\",\n            \"ColumnType::Date.def()\",\n            \"ColumnType::Time.def()\",\n            \"ColumnType::DateTime.def()\",\n            \"ColumnType::Timestamp.def()\",\n            \"ColumnType::TimestampWithTimeZone.def()\",\n        ];\n        for (mut col, col_def) in columns.into_iter().zip(col_defs) {\n            let mut col_def: TokenStream = col_def.parse().unwrap();\n\n            col.not_null = true;\n            assert_eq!(col.get_def().to_string(), col_def.to_string());\n\n            col.not_null = false;\n            col_def.extend(quote!(.null()));\n            assert_eq!(col.get_def().to_string(), col_def.to_string());\n\n            col.unique = true;\n            col_def.extend(quote!(.unique()));\n            assert_eq!(col.get_def().to_string(), col_def.to_string());\n        }\n    }\n\n    #[test]\n    fn test_get_info() {\n        let column: Column = ColumnDef::new(Alias::new(\"id\")).string().to_owned().into();\n        assert_eq!(\n            column.get_info(&date_time_crate_chrono()).as_str(),\n            \"Column `id`: Option<String>\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"id\"))\n            .string()\n            .not_null()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_chrono()).as_str(),\n            \"Column `id`: String, not_null\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"id\"))\n            .string()\n            .not_null()\n            .unique_key()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_chrono()).as_str(),\n            \"Column `id`: String, not_null, unique\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"id\"))\n            .string()\n            .not_null()\n            .unique_key()\n            .auto_increment()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_chrono()).as_str(),\n            \"Column `id`: String, auto_increment, not_null, unique\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"date_field\"))\n            .date()\n            .not_null()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_chrono()).as_str(),\n            \"Column `date_field`: Date, not_null\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"date_field\"))\n            .date()\n            .not_null()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_time()).as_str(),\n            \"Column `date_field`: TimeDate, not_null\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"time_field\"))\n            .time()\n            .not_null()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_chrono()).as_str(),\n            \"Column `time_field`: Time, not_null\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"time_field\"))\n            .time()\n            .not_null()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_time()).as_str(),\n            \"Column `time_field`: TimeTime, not_null\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"date_time_field\"))\n            .date_time()\n            .not_null()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_chrono()).as_str(),\n            \"Column `date_time_field`: DateTime, not_null\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"date_time_field\"))\n            .date_time()\n            .not_null()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_time()).as_str(),\n            \"Column `date_time_field`: TimeDateTime, not_null\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"timestamp_field\"))\n            .timestamp()\n            .not_null()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_chrono()).as_str(),\n            \"Column `timestamp_field`: DateTimeUtc, not_null\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"timestamp_field\"))\n            .timestamp()\n            .not_null()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_time()).as_str(),\n            \"Column `timestamp_field`: TimeDateTime, not_null\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"timestamp_with_timezone_field\"))\n            .timestamp_with_time_zone()\n            .not_null()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_chrono()).as_str(),\n            \"Column `timestamp_with_timezone_field`: DateTimeWithTimeZone, not_null\"\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"timestamp_with_timezone_field\"))\n            .timestamp_with_time_zone()\n            .not_null()\n            .to_owned()\n            .into();\n        assert_eq!(\n            column.get_info(&date_time_crate_time()).as_str(),\n            \"Column `timestamp_with_timezone_field`: TimeDateTimeWithTimeZone, not_null\"\n        );\n    }\n\n    #[test]\n    fn test_from_column_def() {\n        let column: Column = ColumnDef::new(Alias::new(\"id\")).string().to_owned().into();\n        assert_eq!(\n            column.get_def().to_string(),\n            quote! {\n                ColumnType::String(StringLen::None).def().null()\n            }\n            .to_string()\n        );\n\n        let column: Column = ColumnDef::new(Alias::new(\"id\"))\n            .string()\n            .not_null()\n            .to_owned()\n            .into();\n        assert!(column.not_null);\n\n        let column: Column = ColumnDef::new(Alias::new(\"id\"))\n            .string()\n            .unique_key()\n            .not_null()\n            .to_owned()\n            .into();\n        assert!(column.unique);\n        assert!(column.not_null);\n\n        let column: Column = ColumnDef::new(Alias::new(\"id\"))\n            .string()\n            .auto_increment()\n            .unique_key()\n            .not_null()\n            .to_owned()\n            .into();\n        assert!(column.auto_increment);\n        assert!(column.unique);\n        assert!(column.not_null);\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/conjunct_relation.rs",
    "content": "use heck::{ToSnakeCase, ToUpperCamelCase};\nuse proc_macro2::Ident;\nuse quote::format_ident;\n\nuse crate::util::escape_rust_keyword;\n\n#[derive(Clone, Debug)]\npub struct ConjunctRelation {\n    pub(crate) via: String,\n    pub(crate) to: String,\n}\n\nimpl ConjunctRelation {\n    pub fn get_via_snake_case(&self) -> Ident {\n        format_ident!(\"{}\", escape_rust_keyword(self.via.to_snake_case()))\n    }\n\n    pub fn get_to_snake_case(&self) -> Ident {\n        format_ident!(\"{}\", escape_rust_keyword(self.to.to_snake_case()))\n    }\n\n    pub fn get_to_upper_camel_case(&self) -> Ident {\n        format_ident!(\"{}\", self.to.to_upper_camel_case())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::ConjunctRelation;\n\n    fn setup() -> Vec<ConjunctRelation> {\n        vec![\n            ConjunctRelation {\n                via: \"cake_filling\".to_owned(),\n                to: \"cake\".to_owned(),\n            },\n            ConjunctRelation {\n                via: \"cake_filling\".to_owned(),\n                to: \"filling\".to_owned(),\n            },\n        ]\n    }\n\n    #[test]\n    fn test_get_via_snake_case() {\n        let conjunct_relations = setup();\n        let via_vec = vec![\"cake_filling\", \"cake_filling\"];\n        for (con_rel, via) in conjunct_relations.into_iter().zip(via_vec) {\n            assert_eq!(con_rel.get_via_snake_case(), via);\n        }\n    }\n\n    #[test]\n    fn test_get_to_snake_case() {\n        let conjunct_relations = setup();\n        let to_vec = vec![\"cake\", \"filling\"];\n        for (con_rel, to) in conjunct_relations.into_iter().zip(to_vec) {\n            assert_eq!(con_rel.get_to_snake_case(), to);\n        }\n    }\n\n    #[test]\n    fn test_get_to_upper_camel_case() {\n        let conjunct_relations = setup();\n        let to_vec = vec![\"Cake\", \"Filling\"];\n        for (con_rel, to) in conjunct_relations.into_iter().zip(to_vec) {\n            assert_eq!(con_rel.get_to_upper_camel_case(), to);\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/mod.rs",
    "content": "mod active_enum;\nmod base_entity;\nmod column;\nmod conjunct_relation;\nmod primary_key;\nmod relation;\nmod transformer;\nmod writer;\n\npub use active_enum::*;\npub use base_entity::*;\npub use column::*;\npub use conjunct_relation::*;\npub use primary_key::*;\npub use relation::*;\npub use transformer::*;\npub use writer::*;\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/primary_key.rs",
    "content": "use heck::{ToSnakeCase, ToUpperCamelCase};\nuse proc_macro2::Ident;\nuse quote::format_ident;\n\n#[derive(Clone, Debug)]\npub struct PrimaryKey {\n    pub(crate) name: String,\n}\n\nimpl PrimaryKey {\n    pub fn get_name_snake_case(&self) -> Ident {\n        format_ident!(\"{}\", self.name.to_snake_case())\n    }\n\n    pub fn get_name_camel_case(&self) -> Ident {\n        format_ident!(\"{}\", self.name.to_upper_camel_case())\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::PrimaryKey;\n\n    fn setup() -> PrimaryKey {\n        PrimaryKey {\n            name: \"cake_id\".to_owned(),\n        }\n    }\n\n    #[test]\n    fn test_get_name_snake_case() {\n        let primary_key = setup();\n\n        assert_eq!(primary_key.get_name_snake_case(), \"cake_id\".to_owned());\n    }\n\n    #[test]\n    fn test_get_name_camel_case() {\n        let primary_key = setup();\n\n        assert_eq!(primary_key.get_name_camel_case(), \"CakeId\".to_owned());\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/relation.rs",
    "content": "use heck::{ToSnakeCase, ToUpperCamelCase};\nuse proc_macro2::{Ident, TokenStream};\nuse quote::{format_ident, quote};\nuse sea_query::{ForeignKeyAction, TableForeignKey};\nuse syn::{punctuated::Punctuated, token::Comma};\n\nuse crate::util::escape_rust_keyword;\n\n#[derive(Debug, Clone, Copy)]\npub enum RelationType {\n    HasOne,\n    HasMany,\n    BelongsTo,\n}\n\n#[derive(Clone, Debug)]\npub struct Relation {\n    pub(crate) ref_table: String,\n    pub(crate) columns: Vec<String>,\n    pub(crate) ref_columns: Vec<String>,\n    pub(crate) rel_type: RelationType,\n    pub(crate) on_update: Option<ForeignKeyAction>,\n    pub(crate) on_delete: Option<ForeignKeyAction>,\n    pub(crate) self_referencing: bool,\n    pub(crate) num_suffix: usize,\n    pub(crate) impl_related: bool,\n}\n\nimpl Relation {\n    pub fn get_enum_name(&self) -> Ident {\n        let name = if self.self_referencing {\n            format_ident!(\"SelfRef\")\n        } else {\n            format_ident!(\"{}\", self.ref_table.to_upper_camel_case())\n        };\n        if self.num_suffix > 0 {\n            format_ident!(\"{}{}\", name, self.num_suffix)\n        } else {\n            name\n        }\n    }\n\n    pub fn get_module_name(&self) -> Option<Ident> {\n        if self.self_referencing {\n            None\n        } else {\n            Some(format_ident!(\n                \"{}\",\n                escape_rust_keyword(self.ref_table.to_snake_case())\n            ))\n        }\n    }\n\n    pub fn get_def(&self) -> TokenStream {\n        let rel_type = self.get_rel_type();\n        let module_name = self.get_module_name();\n        let ref_entity = if module_name.is_some() {\n            quote! { super::#module_name::Entity }\n        } else {\n            quote! { Entity }\n        };\n        match self.rel_type {\n            RelationType::HasOne | RelationType::HasMany => {\n                quote! {\n                    Entity::#rel_type(#ref_entity).into()\n                }\n            }\n            RelationType::BelongsTo => {\n                let map_src_column = |src_column: &Ident| {\n                    quote! { Column::#src_column }\n                };\n                let map_ref_column = |ref_column: &Ident| {\n                    if module_name.is_some() {\n                        quote! { super::#module_name::Column::#ref_column }\n                    } else {\n                        quote! { Column::#ref_column }\n                    }\n                };\n                let map_punctuated =\n                    |punctuated: Punctuated<TokenStream, Comma>| match punctuated.len() {\n                        0..=1 => quote! { #punctuated },\n                        _ => quote! { (#punctuated) },\n                    };\n                let (from, to) =\n                    self.get_src_ref_columns(map_src_column, map_ref_column, map_punctuated);\n                quote! {\n                    Entity::#rel_type(#ref_entity)\n                        .from(#from)\n                        .to(#to)\n                        .into()\n                }\n            }\n        }\n    }\n\n    pub fn get_attrs(&self) -> TokenStream {\n        let rel_type = self.get_rel_type();\n        let module_name = if let Some(module_name) = self.get_module_name() {\n            format!(\"super::{module_name}::\")\n        } else {\n            String::new()\n        };\n        let ref_entity = format!(\"{module_name}Entity\");\n        match self.rel_type {\n            RelationType::HasOne | RelationType::HasMany => {\n                quote! {\n                    #[sea_orm(#rel_type = #ref_entity)]\n                }\n            }\n            RelationType::BelongsTo => {\n                let map_src_column = |src_column: &Ident| format!(\"Column::{src_column}\");\n                let map_ref_column =\n                    |ref_column: &Ident| format!(\"{module_name}Column::{ref_column}\");\n                let map_punctuated = |punctuated: Vec<String>| {\n                    let len = punctuated.len();\n                    let punctuated = punctuated.join(\", \");\n                    match len {\n                        0..=1 => punctuated,\n                        _ => format!(\"({punctuated})\"),\n                    }\n                };\n                let (from, to) =\n                    self.get_src_ref_columns(map_src_column, map_ref_column, map_punctuated);\n\n                let on_update = if let Some(action) = &self.on_update {\n                    let action = Self::get_foreign_key_action(action);\n                    quote! {\n                        on_update = #action,\n                    }\n                } else {\n                    quote! {}\n                };\n                let on_delete = if let Some(action) = &self.on_delete {\n                    let action = Self::get_foreign_key_action(action);\n                    quote! {\n                        on_delete = #action,\n                    }\n                } else {\n                    quote! {}\n                };\n                quote! {\n                    #[sea_orm(\n                        #rel_type = #ref_entity,\n                        from = #from,\n                        to = #to,\n                        #on_update\n                        #on_delete\n                    )]\n                }\n            }\n        }\n    }\n\n    pub fn get_rel_type(&self) -> Ident {\n        match self.rel_type {\n            RelationType::HasOne => format_ident!(\"has_one\"),\n            RelationType::HasMany => format_ident!(\"has_many\"),\n            RelationType::BelongsTo => format_ident!(\"belongs_to\"),\n        }\n    }\n\n    pub fn get_column_camel_case(&self) -> Vec<Ident> {\n        self.columns\n            .iter()\n            .map(|col| format_ident!(\"{}\", col.to_upper_camel_case()))\n            .collect()\n    }\n\n    pub fn get_ref_column_camel_case(&self) -> Vec<Ident> {\n        self.ref_columns\n            .iter()\n            .map(|col| format_ident!(\"{}\", col.to_upper_camel_case()))\n            .collect()\n    }\n\n    pub fn get_foreign_key_action(action: &ForeignKeyAction) -> String {\n        action.variant_name().to_owned()\n    }\n\n    pub fn get_src_ref_columns<F1, F2, F3, T, I>(\n        &self,\n        map_src_column: F1,\n        map_ref_column: F2,\n        map_punctuated: F3,\n    ) -> (T, T)\n    where\n        F1: Fn(&Ident) -> T,\n        F2: Fn(&Ident) -> T,\n        F3: Fn(I) -> T,\n        I: Extend<T> + Default,\n    {\n        let from: I =\n            self.get_column_camel_case()\n                .iter()\n                .fold(I::default(), |mut acc, src_column| {\n                    acc.extend([map_src_column(src_column)]);\n                    acc\n                });\n        let to: I =\n            self.get_ref_column_camel_case()\n                .iter()\n                .fold(I::default(), |mut acc, ref_column| {\n                    acc.extend([map_ref_column(ref_column)]);\n                    acc\n                });\n\n        (map_punctuated(from), map_punctuated(to))\n    }\n}\n\nimpl From<&TableForeignKey> for Relation {\n    fn from(tbl_fk: &TableForeignKey) -> Self {\n        let ref_table = match tbl_fk.get_ref_table() {\n            Some(s) => s.sea_orm_table().to_string(),\n            None => panic!(\"RefTable should not be empty\"),\n        };\n        let columns = tbl_fk.get_columns();\n        let ref_columns = tbl_fk.get_ref_columns();\n        let rel_type = RelationType::BelongsTo;\n        let on_delete = tbl_fk.get_on_delete();\n        let on_update = tbl_fk.get_on_update();\n        Self {\n            ref_table,\n            columns,\n            ref_columns,\n            rel_type,\n            on_delete,\n            on_update,\n            self_referencing: false,\n            num_suffix: 0,\n            impl_related: true,\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{Relation, RelationType};\n    use proc_macro2::TokenStream;\n    use sea_query::ForeignKeyAction;\n\n    fn setup() -> Vec<Relation> {\n        vec![\n            Relation {\n                ref_table: \"fruit\".to_owned(),\n                columns: vec![\"id\".to_owned()],\n                ref_columns: vec![\"cake_id\".to_owned()],\n                rel_type: RelationType::HasOne,\n                on_delete: None,\n                on_update: None,\n                self_referencing: false,\n                num_suffix: 0,\n                impl_related: true,\n            },\n            Relation {\n                ref_table: \"filling\".to_owned(),\n                columns: vec![\"filling_id\".to_owned()],\n                ref_columns: vec![\"id\".to_owned()],\n                rel_type: RelationType::BelongsTo,\n                on_delete: Some(ForeignKeyAction::Cascade),\n                on_update: Some(ForeignKeyAction::Cascade),\n                self_referencing: false,\n                num_suffix: 0,\n                impl_related: true,\n            },\n            Relation {\n                ref_table: \"filling\".to_owned(),\n                columns: vec![\"filling_id\".to_owned()],\n                ref_columns: vec![\"id\".to_owned()],\n                rel_type: RelationType::HasMany,\n                on_delete: Some(ForeignKeyAction::Cascade),\n                on_update: None,\n                self_referencing: false,\n                num_suffix: 0,\n                impl_related: true,\n            },\n        ]\n    }\n\n    #[test]\n    fn test_get_module_name() {\n        let relations = setup();\n        let snake_cases = vec![\"fruit\", \"filling\", \"filling\"];\n        for (rel, snake_case) in relations.into_iter().zip(snake_cases) {\n            assert_eq!(rel.get_module_name().unwrap().to_string(), snake_case);\n        }\n    }\n\n    #[test]\n    fn test_get_enum_name() {\n        let relations = setup();\n        let camel_cases = vec![\"Fruit\", \"Filling\", \"Filling\"];\n        for (rel, camel_case) in relations.into_iter().zip(camel_cases) {\n            assert_eq!(rel.get_enum_name().to_string(), camel_case);\n        }\n    }\n\n    #[test]\n    fn test_get_def() {\n        let relations = setup();\n        let rel_defs = vec![\n            \"Entity::has_one(super::fruit::Entity).into()\",\n            \"Entity::belongs_to(super::filling::Entity) \\\n                .from(Column::FillingId) \\\n                .to(super::filling::Column::Id) \\\n                .into()\",\n            \"Entity::has_many(super::filling::Entity).into()\",\n        ];\n        for (rel, rel_def) in relations.into_iter().zip(rel_defs) {\n            let rel_def: TokenStream = rel_def.parse().unwrap();\n\n            assert_eq!(rel.get_def().to_string(), rel_def.to_string());\n        }\n    }\n\n    #[test]\n    fn test_get_rel_type() {\n        let relations = setup();\n        let rel_types = vec![\"has_one\", \"belongs_to\", \"has_many\"];\n        for (rel, rel_type) in relations.into_iter().zip(rel_types) {\n            assert_eq!(rel.get_rel_type(), rel_type);\n        }\n    }\n\n    #[test]\n    fn test_get_column_camel_case() {\n        let relations = setup();\n        let cols = vec![\"Id\", \"FillingId\", \"FillingId\"];\n        for (rel, col) in relations.into_iter().zip(cols) {\n            assert_eq!(rel.get_column_camel_case(), [col]);\n        }\n    }\n\n    #[test]\n    fn test_get_ref_column_camel_case() {\n        let relations = setup();\n        let ref_cols = vec![\"CakeId\", \"Id\", \"Id\"];\n        for (rel, ref_col) in relations.into_iter().zip(ref_cols) {\n            assert_eq!(rel.get_ref_column_camel_case(), [ref_col]);\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/transformer.rs",
    "content": "use crate::{\n    ActiveEnum, Column, ConjunctRelation, Entity, EntityWriter, Error, PrimaryKey, Relation,\n    RelationType,\n};\nuse sea_query::TableCreateStatement;\nuse std::collections::{BTreeMap, HashMap, HashSet};\n\n#[derive(Clone, Debug)]\npub struct EntityTransformer;\n\nimpl EntityTransformer {\n    pub fn transform(table_create_stmts: Vec<TableCreateStatement>) -> Result<EntityWriter, Error> {\n        let mut enums: BTreeMap<String, ActiveEnum> = BTreeMap::new();\n        let mut inverse_relations: BTreeMap<String, Vec<Relation>> = BTreeMap::new();\n        let mut entities = BTreeMap::new();\n        for table_create in table_create_stmts.into_iter() {\n            let table_name = match table_create.get_table_name() {\n                Some(table_ref) => table_ref.sea_orm_table().to_string(),\n                None => {\n                    return Err(Error::TransformError(\n                        \"Table name should not be empty\".into(),\n                    ));\n                }\n            };\n            let mut primary_keys: Vec<PrimaryKey> = Vec::new();\n            let mut columns: Vec<Column> = table_create\n                .get_columns()\n                .iter()\n                .map(|col_def| {\n                    let primary_key = col_def.get_column_spec().primary_key;\n                    if primary_key {\n                        primary_keys.push(PrimaryKey {\n                            name: col_def.get_column_name(),\n                        });\n                    }\n                    col_def.into()\n                })\n                .map(|mut col: Column| {\n                    col.unique |= table_create\n                        .get_indexes()\n                        .iter()\n                        .filter(|index| index.is_unique_key())\n                        .map(|index| index.get_index_spec().get_column_names())\n                        .filter(|col_names| col_names.len() == 1 && col_names[0] == col.name)\n                        .count()\n                        > 0;\n                    col\n                })\n                .inspect(|col| {\n                    if let sea_query::ColumnType::Enum { name, variants } = col.get_inner_col_type()\n                    {\n                        enums.insert(\n                            name.to_string(),\n                            ActiveEnum {\n                                enum_name: name.clone(),\n                                values: variants.clone(),\n                            },\n                        );\n                    }\n                })\n                .collect();\n            for index in table_create.get_indexes().iter() {\n                if index.is_unique_key() {\n                    let col_names = index.get_index_spec().get_column_names();\n                    if col_names.len() > 1 {\n                        if let Some(mut key_name) = index.get_index_spec().get_name() {\n                            if let Some((_, suffix)) = key_name.rsplit_once('-') {\n                                key_name = suffix;\n                            }\n                            for col_name in col_names {\n                                for column in columns.iter_mut() {\n                                    if column.name == col_name {\n                                        column.unique_key = Some(key_name.to_owned());\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            let mut ref_table_counts: BTreeMap<String, usize> = BTreeMap::new();\n            let relations: Vec<Relation> = table_create\n                .get_foreign_key_create_stmts()\n                .iter()\n                .map(|fk_create_stmt| fk_create_stmt.get_foreign_key())\n                .map(|tbl_fk| {\n                    let ref_tbl = tbl_fk.get_ref_table().unwrap().sea_orm_table().to_string();\n                    if let Some(count) = ref_table_counts.get_mut(&ref_tbl) {\n                        if *count == 0 {\n                            *count = 1;\n                        }\n                        *count += 1;\n                    } else {\n                        ref_table_counts.insert(ref_tbl, 0);\n                    };\n                    tbl_fk.into()\n                })\n                .collect::<Vec<_>>()\n                .into_iter()\n                .rev()\n                .map(|mut rel: Relation| {\n                    rel.self_referencing = rel.ref_table == table_name;\n                    if let Some(count) = ref_table_counts.get_mut(&rel.ref_table) {\n                        rel.num_suffix = *count;\n                        if *count > 0 {\n                            *count -= 1;\n                        }\n                    }\n                    rel\n                })\n                .rev()\n                .collect();\n            primary_keys.extend(\n                table_create\n                    .get_indexes()\n                    .iter()\n                    .filter(|index| index.is_primary_key())\n                    .flat_map(|index| {\n                        index\n                            .get_index_spec()\n                            .get_column_names()\n                            .into_iter()\n                            .map(|name| PrimaryKey { name })\n                            .collect::<Vec<_>>()\n                    }),\n            );\n            let entity = Entity {\n                table_name: table_name.clone(),\n                columns,\n                relations: relations.clone(),\n                conjunct_relations: vec![],\n                primary_keys,\n            };\n            entities.insert(table_name.clone(), entity.clone());\n            for mut rel in relations.into_iter() {\n                // This will produce a duplicated relation\n                if rel.self_referencing {\n                    continue;\n                }\n                // This will cause compile error on the many side,\n                // got relation variant but without Related<T> implemented\n                if rel.num_suffix > 0 {\n                    continue;\n                }\n                let ref_table = rel.ref_table;\n                let mut unique = true;\n                for column in rel.columns.iter() {\n                    if !entity\n                        .columns\n                        .iter()\n                        .filter(|col| col.unique)\n                        .any(|col| col.name.as_str() == column)\n                    {\n                        unique = false;\n                        break;\n                    }\n                }\n                if rel.columns.len() == entity.primary_keys.len() {\n                    let mut count_pk = 0;\n                    for primary_key in entity.primary_keys.iter() {\n                        if rel.columns.contains(&primary_key.name) {\n                            count_pk += 1;\n                        }\n                    }\n                    if count_pk == entity.primary_keys.len() {\n                        unique = true;\n                    }\n                }\n                let rel_type = if unique {\n                    RelationType::HasOne\n                } else {\n                    RelationType::HasMany\n                };\n                rel.rel_type = rel_type;\n                rel.ref_table = table_name.to_string();\n                rel.columns = Vec::new();\n                rel.ref_columns = Vec::new();\n                if let Some(vec) = inverse_relations.get_mut(&ref_table) {\n                    vec.push(rel);\n                } else {\n                    inverse_relations.insert(ref_table, vec![rel]);\n                }\n            }\n        }\n        for (tbl_name, relations) in inverse_relations.into_iter() {\n            if let Some(entity) = entities.get_mut(&tbl_name) {\n                for relation in relations.into_iter() {\n                    let duplicate_relation = entity\n                        .relations\n                        .iter()\n                        .any(|rel| rel.ref_table == relation.ref_table);\n                    if !duplicate_relation {\n                        entity.relations.push(relation);\n                    }\n                }\n            }\n        }\n\n        // When codegen is fed with a subset of tables (e.g. via `sea-orm-cli generate entity --tables`),\n        // we must not generate relations that point to entities outside this set, otherwise it will\n        // produce invalid paths like `super::<missing_table>::Entity`.\n        let table_names: HashSet<String> = entities.keys().cloned().collect();\n        for entity in entities.values_mut() {\n            entity\n                .relations\n                .retain(|rel| rel.self_referencing || table_names.contains(&rel.ref_table));\n        }\n\n        for table_name in entities.clone().keys() {\n            let relations = match entities.get(table_name) {\n                Some(entity) => {\n                    let is_conjunct_relation =\n                        entity.relations.len() == 2 && entity.primary_keys.len() == 2;\n                    if !is_conjunct_relation {\n                        continue;\n                    }\n                    entity.relations.clone()\n                }\n                None => unreachable!(),\n            };\n            for (i, rel) in relations.iter().enumerate() {\n                let another_rel = relations.get((i == 0) as usize).unwrap();\n                if let Some(entity) = entities.get_mut(&rel.ref_table) {\n                    let conjunct_relation = ConjunctRelation {\n                        via: table_name.clone(),\n                        to: another_rel.ref_table.clone(),\n                    };\n                    entity.conjunct_relations.push(conjunct_relation);\n                }\n            }\n        }\n        Ok(EntityWriter {\n            entities: entities\n                .into_values()\n                .map(|mut v| {\n                    // Filter duplicated conjunct relations\n                    let duplicated_to: Vec<_> = v\n                        .conjunct_relations\n                        .iter()\n                        .fold(HashMap::new(), |mut acc, conjunct_relation| {\n                            acc.entry(conjunct_relation.to.clone())\n                                .and_modify(|c| *c += 1)\n                                .or_insert(1);\n                            acc\n                        })\n                        .into_iter()\n                        .filter(|(_, v)| v > &1)\n                        .map(|(k, _)| k)\n                        .collect();\n                    v.conjunct_relations\n                        .retain(|conjunct_relation| !duplicated_to.contains(&conjunct_relation.to));\n\n                    // Skip `impl Related ... { fn to() ... }` implementation block,\n                    // if the same related entity is being referenced by a conjunct relation\n                    v.relations.iter_mut().for_each(|relation| {\n                        if v.conjunct_relations\n                            .iter()\n                            .any(|conjunct_relation| conjunct_relation.to == relation.ref_table)\n                        {\n                            relation.impl_related = false;\n                        }\n                    });\n\n                    // Sort relation vectors\n                    v.relations.sort_by(|a, b| a.ref_table.cmp(&b.ref_table));\n                    v.conjunct_relations.sort_by(|a, b| a.to.cmp(&b.to));\n                    v\n                })\n                .collect(),\n            enums,\n        })\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use pretty_assertions::assert_eq;\n    use proc_macro2::TokenStream;\n    use sea_orm::{DbBackend, Schema};\n    use sea_query::{ColumnDef, ForeignKey, Table};\n    use std::{\n        error::Error,\n        io::{self, BufRead, BufReader},\n    };\n\n    #[test]\n    fn duplicated_many_to_many_paths() -> Result<(), Box<dyn Error>> {\n        use crate::tests_cfg::duplicated_many_to_many_paths::*;\n        let schema = Schema::new(DbBackend::Postgres);\n\n        validate_compact_entities(\n            vec![\n                schema.create_table_from_entity(bills::Entity),\n                schema.create_table_from_entity(users::Entity),\n                schema.create_table_from_entity(users_saved_bills::Entity),\n                schema.create_table_from_entity(users_votes::Entity),\n            ],\n            vec![\n                (\n                    \"bills\",\n                    include_str!(\"../tests_cfg/duplicated_many_to_many_paths/bills.rs\"),\n                ),\n                (\n                    \"users\",\n                    include_str!(\"../tests_cfg/duplicated_many_to_many_paths/users.rs\"),\n                ),\n                (\n                    \"users_saved_bills\",\n                    include_str!(\"../tests_cfg/duplicated_many_to_many_paths/users_saved_bills.rs\"),\n                ),\n                (\n                    \"users_votes\",\n                    include_str!(\"../tests_cfg/duplicated_many_to_many_paths/users_votes.rs\"),\n                ),\n            ],\n        )\n    }\n\n    #[test]\n    fn many_to_many() -> Result<(), Box<dyn Error>> {\n        use crate::tests_cfg::many_to_many::*;\n        let schema = Schema::new(DbBackend::Postgres);\n\n        validate_compact_entities(\n            vec![\n                schema.create_table_from_entity(bills::Entity),\n                schema.create_table_from_entity(users::Entity),\n                schema.create_table_from_entity(users_votes::Entity),\n            ],\n            vec![\n                (\"bills\", include_str!(\"../tests_cfg/many_to_many/bills.rs\")),\n                (\"users\", include_str!(\"../tests_cfg/many_to_many/users.rs\")),\n                (\n                    \"users_votes\",\n                    include_str!(\"../tests_cfg/many_to_many/users_votes.rs\"),\n                ),\n            ],\n        )\n    }\n\n    #[test]\n    fn many_to_many_multiple() -> Result<(), Box<dyn Error>> {\n        use crate::tests_cfg::many_to_many_multiple::*;\n        let schema = Schema::new(DbBackend::Postgres);\n\n        validate_compact_entities(\n            vec![\n                schema.create_table_from_entity(bills::Entity),\n                schema.create_table_from_entity(users::Entity),\n                schema.create_table_from_entity(users_votes::Entity),\n            ],\n            vec![\n                (\n                    \"bills\",\n                    include_str!(\"../tests_cfg/many_to_many_multiple/bills.rs\"),\n                ),\n                (\n                    \"users\",\n                    include_str!(\"../tests_cfg/many_to_many_multiple/users.rs\"),\n                ),\n                (\n                    \"users_votes\",\n                    include_str!(\"../tests_cfg/many_to_many_multiple/users_votes.rs\"),\n                ),\n            ],\n        )\n    }\n\n    #[test]\n    fn self_referencing() -> Result<(), Box<dyn Error>> {\n        use crate::tests_cfg::self_referencing::*;\n        let schema = Schema::new(DbBackend::Postgres);\n\n        validate_compact_entities(\n            vec![\n                schema.create_table_from_entity(bills::Entity),\n                schema.create_table_from_entity(users::Entity),\n            ],\n            vec![\n                (\n                    \"bills\",\n                    include_str!(\"../tests_cfg/self_referencing/bills.rs\"),\n                ),\n                (\n                    \"users\",\n                    include_str!(\"../tests_cfg/self_referencing/users.rs\"),\n                ),\n            ],\n        )\n    }\n\n    #[test]\n    fn test_indexes_transform() -> Result<(), Box<dyn Error>> {\n        let schema = Schema::new(DbBackend::Postgres);\n\n        validate_compact_entities(\n            vec![\n                schema.create_table_with_index_from_entity(\n                    crate::tests_cfg::compact::indexes::Entity,\n                ),\n            ],\n            vec![(\"indexes\", include_str!(\"../tests_cfg/compact/indexes.rs\"))],\n        )?;\n\n        validate_dense_entities(\n            vec![\n                schema\n                    .create_table_with_index_from_entity(crate::tests_cfg::dense::indexes::Entity),\n            ],\n            vec![(\"indexes\", include_str!(\"../tests_cfg/dense/indexes.rs\"))],\n        )?;\n\n        Ok(())\n    }\n\n    #[test]\n    fn filter_relations_to_missing_entities() -> Result<(), Box<dyn Error>> {\n        let parent_stmt = || {\n            Table::create()\n                .table(\"parent\")\n                .col(\n                    ColumnDef::new(\"id\")\n                        .integer()\n                        .not_null()\n                        .auto_increment()\n                        .primary_key(),\n                )\n                .to_owned()\n        };\n\n        let child_stmt = || {\n            Table::create()\n                .table(\"child\")\n                .col(\n                    ColumnDef::new(\"id\")\n                        .integer()\n                        .not_null()\n                        .auto_increment()\n                        .primary_key(),\n                )\n                .col(ColumnDef::new(\"parent_id\").integer().not_null())\n                .foreign_key(\n                    ForeignKey::create()\n                        .name(\"fk-child-parent_id\")\n                        .from(\"child\", \"parent_id\")\n                        .to(\"parent\", \"id\"),\n                )\n                .to_owned()\n        };\n\n        let entities: HashMap<_, _> =\n            EntityTransformer::transform(vec![parent_stmt(), child_stmt()])?\n                .entities\n                .into_iter()\n                .map(|entity| (entity.table_name.clone(), entity))\n                .collect();\n\n        let child = entities.get(\"child\").expect(\"missing entity `child`\");\n        assert_eq!(child.relations.len(), 1);\n        assert_eq!(child.relations[0].ref_table, \"parent\");\n\n        let entities: HashMap<_, _> = EntityTransformer::transform(vec![child_stmt()])?\n            .entities\n            .into_iter()\n            .map(|entity| (entity.table_name.clone(), entity))\n            .collect();\n\n        let child = entities.get(\"child\").expect(\"missing entity `child`\");\n        assert!(child.relations.is_empty());\n\n        Ok(())\n    }\n\n    #[test]\n    fn filter_conjunct_relations_to_missing_entities() -> Result<(), Box<dyn Error>> {\n        let user_stmt = || {\n            Table::create()\n                .table(\"user\")\n                .col(\n                    ColumnDef::new(\"id\")\n                        .integer()\n                        .not_null()\n                        .auto_increment()\n                        .primary_key(),\n                )\n                .to_owned()\n        };\n\n        let role_stmt = || {\n            Table::create()\n                .table(\"role\")\n                .col(\n                    ColumnDef::new(\"id\")\n                        .integer()\n                        .not_null()\n                        .auto_increment()\n                        .primary_key(),\n                )\n                .to_owned()\n        };\n\n        let user_role_stmt = || {\n            Table::create()\n                .table(\"user_role\")\n                .col(ColumnDef::new(\"user_id\").integer().not_null().primary_key())\n                .col(ColumnDef::new(\"role_id\").integer().not_null().primary_key())\n                .foreign_key(\n                    ForeignKey::create()\n                        .name(\"fk-user_role-user_id\")\n                        .from(\"user_role\", \"user_id\")\n                        .to(\"user\", \"id\"),\n                )\n                .foreign_key(\n                    ForeignKey::create()\n                        .name(\"fk-user_role-role_id\")\n                        .from(\"user_role\", \"role_id\")\n                        .to(\"role\", \"id\"),\n                )\n                .to_owned()\n        };\n\n        let entities: HashMap<_, _> =\n            EntityTransformer::transform(vec![user_stmt(), role_stmt(), user_role_stmt()])?\n                .entities\n                .into_iter()\n                .map(|entity| (entity.table_name.clone(), entity))\n                .collect();\n\n        let user = entities.get(\"user\").expect(\"missing entity `user`\");\n        assert!(user.conjunct_relations.iter().any(|conjunct_relation| {\n            conjunct_relation.via == \"user_role\" && conjunct_relation.to == \"role\"\n        }));\n\n        let entities: HashMap<_, _> =\n            EntityTransformer::transform(vec![user_stmt(), user_role_stmt()])?\n                .entities\n                .into_iter()\n                .map(|entity| (entity.table_name.clone(), entity))\n                .collect();\n\n        let user = entities.get(\"user\").expect(\"missing entity `user`\");\n        assert!(user.conjunct_relations.is_empty());\n\n        let user_role = entities\n            .get(\"user_role\")\n            .expect(\"missing entity `user_role`\");\n        assert_eq!(user_role.relations.len(), 1);\n        assert_eq!(user_role.relations[0].ref_table, \"user\");\n\n        Ok(())\n    }\n\n    macro_rules! validate_entities_fn {\n        ($fn_name: ident, $method: ident) => {\n            fn $fn_name(\n                table_create_stmts: Vec<TableCreateStatement>,\n                files: Vec<(&str, &str)>,\n            ) -> Result<(), Box<dyn Error>> {\n                let entities: HashMap<_, _> = EntityTransformer::transform(table_create_stmts)?\n                    .entities\n                    .into_iter()\n                    .map(|entity| (entity.table_name.clone(), entity))\n                    .collect();\n\n                for (entity_name, file_content) in files {\n                    let entity = entities\n                        .get(entity_name)\n                        .expect(\"Forget to add entity to the list\");\n\n                    assert_eq!(\n                        parse_from_file(file_content.as_bytes())?.to_string(),\n                        EntityWriter::$method(\n                            entity,\n                            &crate::WithSerde::None,\n                            &Default::default(),\n                            &None,\n                            false,\n                            false,\n                            &Default::default(),\n                            &Default::default(),\n                            &Default::default(),\n                            false,\n                            true,\n                        )\n                        .into_iter()\n                        .skip(1)\n                        .fold(TokenStream::new(), |mut acc, tok| {\n                            acc.extend(tok);\n                            acc\n                        })\n                        .to_string()\n                    );\n                }\n\n                Ok(())\n            }\n        };\n    }\n\n    validate_entities_fn!(validate_compact_entities, gen_compact_code_blocks);\n    validate_entities_fn!(validate_dense_entities, gen_dense_code_blocks);\n\n    fn parse_from_file<R>(inner: R) -> io::Result<TokenStream>\n    where\n        R: io::Read,\n    {\n        let mut reader = BufReader::new(inner);\n        let mut lines: Vec<String> = Vec::new();\n\n        reader.read_until(b';', &mut Vec::new())?;\n\n        let mut line = String::new();\n        while reader.read_line(&mut line)? > 0 {\n            lines.push(line.to_owned());\n            line.clear();\n        }\n        let content = lines.join(\"\");\n        Ok(content.parse().unwrap())\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/writer/compact.rs",
    "content": "use super::*;\n\nimpl EntityWriter {\n    #[allow(clippy::too_many_arguments)]\n    pub fn gen_compact_code_blocks(\n        entity: &Entity,\n        with_serde: &WithSerde,\n        column_option: &ColumnOption,\n        schema_name: &Option<String>,\n        serde_skip_deserializing_primary_key: bool,\n        serde_skip_hidden_column: bool,\n        model_extra_derives: &TokenStream,\n        model_extra_attributes: &TokenStream,\n        _column_extra_derives: &TokenStream,\n        seaography: bool,\n        impl_active_model_behavior: bool,\n    ) -> Vec<TokenStream> {\n        let mut imports = Self::gen_import(with_serde);\n        imports.extend(Self::gen_import_active_enum(entity));\n        let mut code_blocks = vec![\n            imports,\n            Self::gen_compact_model_struct(\n                entity,\n                with_serde,\n                column_option,\n                schema_name,\n                serde_skip_deserializing_primary_key,\n                serde_skip_hidden_column,\n                model_extra_derives,\n                model_extra_attributes,\n            ),\n            Self::gen_compact_relation_enum(entity),\n        ];\n        code_blocks.extend(Self::gen_impl_related(entity));\n        code_blocks.extend(Self::gen_impl_conjunct_related(entity));\n        if impl_active_model_behavior {\n            code_blocks.extend([Self::impl_active_model_behavior()]);\n        }\n        if seaography {\n            code_blocks.extend([Self::gen_related_entity(entity)]);\n        }\n        code_blocks\n    }\n\n    #[allow(clippy::too_many_arguments)]\n    pub fn gen_compact_model_struct(\n        entity: &Entity,\n        with_serde: &WithSerde,\n        column_option: &ColumnOption,\n        schema_name: &Option<String>,\n        serde_skip_deserializing_primary_key: bool,\n        serde_skip_hidden_column: bool,\n        model_extra_derives: &TokenStream,\n        model_extra_attributes: &TokenStream,\n    ) -> TokenStream {\n        let table_name = entity.table_name.as_str();\n        let column_names_snake_case = entity.get_column_names_snake_case();\n        let column_rs_types = entity.get_column_rs_types(column_option);\n        let if_eq_needed = entity.get_eq_needed();\n        let primary_keys: Vec<String> = entity\n            .primary_keys\n            .iter()\n            .map(|pk| pk.name.clone())\n            .collect();\n        let attrs: Vec<TokenStream> = entity\n            .columns\n            .iter()\n            .map(|col| {\n                let mut attrs: Punctuated<_, Comma> = Punctuated::new();\n                let is_primary_key = primary_keys.contains(&col.name);\n                if !col.is_snake_case_name() {\n                    let column_name = &col.name;\n                    attrs.push(quote! { column_name = #column_name });\n                }\n                if is_primary_key {\n                    attrs.push(quote! { primary_key });\n                    if !col.auto_increment {\n                        attrs.push(quote! { auto_increment = false });\n                    }\n                }\n                if let Some(ts) = col.get_col_type_attrs() {\n                    attrs.extend([ts]);\n                    if !col.not_null {\n                        attrs.push(quote! { nullable });\n                    }\n                };\n                if col.unique {\n                    attrs.push(quote! { unique });\n                } else if let Some(unique_key) = &col.unique_key {\n                    attrs.push(quote! { unique_key = #unique_key });\n                }\n                let mut ts = quote! {};\n                if !attrs.is_empty() {\n                    for (i, attr) in attrs.into_iter().enumerate() {\n                        if i > 0 {\n                            ts = quote! { #ts, };\n                        }\n                        ts = quote! { #ts #attr };\n                    }\n                    ts = quote! { #[sea_orm(#ts)] };\n                }\n                let serde_attribute = col.get_serde_attribute(\n                    is_primary_key,\n                    serde_skip_deserializing_primary_key,\n                    serde_skip_hidden_column,\n                );\n                ts = quote! {\n                    #ts\n                    #serde_attribute\n                };\n                ts\n            })\n            .collect();\n        let schema_name = match Self::gen_schema_name(schema_name) {\n            Some(schema_name) => quote! {\n                schema_name = #schema_name,\n            },\n            None => quote! {},\n        };\n        let extra_derive = with_serde.extra_derive();\n\n        quote! {\n            #[derive(Clone, Debug, PartialEq #if_eq_needed, DeriveEntityModel #extra_derive #model_extra_derives)]\n            #[sea_orm(\n                #schema_name\n                table_name = #table_name\n            )]\n            #model_extra_attributes\n            pub struct Model {\n                #(\n                    #attrs\n                    pub #column_names_snake_case: #column_rs_types,\n                )*\n            }\n        }\n    }\n\n    pub fn gen_compact_relation_enum(entity: &Entity) -> TokenStream {\n        let attrs = entity.get_relation_attrs();\n        let relation_enum_name = entity.get_relation_enum_name();\n        quote! {\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {\n                #(\n                    #attrs\n                    #relation_enum_name,\n                )*\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/writer/dense.rs",
    "content": "use super::*;\nuse crate::{Relation, RelationType};\nuse heck::ToSnakeCase;\n\nimpl EntityWriter {\n    #[allow(clippy::too_many_arguments)]\n    pub fn gen_dense_code_blocks(\n        entity: &Entity,\n        with_serde: &WithSerde,\n        column_option: &ColumnOption,\n        schema_name: &Option<String>,\n        serde_skip_deserializing_primary_key: bool,\n        serde_skip_hidden_column: bool,\n        model_extra_derives: &TokenStream,\n        model_extra_attributes: &TokenStream,\n        _column_extra_derives: &TokenStream,\n        _seaography: bool,\n        impl_active_model_behavior: bool,\n    ) -> Vec<TokenStream> {\n        let mut imports = Self::gen_import(with_serde);\n        imports.extend(Self::gen_import_active_enum(entity));\n        let mut code_blocks = vec![\n            imports,\n            Self::gen_dense_model_struct(\n                entity,\n                with_serde,\n                column_option,\n                schema_name,\n                serde_skip_deserializing_primary_key,\n                serde_skip_hidden_column,\n                model_extra_derives,\n                model_extra_attributes,\n            ),\n        ];\n        if impl_active_model_behavior {\n            code_blocks.push(Self::impl_active_model_behavior());\n        }\n        code_blocks\n    }\n\n    #[allow(clippy::too_many_arguments)]\n    pub fn gen_dense_model_struct(\n        entity: &Entity,\n        with_serde: &WithSerde,\n        column_option: &ColumnOption,\n        schema_name: &Option<String>,\n        serde_skip_deserializing_primary_key: bool,\n        serde_skip_hidden_column: bool,\n        model_extra_derives: &TokenStream,\n        model_extra_attributes: &TokenStream,\n    ) -> TokenStream {\n        let table_name = entity.table_name.as_str();\n        let column_names_snake_case = entity.get_column_names_snake_case();\n        let column_rs_types = entity.get_column_rs_types(column_option);\n        let if_eq_needed = entity.get_eq_needed();\n        let primary_keys: Vec<String> = entity\n            .primary_keys\n            .iter()\n            .map(|pk| pk.name.clone())\n            .collect();\n        let attrs: Vec<TokenStream> = entity\n            .columns\n            .iter()\n            .map(|col| {\n                let mut attrs: Punctuated<_, Comma> = Punctuated::new();\n                let is_primary_key = primary_keys.contains(&col.name);\n                if !col.is_snake_case_name() {\n                    let column_name = &col.name;\n                    attrs.push(quote! { column_name = #column_name });\n                }\n                if is_primary_key {\n                    attrs.push(quote! { primary_key });\n                    if !col.auto_increment {\n                        attrs.push(quote! { auto_increment = false });\n                    }\n                }\n                if let Some(ts) = col.get_col_type_attrs() {\n                    attrs.extend([ts]);\n                    if !col.not_null {\n                        attrs.push(quote! { nullable });\n                    }\n                };\n                if col.unique {\n                    attrs.push(quote! { unique });\n                } else if let Some(unique_key) = &col.unique_key {\n                    attrs.push(quote! { unique_key = #unique_key });\n                }\n                let mut ts = quote! {};\n                if !attrs.is_empty() {\n                    for (i, attr) in attrs.into_iter().enumerate() {\n                        if i > 0 {\n                            ts = quote! { #ts, };\n                        }\n                        ts = quote! { #ts #attr };\n                    }\n                    ts = quote! { #[sea_orm(#ts)] };\n                }\n                let serde_attribute = col.get_serde_attribute(\n                    is_primary_key,\n                    serde_skip_deserializing_primary_key,\n                    serde_skip_hidden_column,\n                );\n                ts = quote! {\n                    #ts\n                    #serde_attribute\n                };\n                ts\n            })\n            .collect();\n        let schema_name = match Self::gen_schema_name(schema_name) {\n            Some(schema_name) => quote! {\n                schema_name = #schema_name,\n            },\n            None => quote! {},\n        };\n        let extra_derive = with_serde.extra_derive();\n\n        let mut compound_objects: Punctuated<_, Comma> = Punctuated::new();\n\n        let map_col = |a: &syn::Ident| -> String {\n            let a = a.to_string();\n            let b = a.to_snake_case();\n            if a != b.to_upper_camel_case() {\n                // if roundtrip fails, use original\n                a\n            } else {\n                b\n            }\n        };\n        let map_punctuated = |punctuated: Vec<String>| -> String {\n            let len = punctuated.len();\n            let punctuated = punctuated.join(\", \");\n            match len {\n                0..=1 => punctuated,\n                _ => format!(\"({punctuated})\"),\n            }\n        };\n\n        let via_entities = entity.get_conjunct_relations_via_snake_case();\n        for rel in entity.relations.iter() {\n            if !rel.self_referencing && rel.impl_related {\n                let (rel_type, sea_orm_attr) = match rel.rel_type {\n                    RelationType::HasOne => (format_ident!(\"HasOne\"), quote!(#[sea_orm(has_one)])),\n                    RelationType::HasMany => {\n                        (format_ident!(\"HasMany\"), quote!(#[sea_orm(has_many)]))\n                    }\n                    RelationType::BelongsTo => {\n                        let (from, to) = rel.get_src_ref_columns(map_col, map_col, map_punctuated);\n                        let on_update = if let Some(action) = &rel.on_update {\n                            let action = Relation::get_foreign_key_action(action);\n                            quote!(, on_update = #action)\n                        } else {\n                            quote!()\n                        };\n                        let on_delete = if let Some(action) = &rel.on_delete {\n                            let action = Relation::get_foreign_key_action(action);\n                            quote!(, on_delete = #action)\n                        } else {\n                            quote!()\n                        };\n                        let relation_enum = if rel.num_suffix > 0 {\n                            let relation_enum = rel.get_enum_name().to_string();\n                            quote!(relation_enum = #relation_enum,)\n                        } else {\n                            quote!()\n                        };\n                        (\n                            format_ident!(\"HasOne\"),\n                            quote!(#[sea_orm(belongs_to, #relation_enum from = #from, to = #to #on_update #on_delete)]),\n                        )\n                    }\n                };\n\n                if let Some(to_entity) = rel.get_module_name() {\n                    if !via_entities.contains(&to_entity) {\n                        // skip junctions\n                        let field = if matches!(rel.rel_type, RelationType::HasMany) {\n                            format_ident!(\n                                \"{}\",\n                                pluralizer::pluralize(&to_entity.to_string(), 2, false)\n                            )\n                        } else {\n                            to_entity.clone()\n                        };\n                        let field = if rel.num_suffix == 0 {\n                            field\n                        } else {\n                            format_ident!(\"{field}_{}\", rel.num_suffix)\n                        };\n                        compound_objects.push(quote! {\n                            #sea_orm_attr\n                            pub #field: #rel_type<super::#to_entity::Entity>\n                        });\n                    }\n                }\n            } else if rel.self_referencing {\n                let (from, to) = rel.get_src_ref_columns(map_col, map_col, map_punctuated);\n                let on_update = if let Some(action) = &rel.on_update {\n                    let action = Relation::get_foreign_key_action(action);\n                    quote!(, on_update = #action)\n                } else {\n                    quote!()\n                };\n                let on_delete = if let Some(action) = &rel.on_delete {\n                    let action = Relation::get_foreign_key_action(action);\n                    quote!(, on_delete = #action)\n                } else {\n                    quote!()\n                };\n                let relation_enum = rel.get_enum_name().to_string();\n                let field = format_ident!(\n                    \"{}{}\",\n                    entity.get_table_name_snake_case_ident(),\n                    if rel.num_suffix > 0 {\n                        format!(\"_{}\", rel.num_suffix)\n                    } else {\n                        \"\".into()\n                    }\n                );\n\n                compound_objects.push(quote! {\n                    #[sea_orm(self_ref, relation_enum = #relation_enum, from = #from, to = #to #on_update #on_delete)]\n                    pub #field: HasOne<Entity>\n                });\n            }\n        }\n        for (to_entity, via_entity) in entity\n            .get_conjunct_relations_to_snake_case()\n            .into_iter()\n            .zip(via_entities)\n        {\n            let field = format_ident!(\n                \"{}\",\n                pluralizer::pluralize(&to_entity.to_string(), 2, false)\n            );\n            let via_entity = via_entity.to_string();\n            compound_objects.push(quote! {\n                #[sea_orm(has_many, via = #via_entity)]\n                pub #field: HasMany<super::#to_entity::Entity>\n            });\n        }\n\n        if !compound_objects.is_empty() {\n            compound_objects.push_punct(<syn::Token![,]>::default());\n        }\n\n        quote! {\n            #[sea_orm::model]\n            #[derive(Clone, Debug, PartialEq #if_eq_needed, DeriveEntityModel #extra_derive #model_extra_derives)]\n            #[sea_orm(\n                #schema_name\n                table_name = #table_name\n            )]\n            #model_extra_attributes\n            pub struct Model {\n                #(\n                    #attrs\n                    pub #column_names_snake_case: #column_rs_types,\n                )*\n                #compound_objects\n            }\n        }\n    }\n\n    #[allow(dead_code)]\n    fn gen_dense_related_entity(entity: &Entity) -> TokenStream {\n        let via_entities = entity.get_conjunct_relations_via_snake_case();\n\n        let related_modules = entity.get_related_entity_modules();\n        let related_attrs = entity.get_related_entity_attrs();\n        let related_enum_names = entity.get_related_entity_enum_name();\n\n        let items = related_modules\n            .into_iter()\n            .zip(related_attrs)\n            .zip(related_enum_names)\n            .filter_map(|((related_module, related_attr), related_enum_name)| {\n                if !via_entities.contains(&related_module) {\n                    // skip junctions\n                    Some(quote!(#related_attr #related_enum_name))\n                } else {\n                    None\n                }\n            })\n            .collect::<Vec<_>>();\n\n        quote! {\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]\n            pub enum RelatedEntity {\n                #(#items),*\n            }\n        }\n    }\n}\n\n#[cfg(test)]\nmod test {\n    #[test]\n    #[ignore]\n    fn test_name() {\n        panic!(\"{}\", pluralizer::pluralize(\"filling\", 2, false));\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/writer/expanded.rs",
    "content": "use super::*;\n\nimpl EntityWriter {\n    #[allow(clippy::too_many_arguments)]\n    pub fn gen_expanded_code_blocks(\n        entity: &Entity,\n        with_serde: &WithSerde,\n        column_option: &ColumnOption,\n        schema_name: &Option<String>,\n        serde_skip_deserializing_primary_key: bool,\n        serde_skip_hidden_column: bool,\n        model_extra_derives: &TokenStream,\n        model_extra_attributes: &TokenStream,\n        column_extra_derives: &TokenStream,\n        seaography: bool,\n        impl_active_model_behavior: bool,\n    ) -> Vec<TokenStream> {\n        let mut imports = Self::gen_import(with_serde);\n        imports.extend(Self::gen_import_active_enum(entity));\n        let mut code_blocks = vec![\n            imports,\n            Self::gen_entity_struct(),\n            Self::gen_impl_entity_name(entity, schema_name),\n            Self::gen_expanded_model_struct(\n                entity,\n                with_serde,\n                column_option,\n                serde_skip_deserializing_primary_key,\n                serde_skip_hidden_column,\n                model_extra_derives,\n                model_extra_attributes,\n            ),\n            Self::gen_column_enum(entity, column_extra_derives),\n            Self::gen_primary_key_enum(entity),\n            Self::gen_impl_primary_key(entity, column_option),\n            Self::gen_relation_enum(entity),\n            Self::gen_impl_column_trait(entity),\n            Self::gen_impl_relation_trait(entity),\n        ];\n        code_blocks.extend(Self::gen_impl_related(entity));\n        code_blocks.extend(Self::gen_impl_conjunct_related(entity));\n        if impl_active_model_behavior {\n            code_blocks.extend([Self::impl_active_model_behavior()]);\n        }\n        if seaography {\n            code_blocks.extend([Self::gen_related_entity(entity)]);\n        }\n        code_blocks\n    }\n\n    pub fn gen_expanded_model_struct(\n        entity: &Entity,\n        with_serde: &WithSerde,\n        column_option: &ColumnOption,\n        serde_skip_deserializing_primary_key: bool,\n        serde_skip_hidden_column: bool,\n        model_extra_derives: &TokenStream,\n        model_extra_attributes: &TokenStream,\n    ) -> TokenStream {\n        let column_names_snake_case = entity.get_column_names_snake_case();\n        let column_rs_types = entity.get_column_rs_types(column_option);\n        let if_eq_needed = entity.get_eq_needed();\n        let serde_attributes = entity.get_column_serde_attributes(\n            serde_skip_deserializing_primary_key,\n            serde_skip_hidden_column,\n        );\n        let extra_derive = with_serde.extra_derive();\n\n        quote! {\n            #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel #if_eq_needed #extra_derive #model_extra_derives)]\n            #model_extra_attributes\n            pub struct Model {\n                #(\n                    #serde_attributes\n                    pub #column_names_snake_case: #column_rs_types,\n                )*\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/writer/frontend.rs",
    "content": "use super::*;\n\nimpl EntityWriter {\n    #[allow(clippy::too_many_arguments)]\n    pub fn gen_frontend_code_blocks(\n        entity: &Entity,\n        with_serde: &WithSerde,\n        column_option: &ColumnOption,\n        schema_name: &Option<String>,\n        serde_skip_deserializing_primary_key: bool,\n        serde_skip_hidden_column: bool,\n        model_extra_derives: &TokenStream,\n        model_extra_attributes: &TokenStream,\n        _column_extra_derives: &TokenStream,\n        _seaography: bool,\n        _impl_active_model_behavior: bool,\n    ) -> Vec<TokenStream> {\n        let mut imports = Self::gen_import_serde(with_serde);\n        imports.extend(Self::gen_import_active_enum(entity));\n        let code_blocks = vec![\n            imports,\n            Self::gen_frontend_model_struct(\n                entity,\n                with_serde,\n                column_option,\n                schema_name,\n                serde_skip_deserializing_primary_key,\n                serde_skip_hidden_column,\n                model_extra_derives,\n                model_extra_attributes,\n            ),\n        ];\n        code_blocks\n    }\n\n    #[allow(clippy::too_many_arguments)]\n    pub fn gen_frontend_model_struct(\n        entity: &Entity,\n        with_serde: &WithSerde,\n        column_option: &ColumnOption,\n        _schema_name: &Option<String>,\n        serde_skip_deserializing_primary_key: bool,\n        serde_skip_hidden_column: bool,\n        model_extra_derives: &TokenStream,\n        model_extra_attributes: &TokenStream,\n    ) -> TokenStream {\n        let column_names_snake_case = entity.get_column_names_snake_case();\n        let column_rs_types = entity.get_column_rs_types(column_option);\n        let if_eq_needed = entity.get_eq_needed();\n        let primary_keys: Vec<String> = entity\n            .primary_keys\n            .iter()\n            .map(|pk| pk.name.clone())\n            .collect();\n        let attrs: Vec<TokenStream> = entity\n            .columns\n            .iter()\n            .map(|col| {\n                let is_primary_key = primary_keys.contains(&col.name);\n                col.get_serde_attribute(\n                    is_primary_key,\n                    serde_skip_deserializing_primary_key,\n                    serde_skip_hidden_column,\n                )\n            })\n            .collect();\n        let extra_derive = with_serde.extra_derive();\n\n        quote! {\n            #[derive(Clone, Debug, PartialEq #if_eq_needed #extra_derive #model_extra_derives)]\n            #model_extra_attributes\n            pub struct Model {\n                #(\n                    #attrs\n                    pub #column_names_snake_case: #column_rs_types,\n                )*\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/writer/mermaid.rs",
    "content": "use std::collections::{BTreeSet, HashSet};\nuse std::fmt::Write;\n\nuse sea_query::ColumnType;\n\nuse crate::{Entity, RelationType};\n\nuse super::EntityWriter;\n\nimpl EntityWriter {\n    pub fn generate_er_diagram(&self) -> String {\n        let mut out = String::from(\"erDiagram\\n\");\n\n        let pk_sets: Vec<HashSet<&str>> = self\n            .entities\n            .iter()\n            .map(|e| e.primary_keys.iter().map(|pk| pk.name.as_str()).collect())\n            .collect();\n\n        let fk_sets: Vec<HashSet<&str>> = self\n            .entities\n            .iter()\n            .map(|e| {\n                e.relations\n                    .iter()\n                    .filter(|r| matches!(r.rel_type, RelationType::BelongsTo))\n                    .flat_map(|r| r.columns.iter().map(String::as_str))\n                    .collect()\n            })\n            .collect();\n\n        for (i, entity) in self.entities.iter().enumerate() {\n            write_entity_block(&mut out, entity, &pk_sets[i], &fk_sets[i]);\n        }\n\n        let mut emitted: BTreeSet<String> = BTreeSet::new();\n\n        for entity in &self.entities {\n            write_relations(&mut out, entity, &mut emitted);\n        }\n\n        out\n    }\n}\n\nfn write_entity_block(out: &mut String, entity: &Entity, pks: &HashSet<&str>, fks: &HashSet<&str>) {\n    let _ = writeln!(out, \"    {} {{\", entity.table_name);\n\n    for col in &entity.columns {\n        let type_name = col_type_name(&col.col_type);\n        let is_pk = pks.contains(col.name.as_str());\n        let is_fk = fks.contains(col.name.as_str());\n        let is_uk = col.unique || col.unique_key.is_some();\n\n        let constraint = match (is_pk, is_fk, is_uk) {\n            (true, true, _) => \" PK,FK\",\n            (true, false, _) => \" PK\",\n            (false, true, true) => \" FK,UK\",\n            (false, true, false) => \" FK\",\n            (false, false, true) => \" UK\",\n            (false, false, false) => \"\",\n        };\n\n        let _ = writeln!(out, \"        {} {}{}\", type_name, col.name, constraint);\n    }\n\n    let _ = writeln!(out, \"    }}\");\n}\n\nfn write_relations(out: &mut String, entity: &Entity, emitted: &mut BTreeSet<String>) {\n    for rel in &entity.relations {\n        let (left, right, cardinality, label) = match rel.rel_type {\n            RelationType::BelongsTo => (\n                &entity.table_name,\n                &rel.ref_table,\n                \"}o--||\",\n                rel.columns.join(\", \"),\n            ),\n            RelationType::HasOne => continue,\n            RelationType::HasMany => continue,\n        };\n\n        let key = format!(\"{left} {cardinality} {right} : \\\"{label}\\\"\");\n        if emitted.insert(key.clone()) {\n            let _ = writeln!(out, \"    {key}\");\n        }\n    }\n\n    for conj in &entity.conjunct_relations {\n        let left = &entity.table_name;\n        let right = &conj.to;\n        let label = format!(\"[{}]\", conj.via);\n\n        let key = if left <= right {\n            format!(\"{left} }}o--o{{ {right} : \\\"{label}\\\"\")\n        } else {\n            format!(\"{right} }}o--o{{ {left} : \\\"{label}\\\"\")\n        };\n\n        if emitted.insert(key.clone()) {\n            let _ = writeln!(out, \"    {key}\");\n        }\n    }\n}\n\nfn col_type_name(col_type: &ColumnType) -> &str {\n    #[allow(unreachable_patterns)]\n    match col_type {\n        ColumnType::Char(_) => \"char\",\n        ColumnType::String(_) => \"varchar\",\n        ColumnType::Text => \"text\",\n        ColumnType::TinyInteger => \"tinyint\",\n        ColumnType::SmallInteger => \"smallint\",\n        ColumnType::Integer => \"int\",\n        ColumnType::BigInteger => \"bigint\",\n        ColumnType::TinyUnsigned => \"tinyint_unsigned\",\n        ColumnType::SmallUnsigned => \"smallint_unsigned\",\n        ColumnType::Unsigned => \"int_unsigned\",\n        ColumnType::BigUnsigned => \"bigint_unsigned\",\n        ColumnType::Float => \"float\",\n        ColumnType::Double => \"double\",\n        ColumnType::Decimal(_) => \"decimal\",\n        ColumnType::Money(_) => \"money\",\n        ColumnType::DateTime => \"datetime\",\n        ColumnType::Timestamp => \"timestamp\",\n        ColumnType::TimestampWithTimeZone => \"timestamptz\",\n        ColumnType::Time => \"time\",\n        ColumnType::Date => \"date\",\n        ColumnType::Year => \"year\",\n        ColumnType::Binary(_) | ColumnType::VarBinary(_) | ColumnType::Blob => \"blob\",\n        ColumnType::Boolean => \"bool\",\n        ColumnType::Json | ColumnType::JsonBinary => \"json\",\n        ColumnType::Uuid => \"uuid\",\n        ColumnType::Enum { .. } => \"enum\",\n        ColumnType::Array(_) => \"array\",\n        ColumnType::Vector(_) => \"vector\",\n        ColumnType::Bit(_) | ColumnType::VarBit(_) => \"bit\",\n        ColumnType::Cidr => \"cidr\",\n        ColumnType::Inet => \"inet\",\n        ColumnType::MacAddr => \"macaddr\",\n        ColumnType::LTree => \"ltree\",\n        ColumnType::Interval(_, _) => \"interval\",\n        ColumnType::Custom(_) => \"custom\",\n        _ => \"unknown\",\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use std::collections::BTreeMap;\n\n    use sea_query::{ColumnType, StringLen};\n\n    use crate::{\n        Column, ConjunctRelation, Entity, EntityWriter, PrimaryKey, Relation, RelationType,\n    };\n\n    fn setup_blog_schema() -> EntityWriter {\n        EntityWriter {\n            entities: vec![\n                Entity {\n                    table_name: \"user\".to_owned(),\n                    columns: vec![\n                        Column {\n                            name: \"id\".to_owned(),\n                            col_type: ColumnType::Integer,\n                            auto_increment: true,\n                            not_null: true,\n                            unique: false,\n                            unique_key: None,\n                        },\n                        Column {\n                            name: \"name\".to_owned(),\n                            col_type: ColumnType::String(StringLen::N(255)),\n                            auto_increment: false,\n                            not_null: true,\n                            unique: false,\n                            unique_key: None,\n                        },\n                        Column {\n                            name: \"email\".to_owned(),\n                            col_type: ColumnType::String(StringLen::N(255)),\n                            auto_increment: false,\n                            not_null: true,\n                            unique: true,\n                            unique_key: None,\n                        },\n                        Column {\n                            name: \"parent_id\".to_owned(),\n                            col_type: ColumnType::Integer,\n                            auto_increment: false,\n                            not_null: false,\n                            unique: false,\n                            unique_key: None,\n                        },\n                    ],\n                    relations: vec![\n                        Relation {\n                            ref_table: \"post\".to_owned(),\n                            columns: vec![],\n                            ref_columns: vec![],\n                            rel_type: RelationType::HasMany,\n                            on_delete: None,\n                            on_update: None,\n                            self_referencing: false,\n                            num_suffix: 0,\n                            impl_related: true,\n                        },\n                        Relation {\n                            ref_table: \"user\".to_owned(),\n                            columns: vec![\"parent_id\".to_owned()],\n                            ref_columns: vec![\"id\".to_owned()],\n                            rel_type: RelationType::BelongsTo,\n                            on_delete: None,\n                            on_update: None,\n                            self_referencing: true,\n                            num_suffix: 0,\n                            impl_related: true,\n                        },\n                    ],\n                    conjunct_relations: vec![],\n                    primary_keys: vec![PrimaryKey {\n                        name: \"id\".to_owned(),\n                    }],\n                },\n                Entity {\n                    table_name: \"post\".to_owned(),\n                    columns: vec![\n                        Column {\n                            name: \"id\".to_owned(),\n                            col_type: ColumnType::Integer,\n                            auto_increment: true,\n                            not_null: true,\n                            unique: false,\n                            unique_key: None,\n                        },\n                        Column {\n                            name: \"title\".to_owned(),\n                            col_type: ColumnType::Text,\n                            auto_increment: false,\n                            not_null: true,\n                            unique: false,\n                            unique_key: None,\n                        },\n                        Column {\n                            name: \"user_id\".to_owned(),\n                            col_type: ColumnType::Integer,\n                            auto_increment: false,\n                            not_null: true,\n                            unique: false,\n                            unique_key: None,\n                        },\n                    ],\n                    relations: vec![Relation {\n                        ref_table: \"user\".to_owned(),\n                        columns: vec![\"user_id\".to_owned()],\n                        ref_columns: vec![\"id\".to_owned()],\n                        rel_type: RelationType::BelongsTo,\n                        on_delete: None,\n                        on_update: None,\n                        self_referencing: false,\n                        num_suffix: 0,\n                        impl_related: true,\n                    }],\n                    conjunct_relations: vec![ConjunctRelation {\n                        via: \"post_tag\".to_owned(),\n                        to: \"tag\".to_owned(),\n                    }],\n                    primary_keys: vec![PrimaryKey {\n                        name: \"id\".to_owned(),\n                    }],\n                },\n                Entity {\n                    table_name: \"tag\".to_owned(),\n                    columns: vec![\n                        Column {\n                            name: \"id\".to_owned(),\n                            col_type: ColumnType::Integer,\n                            auto_increment: true,\n                            not_null: true,\n                            unique: false,\n                            unique_key: None,\n                        },\n                        Column {\n                            name: \"name\".to_owned(),\n                            col_type: ColumnType::String(StringLen::N(100)),\n                            auto_increment: false,\n                            not_null: true,\n                            unique: true,\n                            unique_key: None,\n                        },\n                    ],\n                    relations: vec![],\n                    conjunct_relations: vec![ConjunctRelation {\n                        via: \"post_tag\".to_owned(),\n                        to: \"post\".to_owned(),\n                    }],\n                    primary_keys: vec![PrimaryKey {\n                        name: \"id\".to_owned(),\n                    }],\n                },\n                Entity {\n                    table_name: \"post_tag\".to_owned(),\n                    columns: vec![\n                        Column {\n                            name: \"post_id\".to_owned(),\n                            col_type: ColumnType::Integer,\n                            auto_increment: false,\n                            not_null: true,\n                            unique: false,\n                            unique_key: None,\n                        },\n                        Column {\n                            name: \"tag_id\".to_owned(),\n                            col_type: ColumnType::Integer,\n                            auto_increment: false,\n                            not_null: true,\n                            unique: false,\n                            unique_key: None,\n                        },\n                    ],\n                    relations: vec![\n                        Relation {\n                            ref_table: \"post\".to_owned(),\n                            columns: vec![\"post_id\".to_owned()],\n                            ref_columns: vec![\"id\".to_owned()],\n                            rel_type: RelationType::BelongsTo,\n                            on_delete: None,\n                            on_update: None,\n                            self_referencing: false,\n                            num_suffix: 0,\n                            impl_related: true,\n                        },\n                        Relation {\n                            ref_table: \"tag\".to_owned(),\n                            columns: vec![\"tag_id\".to_owned()],\n                            ref_columns: vec![\"id\".to_owned()],\n                            rel_type: RelationType::BelongsTo,\n                            on_delete: None,\n                            on_update: None,\n                            self_referencing: false,\n                            num_suffix: 0,\n                            impl_related: true,\n                        },\n                    ],\n                    conjunct_relations: vec![],\n                    primary_keys: vec![\n                        PrimaryKey {\n                            name: \"post_id\".to_owned(),\n                        },\n                        PrimaryKey {\n                            name: \"tag_id\".to_owned(),\n                        },\n                    ],\n                },\n            ],\n            enums: BTreeMap::new(),\n        }\n    }\n\n    #[test]\n    fn test_generate_er_diagram() {\n        let writer = setup_blog_schema();\n        let diagram = writer.generate_er_diagram();\n\n        let expected = r#\"erDiagram\n    user {\n        int id PK\n        varchar name\n        varchar email UK\n        int parent_id FK\n    }\n    post {\n        int id PK\n        text title\n        int user_id FK\n    }\n    tag {\n        int id PK\n        varchar name UK\n    }\n    post_tag {\n        int post_id PK,FK\n        int tag_id PK,FK\n    }\n    user }o--|| user : \"parent_id\"\n    post }o--|| user : \"user_id\"\n    post }o--o{ tag : \"[post_tag]\"\n    post_tag }o--|| post : \"post_id\"\n    post_tag }o--|| tag : \"tag_id\"\n\"#;\n\n        assert_eq!(diagram, expected);\n    }\n\n    #[test]\n    fn test_er_diagram_deduplicates_m2m() {\n        let writer = setup_blog_schema();\n        let diagram = writer.generate_er_diagram();\n\n        let m2m_count = diagram.matches(\"}o--o{\").count();\n        assert_eq!(m2m_count, 1, \"M-N relation should appear only once\");\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/entity/writer.rs",
    "content": "use crate::{ActiveEnum, ColumnOption, Entity, util::escape_rust_keyword};\nuse heck::ToUpperCamelCase;\nuse proc_macro2::TokenStream;\nuse quote::{format_ident, quote};\nuse std::{collections::BTreeMap, str::FromStr};\nuse syn::{punctuated::Punctuated, token::Comma};\nuse tracing::info;\n\nmod compact;\nmod dense;\nmod expanded;\nmod frontend;\nmod mermaid;\n\n#[derive(Clone, Debug)]\npub struct EntityWriter {\n    pub(crate) entities: Vec<Entity>,\n    pub(crate) enums: BTreeMap<String, ActiveEnum>,\n}\n\npub struct WriterOutput {\n    pub files: Vec<OutputFile>,\n}\n\npub struct OutputFile {\n    pub name: String,\n    pub content: String,\n}\n\n#[derive(Debug, Default, PartialEq, Eq, Clone, Copy)]\npub enum WithPrelude {\n    #[default]\n    All,\n    None,\n    AllAllowUnusedImports,\n}\n\n#[derive(Debug, Default, PartialEq, Eq, Copy, Clone)]\npub enum WithSerde {\n    #[default]\n    None,\n    Serialize,\n    Deserialize,\n    Both,\n}\n\n#[derive(Debug, Default, PartialEq, Eq, Copy, Clone)]\npub enum DateTimeCrate {\n    #[default]\n    Chrono,\n    Time,\n}\n\n#[derive(Debug, Default, PartialEq, Eq, Copy, Clone)]\npub enum BigIntegerType {\n    #[default]\n    I64,\n    I32,\n}\n\n#[derive(Debug, Default, PartialEq, Eq, Copy, Clone)]\npub enum EntityFormat {\n    #[default]\n    Compact,\n    Expanded,\n    Frontend,\n    Dense,\n}\n\n#[derive(Debug, Default, PartialEq, Eq, Copy, Clone)]\npub enum BannerVersion {\n    Off,\n    Major,\n    #[default]\n    Minor,\n    Patch,\n}\n\n#[derive(Debug)]\npub struct EntityWriterContext {\n    pub(crate) entity_format: EntityFormat,\n    pub(crate) with_prelude: WithPrelude,\n    pub(crate) with_serde: WithSerde,\n    pub(crate) with_copy_enums: bool,\n    pub(crate) date_time_crate: DateTimeCrate,\n    pub(crate) big_integer_type: BigIntegerType,\n    pub(crate) schema_name: Option<String>,\n    pub(crate) lib: bool,\n    pub(crate) serde_skip_hidden_column: bool,\n    pub(crate) serde_skip_deserializing_primary_key: bool,\n    pub(crate) model_extra_derives: TokenStream,\n    pub(crate) model_extra_attributes: TokenStream,\n    pub(crate) enum_extra_derives: TokenStream,\n    pub(crate) enum_extra_attributes: TokenStream,\n    pub(crate) column_extra_derives: TokenStream,\n    pub(crate) seaography: bool,\n    pub(crate) impl_active_model_behavior: bool,\n    pub(crate) banner_version: BannerVersion,\n}\n\nimpl WithSerde {\n    pub fn extra_derive(&self) -> TokenStream {\n        let mut extra_derive = match self {\n            Self::None => {\n                quote! {}\n            }\n            Self::Serialize => {\n                quote! {\n                    Serialize\n                }\n            }\n            Self::Deserialize => {\n                quote! {\n                    Deserialize\n                }\n            }\n            Self::Both => {\n                quote! {\n                    Serialize, Deserialize\n                }\n            }\n        };\n        if !extra_derive.is_empty() {\n            extra_derive = quote! { , #extra_derive }\n        }\n        extra_derive\n    }\n}\n\n/// Converts *_extra_derives argument to token stream\npub(crate) fn bonus_derive<T, I>(extra_derives: I) -> TokenStream\nwhere\n    T: Into<String>,\n    I: IntoIterator<Item = T>,\n{\n    extra_derives.into_iter().map(Into::<String>::into).fold(\n        TokenStream::default(),\n        |acc, derive| {\n            let tokens: TokenStream = derive.parse().unwrap();\n            quote! { #acc, #tokens }\n        },\n    )\n}\n\n/// convert *_extra_attributes argument to token stream\npub(crate) fn bonus_attributes<T, I>(attributes: I) -> TokenStream\nwhere\n    T: Into<String>,\n    I: IntoIterator<Item = T>,\n{\n    attributes.into_iter().map(Into::<String>::into).fold(\n        TokenStream::default(),\n        |acc, attribute| {\n            let tokens: TokenStream = attribute.parse().unwrap();\n            quote! {\n                #acc\n                #[#tokens]\n            }\n        },\n    )\n}\n\nimpl FromStr for WithPrelude {\n    type Err = crate::Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        Ok(match s {\n            \"none\" => Self::None,\n            \"all-allow-unused-imports\" => Self::AllAllowUnusedImports,\n            \"all\" => Self::All,\n            v => {\n                return Err(crate::Error::TransformError(format!(\n                    \"Unsupported enum variant '{v}'\"\n                )));\n            }\n        })\n    }\n}\n\nimpl FromStr for EntityFormat {\n    type Err = crate::Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        Ok(match s {\n            \"compact\" => Self::Compact,\n            \"expanded\" => Self::Expanded,\n            \"frontend\" => Self::Frontend,\n            \"dense\" => Self::Dense,\n            v => {\n                return Err(crate::Error::TransformError(format!(\n                    \"Unsupported enum variant '{v}'\"\n                )));\n            }\n        })\n    }\n}\n\nimpl FromStr for WithSerde {\n    type Err = crate::Error;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        Ok(match s {\n            \"none\" => Self::None,\n            \"serialize\" => Self::Serialize,\n            \"deserialize\" => Self::Deserialize,\n            \"both\" => Self::Both,\n            v => {\n                return Err(crate::Error::TransformError(format!(\n                    \"Unsupported enum variant '{v}'\"\n                )));\n            }\n        })\n    }\n}\n\nimpl EntityWriterContext {\n    #[allow(clippy::too_many_arguments)]\n    pub fn new(\n        entity_format: EntityFormat,\n        with_prelude: WithPrelude,\n        with_serde: WithSerde,\n        with_copy_enums: bool,\n        date_time_crate: DateTimeCrate,\n        big_integer_type: BigIntegerType,\n        schema_name: Option<String>,\n        lib: bool,\n        serde_skip_deserializing_primary_key: bool,\n        serde_skip_hidden_column: bool,\n        model_extra_derives: Vec<String>,\n        model_extra_attributes: Vec<String>,\n        enum_extra_derives: Vec<String>,\n        enum_extra_attributes: Vec<String>,\n        column_extra_derives: Vec<String>,\n        seaography: bool,\n        impl_active_model_behavior: bool,\n        banner_version: BannerVersion,\n    ) -> Self {\n        Self {\n            entity_format,\n            with_prelude,\n            with_serde,\n            with_copy_enums,\n            date_time_crate,\n            big_integer_type,\n            schema_name,\n            lib,\n            serde_skip_deserializing_primary_key,\n            serde_skip_hidden_column,\n            model_extra_derives: bonus_derive(model_extra_derives),\n            model_extra_attributes: bonus_attributes(model_extra_attributes),\n            enum_extra_derives: bonus_derive(enum_extra_derives),\n            enum_extra_attributes: bonus_attributes(enum_extra_attributes),\n            column_extra_derives: bonus_derive(column_extra_derives),\n            seaography,\n            impl_active_model_behavior,\n            banner_version,\n        }\n    }\n\n    fn column_option(&self) -> ColumnOption {\n        ColumnOption {\n            date_time_crate: self.date_time_crate,\n            big_integer_type: self.big_integer_type,\n        }\n    }\n}\n\nimpl EntityWriter {\n    pub fn generate(self, context: &EntityWriterContext) -> WriterOutput {\n        let mut files = Vec::new();\n        files.extend(self.write_entities(context));\n        let with_prelude = context.with_prelude != WithPrelude::None;\n        files.push(self.write_index_file(\n            context.lib,\n            with_prelude,\n            context.seaography,\n            context.banner_version,\n        ));\n        if with_prelude {\n            files.push(self.write_prelude(\n                context.with_prelude,\n                context.entity_format,\n                context.banner_version,\n            ));\n        }\n        if !self.enums.is_empty() {\n            files.push(self.write_sea_orm_active_enums(\n                &context.with_serde,\n                context.with_copy_enums,\n                &context.enum_extra_derives,\n                &context.enum_extra_attributes,\n                context.entity_format,\n                context.banner_version,\n            ));\n        }\n        WriterOutput { files }\n    }\n\n    pub fn write_entities(&self, context: &EntityWriterContext) -> Vec<OutputFile> {\n        self.entities\n            .iter()\n            .map(|entity| {\n                let entity_file = format!(\"{}.rs\", entity.get_table_name_snake_case());\n                let column_info = entity\n                    .columns\n                    .iter()\n                    .map(|column| column.get_info(&context.column_option()))\n                    .collect::<Vec<String>>();\n                // Serde must be enabled to use this\n                let serde_skip_deserializing_primary_key = context\n                    .serde_skip_deserializing_primary_key\n                    && matches!(context.with_serde, WithSerde::Both | WithSerde::Deserialize);\n                let serde_skip_hidden_column = context.serde_skip_hidden_column\n                    && matches!(\n                        context.with_serde,\n                        WithSerde::Both | WithSerde::Serialize | WithSerde::Deserialize\n                    );\n\n                info!(\"Generating {}\", entity_file);\n                for info in column_info.iter() {\n                    info!(\"    > {}\", info);\n                }\n\n                let mut lines = Vec::new();\n                Self::write_doc_comment(&mut lines, context.banner_version);\n                let code_blocks = if context.entity_format == EntityFormat::Frontend {\n                    Self::gen_frontend_code_blocks(\n                        entity,\n                        &context.with_serde,\n                        &context.column_option(),\n                        &context.schema_name,\n                        serde_skip_deserializing_primary_key,\n                        serde_skip_hidden_column,\n                        &context.model_extra_derives,\n                        &context.model_extra_attributes,\n                        &context.column_extra_derives,\n                        context.seaography,\n                        context.impl_active_model_behavior,\n                    )\n                } else if context.entity_format == EntityFormat::Expanded {\n                    Self::gen_expanded_code_blocks(\n                        entity,\n                        &context.with_serde,\n                        &context.column_option(),\n                        &context.schema_name,\n                        serde_skip_deserializing_primary_key,\n                        serde_skip_hidden_column,\n                        &context.model_extra_derives,\n                        &context.model_extra_attributes,\n                        &context.column_extra_derives,\n                        context.seaography,\n                        context.impl_active_model_behavior,\n                    )\n                } else if context.entity_format == EntityFormat::Dense {\n                    Self::gen_dense_code_blocks(\n                        entity,\n                        &context.with_serde,\n                        &context.column_option(),\n                        &context.schema_name,\n                        serde_skip_deserializing_primary_key,\n                        serde_skip_hidden_column,\n                        &context.model_extra_derives,\n                        &context.model_extra_attributes,\n                        &context.column_extra_derives,\n                        context.seaography,\n                        context.impl_active_model_behavior,\n                    )\n                } else {\n                    Self::gen_compact_code_blocks(\n                        entity,\n                        &context.with_serde,\n                        &context.column_option(),\n                        &context.schema_name,\n                        serde_skip_deserializing_primary_key,\n                        serde_skip_hidden_column,\n                        &context.model_extra_derives,\n                        &context.model_extra_attributes,\n                        &context.column_extra_derives,\n                        context.seaography,\n                        context.impl_active_model_behavior,\n                    )\n                };\n                Self::write(&mut lines, code_blocks);\n                OutputFile {\n                    name: entity_file,\n                    content: lines.join(\"\\n\\n\"),\n                }\n            })\n            .collect()\n    }\n\n    pub fn write_index_file(\n        &self,\n        lib: bool,\n        prelude: bool,\n        seaography: bool,\n        banner_version: BannerVersion,\n    ) -> OutputFile {\n        let mut lines = Vec::new();\n        Self::write_doc_comment(&mut lines, banner_version);\n        let code_blocks: Vec<TokenStream> = self.entities.iter().map(Self::gen_mod).collect();\n        if prelude {\n            Self::write(\n                &mut lines,\n                vec![quote! {\n                    pub mod prelude;\n                }],\n            );\n            lines.push(\"\".to_owned());\n        }\n        Self::write(&mut lines, code_blocks);\n        if !self.enums.is_empty() {\n            Self::write(\n                &mut lines,\n                vec![quote! {\n                    pub mod sea_orm_active_enums;\n                }],\n            );\n        }\n\n        if seaography {\n            lines.push(\"\".to_owned());\n            let ts = Self::gen_seaography_entity_mod(&self.entities, &self.enums);\n            Self::write(&mut lines, vec![ts]);\n        }\n\n        let file_name = match lib {\n            true => \"lib.rs\".to_owned(),\n            false => \"mod.rs\".to_owned(),\n        };\n\n        OutputFile {\n            name: file_name,\n            content: lines.join(\"\\n\"),\n        }\n    }\n\n    pub fn write_prelude(\n        &self,\n        with_prelude: WithPrelude,\n        entity_format: EntityFormat,\n        banner_version: BannerVersion,\n    ) -> OutputFile {\n        let mut lines = Vec::new();\n        Self::write_doc_comment(&mut lines, banner_version);\n        if with_prelude == WithPrelude::AllAllowUnusedImports {\n            Self::write_allow_unused_imports(&mut lines)\n        }\n        let code_blocks = self\n            .entities\n            .iter()\n            .map({\n                if entity_format == EntityFormat::Frontend {\n                    Self::gen_prelude_use_model\n                } else {\n                    Self::gen_prelude_use\n                }\n            })\n            .collect();\n        Self::write(&mut lines, code_blocks);\n        OutputFile {\n            name: \"prelude.rs\".to_owned(),\n            content: lines.join(\"\\n\"),\n        }\n    }\n\n    pub fn write_sea_orm_active_enums(\n        &self,\n        with_serde: &WithSerde,\n        with_copy_enums: bool,\n        extra_derives: &TokenStream,\n        extra_attributes: &TokenStream,\n        entity_format: EntityFormat,\n        banner_version: BannerVersion,\n    ) -> OutputFile {\n        let mut lines = Vec::new();\n        Self::write_doc_comment(&mut lines, banner_version);\n        if entity_format == EntityFormat::Frontend {\n            Self::write(&mut lines, vec![Self::gen_import_serde(with_serde)]);\n        } else {\n            Self::write(&mut lines, vec![Self::gen_import(with_serde)]);\n        }\n        lines.push(\"\".to_owned());\n        let code_blocks = self\n            .enums\n            .values()\n            .map(|active_enum| {\n                active_enum.impl_active_enum(\n                    with_serde,\n                    with_copy_enums,\n                    extra_derives,\n                    extra_attributes,\n                    entity_format,\n                )\n            })\n            .collect();\n        Self::write(&mut lines, code_blocks);\n        OutputFile {\n            name: \"sea_orm_active_enums.rs\".to_owned(),\n            content: lines.join(\"\\n\"),\n        }\n    }\n\n    pub fn write(lines: &mut Vec<String>, code_blocks: Vec<TokenStream>) {\n        lines.extend(\n            code_blocks\n                .into_iter()\n                .map(|code_block| code_block.to_string())\n                .collect::<Vec<_>>(),\n        );\n    }\n\n    pub fn write_doc_comment(lines: &mut Vec<String>, banner_version: BannerVersion) {\n        let ver = env!(\"CARGO_PKG_VERSION\");\n        let version_str = match banner_version {\n            BannerVersion::Off => String::new(),\n            BannerVersion::Patch => ver.to_owned(),\n            _ => {\n                let parts: Vec<&str> = ver.split('.').collect();\n                match banner_version {\n                    BannerVersion::Major => {\n                        parts.first().map(|x| (*x).to_owned()).unwrap_or_default()\n                    }\n                    BannerVersion::Minor => {\n                        if parts.len() >= 2 {\n                            format!(\"{}.{}\", parts[0], parts[1])\n                        } else {\n                            ver.to_owned()\n                        }\n                    }\n                    _ => unreachable!(),\n                }\n            }\n        };\n        let comments = vec![format!(\n            \"//! `SeaORM` Entity, @generated by sea-orm-codegen {version_str}\"\n        )];\n        lines.extend(comments);\n        lines.push(\"\".to_owned());\n    }\n\n    pub fn write_allow_unused_imports(lines: &mut Vec<String>) {\n        lines.extend(vec![\"#![allow(unused_imports)]\".to_string()]);\n        lines.push(\"\".to_owned());\n    }\n\n    pub fn gen_import(with_serde: &WithSerde) -> TokenStream {\n        let serde_import = Self::gen_import_serde(with_serde);\n        quote! {\n            use sea_orm::entity::prelude::*;\n            #serde_import\n        }\n    }\n\n    pub fn gen_import_serde(with_serde: &WithSerde) -> TokenStream {\n        match with_serde {\n            WithSerde::None => Default::default(),\n            WithSerde::Serialize => {\n                quote! {\n                    use serde::Serialize;\n                }\n            }\n            WithSerde::Deserialize => {\n                quote! {\n                    use serde::Deserialize;\n                }\n            }\n            WithSerde::Both => {\n                quote! {\n                    use serde::{Deserialize,Serialize};\n                }\n            }\n        }\n    }\n\n    pub fn gen_entity_struct() -> TokenStream {\n        quote! {\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n        }\n    }\n\n    pub fn gen_impl_entity_name(entity: &Entity, schema_name: &Option<String>) -> TokenStream {\n        let schema_name = match Self::gen_schema_name(schema_name) {\n            Some(schema_name) => quote! {\n                fn schema_name(&self) -> Option<&str> {\n                    Some(#schema_name)\n                }\n            },\n            None => quote! {},\n        };\n        let table_name = entity.table_name.as_str();\n        let table_name = quote! {\n            fn table_name(&self) -> &'static str {\n                #table_name\n            }\n        };\n        quote! {\n            impl EntityName for Entity {\n                #schema_name\n                #table_name\n            }\n        }\n    }\n\n    pub fn gen_import_active_enum(entity: &Entity) -> TokenStream {\n        entity\n            .columns\n            .iter()\n            .fold(\n                (TokenStream::new(), Vec::new()),\n                |(mut ts, mut enums), col| {\n                    if let sea_query::ColumnType::Enum { name, .. } = col.get_inner_col_type() {\n                        if !enums.contains(&name) {\n                            enums.push(name);\n                            let enum_name =\n                                format_ident!(\"{}\", name.to_string().to_upper_camel_case());\n                            ts.extend([quote! {\n                                use super::sea_orm_active_enums::#enum_name;\n                            }]);\n                        }\n                    }\n                    (ts, enums)\n                },\n            )\n            .0\n    }\n\n    pub fn gen_column_enum(entity: &Entity, column_extra_derives: &TokenStream) -> TokenStream {\n        let column_variants = entity.columns.iter().map(|col| {\n            let variant = col.get_name_camel_case();\n            let mut variant = quote! { #variant };\n            if !col.is_snake_case_name() {\n                let column_name = &col.name;\n                variant = quote! {\n                    #[sea_orm(column_name = #column_name)]\n                    #variant\n                };\n            }\n            variant\n        });\n        quote! {\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn #column_extra_derives)]\n            pub enum Column {\n                #(#column_variants,)*\n            }\n        }\n    }\n\n    pub fn gen_primary_key_enum(entity: &Entity) -> TokenStream {\n        let primary_key_names_camel_case = entity.get_primary_key_names_camel_case();\n        quote! {\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                #(#primary_key_names_camel_case,)*\n            }\n        }\n    }\n\n    pub fn gen_impl_primary_key(entity: &Entity, column_option: &ColumnOption) -> TokenStream {\n        let primary_key_auto_increment = entity.get_primary_key_auto_increment();\n        let value_type = entity.get_primary_key_rs_type(column_option);\n        quote! {\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = #value_type;\n\n                fn auto_increment() -> bool {\n                    #primary_key_auto_increment\n                }\n            }\n        }\n    }\n\n    pub fn gen_relation_enum(entity: &Entity) -> TokenStream {\n        let relation_enum_name = entity.get_relation_enum_name();\n        quote! {\n            #[derive(Copy, Clone, Debug, EnumIter)]\n            pub enum Relation {\n                #(#relation_enum_name,)*\n            }\n        }\n    }\n\n    pub fn gen_impl_column_trait(entity: &Entity) -> TokenStream {\n        let column_names_camel_case = entity.get_column_names_camel_case();\n        let column_defs = entity.get_column_defs();\n        quote! {\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        #(Self::#column_names_camel_case => #column_defs,)*\n                    }\n                }\n            }\n        }\n    }\n\n    pub fn gen_impl_relation_trait(entity: &Entity) -> TokenStream {\n        let relation_enum_name = entity.get_relation_enum_name();\n        let relation_defs = entity.get_relation_defs();\n        let quoted = if relation_enum_name.is_empty() {\n            quote! {\n                panic!(\"No RelationDef\")\n            }\n        } else {\n            quote! {\n                match self {\n                    #(Self::#relation_enum_name => #relation_defs,)*\n                }\n            }\n        };\n        quote! {\n            impl RelationTrait for Relation {\n                fn def(&self) -> RelationDef {\n                    #quoted\n                }\n            }\n        }\n    }\n\n    pub fn gen_impl_related(entity: &Entity) -> Vec<TokenStream> {\n        entity\n            .relations\n            .iter()\n            .filter(|rel| !rel.self_referencing && rel.num_suffix == 0 && rel.impl_related)\n            .map(|rel| {\n                let enum_name = rel.get_enum_name();\n                let module_name = rel.get_module_name();\n                let inner = quote! {\n                    fn to() -> RelationDef {\n                        Relation::#enum_name.def()\n                    }\n                };\n                if module_name.is_some() {\n                    quote! {\n                        impl Related<super::#module_name::Entity> for Entity { #inner }\n                    }\n                } else {\n                    quote! {\n                        impl Related<Entity> for Entity { #inner }\n                    }\n                }\n            })\n            .collect()\n    }\n\n    /// Used to generate `enum RelatedEntity` that is useful to the Seaography project\n    pub fn gen_related_entity(entity: &Entity) -> TokenStream {\n        let related_enum_name = entity.get_related_entity_enum_name();\n        let related_attrs = entity.get_related_entity_attrs();\n\n        quote! {\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]\n            pub enum RelatedEntity {\n                #(\n                    #related_attrs\n                    #related_enum_name\n                ),*\n            }\n        }\n    }\n\n    pub fn gen_impl_conjunct_related(entity: &Entity) -> Vec<TokenStream> {\n        let table_name_camel_case = entity.get_table_name_camel_case_ident();\n        let via_snake_case = entity.get_conjunct_relations_via_snake_case();\n        let to_snake_case = entity.get_conjunct_relations_to_snake_case();\n        let to_upper_camel_case = entity.get_conjunct_relations_to_upper_camel_case();\n        via_snake_case\n            .into_iter()\n            .zip(to_snake_case)\n            .zip(to_upper_camel_case)\n            .map(|((via_snake_case, to_snake_case), to_upper_camel_case)| {\n                quote! {\n                    impl Related<super::#to_snake_case::Entity> for Entity {\n                        fn to() -> RelationDef {\n                            super::#via_snake_case::Relation::#to_upper_camel_case.def()\n                        }\n\n                        fn via() -> Option<RelationDef> {\n                            Some(super::#via_snake_case::Relation::#table_name_camel_case.def().rev())\n                        }\n                    }\n                }\n            })\n            .collect()\n    }\n\n    pub fn impl_active_model_behavior() -> TokenStream {\n        quote! {\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n    }\n\n    pub fn gen_mod(entity: &Entity) -> TokenStream {\n        let table_name_snake_case_ident = format_ident!(\n            \"{}\",\n            escape_rust_keyword(entity.get_table_name_snake_case_ident())\n        );\n        quote! {\n            pub mod #table_name_snake_case_ident;\n        }\n    }\n\n    pub fn gen_seaography_entity_mod(\n        entities: &[Entity],\n        enums: &BTreeMap<String, ActiveEnum>,\n    ) -> TokenStream {\n        let mut ts = TokenStream::new();\n        for entity in entities {\n            let table_name_snake_case_ident = format_ident!(\n                \"{}\",\n                escape_rust_keyword(entity.get_table_name_snake_case_ident())\n            );\n            ts = quote! {\n                #ts\n                #table_name_snake_case_ident,\n            }\n        }\n        ts = quote! {\n            seaography::register_entity_modules!([\n                #ts\n            ]);\n        };\n\n        let mut enum_ts = TokenStream::new();\n        for active_enum in enums.values() {\n            let enum_name = &active_enum.enum_name.to_string();\n            let enum_iden = format_ident!(\"{}\", enum_name.to_upper_camel_case());\n            enum_ts = quote! {\n                #enum_ts\n                sea_orm_active_enums::#enum_iden,\n            }\n        }\n        if !enum_ts.is_empty() {\n            ts = quote! {\n                #ts\n\n                seaography::register_active_enums!([\n                    #enum_ts\n                ]);\n            };\n        }\n        ts\n    }\n\n    pub fn gen_prelude_use(entity: &Entity) -> TokenStream {\n        let table_name_snake_case_ident = entity.get_table_name_snake_case_ident();\n        let table_name_camel_case_ident = entity.get_table_name_camel_case_ident();\n        quote! {\n            pub use super::#table_name_snake_case_ident::Entity as #table_name_camel_case_ident;\n        }\n    }\n\n    pub fn gen_prelude_use_model(entity: &Entity) -> TokenStream {\n        let table_name_snake_case_ident = entity.get_table_name_snake_case_ident();\n        let table_name_camel_case_ident = entity.get_table_name_camel_case_ident();\n        quote! {\n            pub use super::#table_name_snake_case_ident::Model as #table_name_camel_case_ident;\n        }\n    }\n\n    pub fn gen_schema_name(schema_name: &Option<String>) -> Option<TokenStream> {\n        schema_name\n            .as_ref()\n            .map(|schema_name| quote! { #schema_name })\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        Column, ColumnOption, ConjunctRelation, Entity, EntityWriter, PrimaryKey, Relation,\n        RelationType, WithSerde,\n        entity::writer::{bonus_attributes, bonus_derive},\n    };\n    use pretty_assertions::assert_eq;\n    use proc_macro2::TokenStream;\n    use quote::quote;\n    use sea_query::{Alias, ColumnType, ForeignKeyAction, RcOrArc, SeaRc, StringLen};\n    use std::io::{self, BufRead, BufReader, Read};\n\n    fn default_column_option() -> ColumnOption {\n        Default::default()\n    }\n\n    fn setup() -> Vec<Entity> {\n        vec![\n            Entity {\n                table_name: \"cake\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"name\".to_owned(),\n                        col_type: ColumnType::Text,\n                        auto_increment: false,\n                        not_null: false,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![Relation {\n                    ref_table: \"fruit\".to_owned(),\n                    columns: vec![],\n                    ref_columns: vec![],\n                    rel_type: RelationType::HasMany,\n                    on_delete: None,\n                    on_update: None,\n                    self_referencing: false,\n                    num_suffix: 0,\n                    impl_related: true,\n                }],\n                conjunct_relations: vec![ConjunctRelation {\n                    via: \"cake_filling\".to_owned(),\n                    to: \"filling\".to_owned(),\n                }],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n            Entity {\n                table_name: \"_cake_filling_\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"cake_id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"filling_id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![\n                    Relation {\n                        ref_table: \"cake\".to_owned(),\n                        columns: vec![\"cake_id\".to_owned()],\n                        ref_columns: vec![\"id\".to_owned()],\n                        rel_type: RelationType::BelongsTo,\n                        on_delete: Some(ForeignKeyAction::Cascade),\n                        on_update: Some(ForeignKeyAction::Cascade),\n                        self_referencing: false,\n                        num_suffix: 0,\n                        impl_related: true,\n                    },\n                    Relation {\n                        ref_table: \"filling\".to_owned(),\n                        columns: vec![\"filling_id\".to_owned()],\n                        ref_columns: vec![\"id\".to_owned()],\n                        rel_type: RelationType::BelongsTo,\n                        on_delete: Some(ForeignKeyAction::Cascade),\n                        on_update: Some(ForeignKeyAction::Cascade),\n                        self_referencing: false,\n                        num_suffix: 0,\n                        impl_related: true,\n                    },\n                ],\n                conjunct_relations: vec![],\n                primary_keys: vec![\n                    PrimaryKey {\n                        name: \"cake_id\".to_owned(),\n                    },\n                    PrimaryKey {\n                        name: \"filling_id\".to_owned(),\n                    },\n                ],\n            },\n            Entity {\n                table_name: \"cake_filling_price\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"cake_id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"filling_id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"price\".to_owned(),\n                        col_type: ColumnType::Decimal(None),\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![Relation {\n                    ref_table: \"cake_filling\".to_owned(),\n                    columns: vec![\"cake_id\".to_owned(), \"filling_id\".to_owned()],\n                    ref_columns: vec![\"cake_id\".to_owned(), \"filling_id\".to_owned()],\n                    rel_type: RelationType::BelongsTo,\n                    on_delete: None,\n                    on_update: None,\n                    self_referencing: false,\n                    num_suffix: 0,\n                    impl_related: true,\n                }],\n                conjunct_relations: vec![],\n                primary_keys: vec![\n                    PrimaryKey {\n                        name: \"cake_id\".to_owned(),\n                    },\n                    PrimaryKey {\n                        name: \"filling_id\".to_owned(),\n                    },\n                ],\n            },\n            Entity {\n                table_name: \"filling\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"name\".to_owned(),\n                        col_type: ColumnType::String(StringLen::N(255)),\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![],\n                conjunct_relations: vec![ConjunctRelation {\n                    via: \"cake_filling\".to_owned(),\n                    to: \"cake\".to_owned(),\n                }],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n            Entity {\n                table_name: \"fruit\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"name\".to_owned(),\n                        col_type: ColumnType::String(StringLen::N(255)),\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"cake_id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: false,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![\n                    Relation {\n                        ref_table: \"cake\".to_owned(),\n                        columns: vec![\"cake_id\".to_owned()],\n                        ref_columns: vec![\"id\".to_owned()],\n                        rel_type: RelationType::BelongsTo,\n                        on_delete: None,\n                        on_update: None,\n                        self_referencing: false,\n                        num_suffix: 0,\n                        impl_related: true,\n                    },\n                    Relation {\n                        ref_table: \"vendor\".to_owned(),\n                        columns: vec![],\n                        ref_columns: vec![],\n                        rel_type: RelationType::HasMany,\n                        on_delete: None,\n                        on_update: None,\n                        self_referencing: false,\n                        num_suffix: 0,\n                        impl_related: true,\n                    },\n                ],\n                conjunct_relations: vec![],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n            Entity {\n                table_name: \"vendor\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"_name_\".to_owned(),\n                        col_type: ColumnType::String(StringLen::N(255)),\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"fruitId\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: false,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![Relation {\n                    ref_table: \"fruit\".to_owned(),\n                    columns: vec![\"fruitId\".to_owned()],\n                    ref_columns: vec![\"id\".to_owned()],\n                    rel_type: RelationType::BelongsTo,\n                    on_delete: None,\n                    on_update: None,\n                    self_referencing: false,\n                    num_suffix: 0,\n                    impl_related: true,\n                }],\n                conjunct_relations: vec![],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n            Entity {\n                table_name: \"rust_keyword\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"testing\".to_owned(),\n                        col_type: ColumnType::TinyInteger,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"rust\".to_owned(),\n                        col_type: ColumnType::TinyUnsigned,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"keywords\".to_owned(),\n                        col_type: ColumnType::SmallInteger,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"type\".to_owned(),\n                        col_type: ColumnType::SmallUnsigned,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"typeof\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"crate\".to_owned(),\n                        col_type: ColumnType::Unsigned,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"self\".to_owned(),\n                        col_type: ColumnType::BigInteger,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"self_id1\".to_owned(),\n                        col_type: ColumnType::BigUnsigned,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"self_id2\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"fruit_id1\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"fruit_id2\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"cake_id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![\n                    Relation {\n                        ref_table: \"rust_keyword\".to_owned(),\n                        columns: vec![\"self_id1\".to_owned()],\n                        ref_columns: vec![\"id\".to_owned()],\n                        rel_type: RelationType::BelongsTo,\n                        on_delete: None,\n                        on_update: None,\n                        self_referencing: true,\n                        num_suffix: 1,\n                        impl_related: true,\n                    },\n                    Relation {\n                        ref_table: \"rust_keyword\".to_owned(),\n                        columns: vec![\"self_id2\".to_owned()],\n                        ref_columns: vec![\"id\".to_owned()],\n                        rel_type: RelationType::BelongsTo,\n                        on_delete: None,\n                        on_update: None,\n                        self_referencing: true,\n                        num_suffix: 2,\n                        impl_related: true,\n                    },\n                    Relation {\n                        ref_table: \"fruit\".to_owned(),\n                        columns: vec![\"fruit_id1\".to_owned()],\n                        ref_columns: vec![\"id\".to_owned()],\n                        rel_type: RelationType::BelongsTo,\n                        on_delete: None,\n                        on_update: None,\n                        self_referencing: false,\n                        num_suffix: 1,\n                        impl_related: true,\n                    },\n                    Relation {\n                        ref_table: \"fruit\".to_owned(),\n                        columns: vec![\"fruit_id2\".to_owned()],\n                        ref_columns: vec![\"id\".to_owned()],\n                        rel_type: RelationType::BelongsTo,\n                        on_delete: None,\n                        on_update: None,\n                        self_referencing: false,\n                        num_suffix: 2,\n                        impl_related: true,\n                    },\n                    Relation {\n                        ref_table: \"cake\".to_owned(),\n                        columns: vec![\"cake_id\".to_owned()],\n                        ref_columns: vec![\"id\".to_owned()],\n                        rel_type: RelationType::BelongsTo,\n                        on_delete: None,\n                        on_update: None,\n                        self_referencing: false,\n                        num_suffix: 0,\n                        impl_related: true,\n                    },\n                ],\n                conjunct_relations: vec![],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n            Entity {\n                table_name: \"cake_with_float\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"name\".to_owned(),\n                        col_type: ColumnType::Text,\n                        auto_increment: false,\n                        not_null: false,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"price\".to_owned(),\n                        col_type: ColumnType::Float,\n                        auto_increment: false,\n                        not_null: false,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![Relation {\n                    ref_table: \"fruit\".to_owned(),\n                    columns: vec![],\n                    ref_columns: vec![],\n                    rel_type: RelationType::HasMany,\n                    on_delete: None,\n                    on_update: None,\n                    self_referencing: false,\n                    num_suffix: 0,\n                    impl_related: true,\n                }],\n                conjunct_relations: vec![ConjunctRelation {\n                    via: \"cake_filling\".to_owned(),\n                    to: \"filling\".to_owned(),\n                }],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n            Entity {\n                table_name: \"cake_with_double\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"name\".to_owned(),\n                        col_type: ColumnType::Text,\n                        auto_increment: false,\n                        not_null: false,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"price\".to_owned(),\n                        col_type: ColumnType::Double,\n                        auto_increment: false,\n                        not_null: false,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![Relation {\n                    ref_table: \"fruit\".to_owned(),\n                    columns: vec![],\n                    ref_columns: vec![],\n                    rel_type: RelationType::HasMany,\n                    on_delete: None,\n                    on_update: None,\n                    self_referencing: false,\n                    num_suffix: 0,\n                    impl_related: true,\n                }],\n                conjunct_relations: vec![ConjunctRelation {\n                    via: \"cake_filling\".to_owned(),\n                    to: \"filling\".to_owned(),\n                }],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n            Entity {\n                table_name: \"collection\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"integers\".to_owned(),\n                        col_type: ColumnType::Array(RcOrArc::new(ColumnType::Integer)),\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"integers_opt\".to_owned(),\n                        col_type: ColumnType::Array(RcOrArc::new(ColumnType::Integer)),\n                        auto_increment: false,\n                        not_null: false,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![],\n                conjunct_relations: vec![],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n            Entity {\n                table_name: \"collection_float\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"floats\".to_owned(),\n                        col_type: ColumnType::Array(RcOrArc::new(ColumnType::Float)),\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"doubles\".to_owned(),\n                        col_type: ColumnType::Array(RcOrArc::new(ColumnType::Double)),\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![],\n                conjunct_relations: vec![],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n            Entity {\n                table_name: \"parent\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id1\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"id2\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![Relation {\n                    ref_table: \"child\".to_owned(),\n                    columns: vec![],\n                    ref_columns: vec![],\n                    rel_type: RelationType::HasMany,\n                    on_delete: None,\n                    on_update: None,\n                    self_referencing: false,\n                    num_suffix: 0,\n                    impl_related: true,\n                }],\n                conjunct_relations: vec![],\n                primary_keys: vec![\n                    PrimaryKey {\n                        name: \"id1\".to_owned(),\n                    },\n                    PrimaryKey {\n                        name: \"id2\".to_owned(),\n                    },\n                ],\n            },\n            Entity {\n                table_name: \"child\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"parent_id1\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"parent_id2\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![Relation {\n                    ref_table: \"parent\".to_owned(),\n                    columns: vec![\"parent_id1\".to_owned(), \"parent_id2\".to_owned()],\n                    ref_columns: vec![\"id1\".to_owned(), \"id2\".to_owned()],\n                    rel_type: RelationType::BelongsTo,\n                    on_delete: None,\n                    on_update: None,\n                    self_referencing: false,\n                    num_suffix: 0,\n                    impl_related: true,\n                }],\n                conjunct_relations: vec![],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n        ]\n    }\n\n    fn parse_from_file<R>(inner: R) -> io::Result<TokenStream>\n    where\n        R: Read,\n    {\n        let mut reader = BufReader::new(inner);\n        let mut lines: Vec<String> = Vec::new();\n\n        reader.read_until(b';', &mut Vec::new())?;\n\n        let mut line = String::new();\n        while reader.read_line(&mut line)? > 0 {\n            lines.push(line.to_owned());\n            line.clear();\n        }\n        let content = lines.join(\"\");\n        Ok(content.parse().unwrap())\n    }\n\n    fn parse_from_frontend_file<R>(inner: R) -> io::Result<TokenStream>\n    where\n        R: Read,\n    {\n        let mut reader = BufReader::new(inner);\n        let mut lines: Vec<String> = Vec::new();\n\n        reader.read_until(b'\\n', &mut Vec::new())?;\n\n        let mut line = String::new();\n        while reader.read_line(&mut line)? > 0 {\n            lines.push(line.to_owned());\n            line.clear();\n        }\n        let content = lines.join(\"\");\n        Ok(content.parse().unwrap())\n    }\n\n    #[test]\n    fn test_gen_expanded_code_blocks() -> io::Result<()> {\n        let entities = setup();\n        const ENTITY_FILES: [&str; 13] = [\n            include_str!(\"../../tests/expanded/cake.rs\"),\n            include_str!(\"../../tests/expanded/cake_filling.rs\"),\n            include_str!(\"../../tests/expanded/cake_filling_price.rs\"),\n            include_str!(\"../../tests/expanded/filling.rs\"),\n            include_str!(\"../../tests/expanded/fruit.rs\"),\n            include_str!(\"../../tests/expanded/vendor.rs\"),\n            include_str!(\"../../tests/expanded/rust_keyword.rs\"),\n            include_str!(\"../../tests/expanded/cake_with_float.rs\"),\n            include_str!(\"../../tests/expanded/cake_with_double.rs\"),\n            include_str!(\"../../tests/expanded/collection.rs\"),\n            include_str!(\"../../tests/expanded/collection_float.rs\"),\n            include_str!(\"../../tests/expanded/parent.rs\"),\n            include_str!(\"../../tests/expanded/child.rs\"),\n        ];\n        const ENTITY_FILES_WITH_SCHEMA_NAME: [&str; 13] = [\n            include_str!(\"../../tests/expanded_with_schema_name/cake.rs\"),\n            include_str!(\"../../tests/expanded_with_schema_name/cake_filling.rs\"),\n            include_str!(\"../../tests/expanded_with_schema_name/cake_filling_price.rs\"),\n            include_str!(\"../../tests/expanded_with_schema_name/filling.rs\"),\n            include_str!(\"../../tests/expanded_with_schema_name/fruit.rs\"),\n            include_str!(\"../../tests/expanded_with_schema_name/vendor.rs\"),\n            include_str!(\"../../tests/expanded_with_schema_name/rust_keyword.rs\"),\n            include_str!(\"../../tests/expanded_with_schema_name/cake_with_float.rs\"),\n            include_str!(\"../../tests/expanded_with_schema_name/cake_with_double.rs\"),\n            include_str!(\"../../tests/expanded_with_schema_name/collection.rs\"),\n            include_str!(\"../../tests/expanded_with_schema_name/collection_float.rs\"),\n            include_str!(\"../../tests/expanded_with_schema_name/parent.rs\"),\n            include_str!(\"../../tests/expanded_with_schema_name/child.rs\"),\n        ];\n\n        assert_eq!(entities.len(), ENTITY_FILES.len());\n\n        for (i, entity) in entities.iter().enumerate() {\n            assert_eq!(\n                parse_from_file(ENTITY_FILES[i].as_bytes())?.to_string(),\n                EntityWriter::gen_expanded_code_blocks(\n                    entity,\n                    &crate::WithSerde::None,\n                    &default_column_option(),\n                    &None,\n                    false,\n                    false,\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    false,\n                    true,\n                )\n                .into_iter()\n                .skip(1)\n                .fold(TokenStream::new(), |mut acc, tok| {\n                    acc.extend(tok);\n                    acc\n                })\n                .to_string()\n            );\n            assert_eq!(\n                parse_from_file(ENTITY_FILES_WITH_SCHEMA_NAME[i].as_bytes())?.to_string(),\n                EntityWriter::gen_expanded_code_blocks(\n                    entity,\n                    &crate::WithSerde::None,\n                    &default_column_option(),\n                    &Some(\"schema_name\".to_owned()),\n                    false,\n                    false,\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    false,\n                    true,\n                )\n                .into_iter()\n                .skip(1)\n                .fold(TokenStream::new(), |mut acc, tok| {\n                    acc.extend(tok);\n                    acc\n                })\n                .to_string()\n            );\n        }\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_gen_compact_code_blocks() -> io::Result<()> {\n        let entities = setup();\n        const ENTITY_FILES: [&str; 13] = [\n            include_str!(\"../../tests/compact/cake.rs\"),\n            include_str!(\"../../tests/compact/cake_filling.rs\"),\n            include_str!(\"../../tests/compact/cake_filling_price.rs\"),\n            include_str!(\"../../tests/compact/filling.rs\"),\n            include_str!(\"../../tests/compact/fruit.rs\"),\n            include_str!(\"../../tests/compact/vendor.rs\"),\n            include_str!(\"../../tests/compact/rust_keyword.rs\"),\n            include_str!(\"../../tests/compact/cake_with_float.rs\"),\n            include_str!(\"../../tests/compact/cake_with_double.rs\"),\n            include_str!(\"../../tests/compact/collection.rs\"),\n            include_str!(\"../../tests/compact/collection_float.rs\"),\n            include_str!(\"../../tests/compact/parent.rs\"),\n            include_str!(\"../../tests/compact/child.rs\"),\n        ];\n        const ENTITY_FILES_WITH_SCHEMA_NAME: [&str; 13] = [\n            include_str!(\"../../tests/compact_with_schema_name/cake.rs\"),\n            include_str!(\"../../tests/compact_with_schema_name/cake_filling.rs\"),\n            include_str!(\"../../tests/compact_with_schema_name/cake_filling_price.rs\"),\n            include_str!(\"../../tests/compact_with_schema_name/filling.rs\"),\n            include_str!(\"../../tests/compact_with_schema_name/fruit.rs\"),\n            include_str!(\"../../tests/compact_with_schema_name/vendor.rs\"),\n            include_str!(\"../../tests/compact_with_schema_name/rust_keyword.rs\"),\n            include_str!(\"../../tests/compact_with_schema_name/cake_with_float.rs\"),\n            include_str!(\"../../tests/compact_with_schema_name/cake_with_double.rs\"),\n            include_str!(\"../../tests/compact_with_schema_name/collection.rs\"),\n            include_str!(\"../../tests/compact_with_schema_name/collection_float.rs\"),\n            include_str!(\"../../tests/compact_with_schema_name/parent.rs\"),\n            include_str!(\"../../tests/compact_with_schema_name/child.rs\"),\n        ];\n\n        assert_eq!(entities.len(), ENTITY_FILES.len());\n\n        for (i, entity) in entities.iter().enumerate() {\n            assert_eq!(\n                parse_from_file(ENTITY_FILES[i].as_bytes())?.to_string(),\n                EntityWriter::gen_compact_code_blocks(\n                    entity,\n                    &crate::WithSerde::None,\n                    &default_column_option(),\n                    &None,\n                    false,\n                    false,\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    false,\n                    true,\n                )\n                .into_iter()\n                .skip(1)\n                .fold(TokenStream::new(), |mut acc, tok| {\n                    acc.extend(tok);\n                    acc\n                })\n                .to_string()\n            );\n            assert_eq!(\n                parse_from_file(ENTITY_FILES_WITH_SCHEMA_NAME[i].as_bytes())?.to_string(),\n                EntityWriter::gen_compact_code_blocks(\n                    entity,\n                    &crate::WithSerde::None,\n                    &default_column_option(),\n                    &Some(\"schema_name\".to_owned()),\n                    false,\n                    false,\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    false,\n                    true,\n                )\n                .into_iter()\n                .skip(1)\n                .fold(TokenStream::new(), |mut acc, tok| {\n                    acc.extend(tok);\n                    acc\n                })\n                .to_string()\n            );\n        }\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_gen_frontend_code_blocks() -> io::Result<()> {\n        let entities = setup();\n        const ENTITY_FILES: [&str; 13] = [\n            include_str!(\"../../tests/frontend/cake.rs\"),\n            include_str!(\"../../tests/frontend/cake_filling.rs\"),\n            include_str!(\"../../tests/frontend/cake_filling_price.rs\"),\n            include_str!(\"../../tests/frontend/filling.rs\"),\n            include_str!(\"../../tests/frontend/fruit.rs\"),\n            include_str!(\"../../tests/frontend/vendor.rs\"),\n            include_str!(\"../../tests/frontend/rust_keyword.rs\"),\n            include_str!(\"../../tests/frontend/cake_with_float.rs\"),\n            include_str!(\"../../tests/frontend/cake_with_double.rs\"),\n            include_str!(\"../../tests/frontend/collection.rs\"),\n            include_str!(\"../../tests/frontend/collection_float.rs\"),\n            include_str!(\"../../tests/frontend/parent.rs\"),\n            include_str!(\"../../tests/frontend/child.rs\"),\n        ];\n        const ENTITY_FILES_WITH_SCHEMA_NAME: [&str; 13] = [\n            include_str!(\"../../tests/frontend_with_schema_name/cake.rs\"),\n            include_str!(\"../../tests/frontend_with_schema_name/cake_filling.rs\"),\n            include_str!(\"../../tests/frontend_with_schema_name/cake_filling_price.rs\"),\n            include_str!(\"../../tests/frontend_with_schema_name/filling.rs\"),\n            include_str!(\"../../tests/frontend_with_schema_name/fruit.rs\"),\n            include_str!(\"../../tests/frontend_with_schema_name/vendor.rs\"),\n            include_str!(\"../../tests/frontend_with_schema_name/rust_keyword.rs\"),\n            include_str!(\"../../tests/frontend_with_schema_name/cake_with_float.rs\"),\n            include_str!(\"../../tests/frontend_with_schema_name/cake_with_double.rs\"),\n            include_str!(\"../../tests/frontend_with_schema_name/collection.rs\"),\n            include_str!(\"../../tests/frontend_with_schema_name/collection_float.rs\"),\n            include_str!(\"../../tests/frontend_with_schema_name/parent.rs\"),\n            include_str!(\"../../tests/frontend_with_schema_name/child.rs\"),\n        ];\n\n        assert_eq!(entities.len(), ENTITY_FILES.len());\n\n        for (i, entity) in entities.iter().enumerate() {\n            assert_eq!(\n                dbg!(parse_from_frontend_file(ENTITY_FILES[i].as_bytes())?.to_string()),\n                EntityWriter::gen_frontend_code_blocks(\n                    entity,\n                    &crate::WithSerde::None,\n                    &default_column_option(),\n                    &None,\n                    false,\n                    false,\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    false,\n                    true,\n                )\n                .into_iter()\n                .skip(1)\n                .fold(TokenStream::new(), |mut acc, tok| {\n                    acc.extend(tok);\n                    acc\n                })\n                .to_string()\n            );\n            assert_eq!(\n                parse_from_frontend_file(ENTITY_FILES_WITH_SCHEMA_NAME[i].as_bytes())?.to_string(),\n                EntityWriter::gen_frontend_code_blocks(\n                    entity,\n                    &crate::WithSerde::None,\n                    &default_column_option(),\n                    &Some(\"schema_name\".to_owned()),\n                    false,\n                    false,\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    false,\n                    true,\n                )\n                .into_iter()\n                .skip(1)\n                .fold(TokenStream::new(), |mut acc, tok| {\n                    acc.extend(tok);\n                    acc\n                })\n                .to_string()\n            );\n        }\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_gen_with_serde() -> io::Result<()> {\n        let cake_entity = setup().get(0).unwrap().clone();\n\n        assert_eq!(cake_entity.get_table_name_snake_case(), \"cake\");\n\n        // Compact code blocks\n        assert_eq!(\n            comparable_file_string(include_str!(\"../../tests/compact_with_serde/cake_none.rs\"))?,\n            generated_to_string(EntityWriter::gen_compact_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/compact_with_serde/cake_serialize.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_compact_code_blocks(\n                &cake_entity,\n                &WithSerde::Serialize,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/compact_with_serde/cake_deserialize.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_compact_code_blocks(\n                &cake_entity,\n                &WithSerde::Deserialize,\n                &default_column_option(),\n                &None,\n                true,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\"../../tests/compact_with_serde/cake_both.rs\"))?,\n            generated_to_string(EntityWriter::gen_compact_code_blocks(\n                &cake_entity,\n                &WithSerde::Both,\n                &default_column_option(),\n                &None,\n                true,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n\n        // Expanded code blocks\n        assert_eq!(\n            comparable_file_string(include_str!(\"../../tests/expanded_with_serde/cake_none.rs\"))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/expanded_with_serde/cake_serialize.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::Serialize,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/expanded_with_serde/cake_deserialize.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::Deserialize,\n                &default_column_option(),\n                &None,\n                true,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\"../../tests/expanded_with_serde/cake_both.rs\"))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::Both,\n                &default_column_option(),\n                &None,\n                true,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n\n        // Frontend code blocks\n        assert_eq!(\n            comparable_file_string(include_str!(\"../../tests/frontend_with_serde/cake_none.rs\"))?,\n            generated_to_string(EntityWriter::gen_frontend_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/frontend_with_serde/cake_serialize.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_frontend_code_blocks(\n                &cake_entity,\n                &WithSerde::Serialize,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/frontend_with_serde/cake_deserialize.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_frontend_code_blocks(\n                &cake_entity,\n                &WithSerde::Deserialize,\n                &default_column_option(),\n                &None,\n                true,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\"../../tests/frontend_with_serde/cake_both.rs\"))?,\n            generated_to_string(EntityWriter::gen_frontend_code_blocks(\n                &cake_entity,\n                &WithSerde::Both,\n                &default_column_option(),\n                &None,\n                true,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_gen_with_seaography() -> io::Result<()> {\n        let cake_entity = Entity {\n            table_name: \"cake\".to_owned(),\n            columns: vec![\n                Column {\n                    name: \"id\".to_owned(),\n                    col_type: ColumnType::Integer,\n                    auto_increment: true,\n                    not_null: true,\n                    unique: false,\n                    unique_key: None,\n                },\n                Column {\n                    name: \"name\".to_owned(),\n                    col_type: ColumnType::Text,\n                    auto_increment: false,\n                    not_null: false,\n                    unique: false,\n                    unique_key: None,\n                },\n                Column {\n                    name: \"base_id\".to_owned(),\n                    col_type: ColumnType::Integer,\n                    auto_increment: false,\n                    not_null: false,\n                    unique: false,\n                    unique_key: None,\n                },\n            ],\n            relations: vec![\n                Relation {\n                    ref_table: \"fruit\".to_owned(),\n                    columns: vec![],\n                    ref_columns: vec![],\n                    rel_type: RelationType::HasMany,\n                    on_delete: None,\n                    on_update: None,\n                    self_referencing: false,\n                    num_suffix: 0,\n                    impl_related: true,\n                },\n                Relation {\n                    ref_table: \"cake\".to_owned(),\n                    columns: vec![],\n                    ref_columns: vec![],\n                    rel_type: RelationType::HasOne,\n                    on_delete: None,\n                    on_update: None,\n                    self_referencing: true,\n                    num_suffix: 0,\n                    impl_related: true,\n                },\n            ],\n            conjunct_relations: vec![ConjunctRelation {\n                via: \"cake_filling\".to_owned(),\n                to: \"filling\".to_owned(),\n            }],\n            primary_keys: vec![PrimaryKey {\n                name: \"id\".to_owned(),\n            }],\n        };\n\n        assert_eq!(cake_entity.get_table_name_snake_case(), \"cake\");\n\n        // Compact code blocks\n        assert_eq!(\n            comparable_file_string(include_str!(\"../../tests/with_seaography/cake.rs\"))?,\n            generated_to_string(EntityWriter::gen_compact_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                true,\n                true,\n            ))\n        );\n\n        // Expanded code blocks\n        assert_eq!(\n            comparable_file_string(include_str!(\"../../tests/with_seaography/cake_expanded.rs\"))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                true,\n                true,\n            ))\n        );\n\n        // Frontend code blocks\n        assert_eq!(\n            comparable_file_string(include_str!(\"../../tests/with_seaography/cake_frontend.rs\"))?,\n            generated_to_string(EntityWriter::gen_frontend_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                true,\n                true,\n            ))\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_gen_with_seaography_mod() -> io::Result<()> {\n        use crate::ActiveEnum;\n        use sea_query::IntoIden;\n\n        let entities = setup();\n        let enums = vec![\n            (\n                \"coinflip_result_type\",\n                ActiveEnum {\n                    enum_name: Alias::new(\"coinflip_result_type\").into_iden(),\n                    values: vec![\"HEADS\", \"TAILS\"]\n                        .into_iter()\n                        .map(|variant| Alias::new(variant).into_iden())\n                        .collect(),\n                },\n            ),\n            (\n                \"media_type\",\n                ActiveEnum {\n                    enum_name: Alias::new(\"media_type\").into_iden(),\n                    values: vec![\n                        \"UNKNOWN\",\n                        \"BITMAP\",\n                        \"DRAWING\",\n                        \"AUDIO\",\n                        \"VIDEO\",\n                        \"MULTIMEDIA\",\n                        \"OFFICE\",\n                        \"TEXT\",\n                        \"EXECUTABLE\",\n                        \"ARCHIVE\",\n                        \"3D\",\n                    ]\n                    .into_iter()\n                    .map(|variant| Alias::new(variant).into_iden())\n                    .collect(),\n                },\n            ),\n        ]\n        .into_iter()\n        .map(|(k, v)| (k.to_string(), v))\n        .collect();\n\n        assert_eq!(\n            comparable_file_string(include_str!(\"../../tests/with_seaography/mod.rs\"))?,\n            generated_to_string(vec![EntityWriter::gen_seaography_entity_mod(\n                &entities, &enums,\n            )])\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_gen_with_derives() -> io::Result<()> {\n        let mut cake_entity = setup().get_mut(0).unwrap().clone();\n\n        assert_eq!(cake_entity.get_table_name_snake_case(), \"cake\");\n\n        // Compact code blocks\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/compact_with_derives/cake_none.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_compact_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\"../../tests/compact_with_derives/cake_one.rs\"))?,\n            generated_to_string(EntityWriter::gen_compact_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &bonus_derive([\"ts_rs::TS\"]),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/compact_with_derives/cake_multiple.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_compact_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &bonus_derive([\"ts_rs::TS\", \"utoipa::ToSchema\"]),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n\n        // Expanded code blocks\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/expanded_with_derives/cake_none.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/expanded_with_derives/cake_one.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &bonus_derive([\"ts_rs::TS\"]),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/expanded_with_derives/cake_multiple.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &bonus_derive([\"ts_rs::TS\", \"utoipa::ToSchema\"]),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n\n        // Frontend code blocks\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/frontend_with_derives/cake_none.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_frontend_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/frontend_with_derives/cake_one.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_frontend_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &bonus_derive([\"ts_rs::TS\"]),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/frontend_with_derives/cake_multiple.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_frontend_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &bonus_derive([\"ts_rs::TS\", \"utoipa::ToSchema\"]),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n\n        // Make the `name` column of `cake` entity as hidden column\n        cake_entity.columns[1].name = \"_name\".into();\n\n        assert_serde_variant_results(\n            &cake_entity,\n            &(\n                include_str!(\"../../tests/compact_with_serde/cake_serialize_with_hidden_column.rs\"),\n                WithSerde::Serialize,\n                None,\n            ),\n            Box::new(EntityWriter::gen_compact_code_blocks),\n        )?;\n        assert_serde_variant_results(\n            &cake_entity,\n            &(\n                include_str!(\n                    \"../../tests/expanded_with_serde/cake_serialize_with_hidden_column.rs\"\n                ),\n                WithSerde::Serialize,\n                None,\n            ),\n            Box::new(EntityWriter::gen_expanded_code_blocks),\n        )?;\n        assert_serde_variant_results(\n            &cake_entity,\n            &(\n                include_str!(\n                    \"../../tests/frontend_with_serde/cake_serialize_with_hidden_column.rs\"\n                ),\n                WithSerde::Serialize,\n                None,\n            ),\n            Box::new(EntityWriter::gen_frontend_code_blocks),\n        )?;\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_gen_with_column_derives() -> io::Result<()> {\n        let cake_entity = setup().get_mut(0).unwrap().clone();\n\n        assert_eq!(cake_entity.get_table_name_snake_case(), \"cake\");\n\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/expanded_with_column_derives/cake_one.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &bonus_derive([\"async_graphql::Enum\"]),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/expanded_with_column_derives/cake_multiple.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &bonus_derive([\"async_graphql::Enum\", \"Eq\", \"PartialEq\"]),\n                false,\n                true,\n            ))\n        );\n\n        Ok(())\n    }\n\n    #[allow(clippy::type_complexity)]\n    fn assert_serde_variant_results(\n        cake_entity: &Entity,\n        entity_serde_variant: &(&str, WithSerde, Option<String>),\n        generator: Box<\n            dyn Fn(\n                &Entity,\n                &WithSerde,\n                &ColumnOption,\n                &Option<String>,\n                bool,\n                bool,\n                &TokenStream,\n                &TokenStream,\n                &TokenStream,\n                bool,\n                bool,\n            ) -> Vec<TokenStream>,\n        >,\n    ) -> io::Result<()> {\n        let mut reader = BufReader::new(entity_serde_variant.0.as_bytes());\n        let mut lines: Vec<String> = Vec::new();\n        let serde_skip_deserializing_primary_key = matches!(\n            entity_serde_variant.1,\n            WithSerde::Both | WithSerde::Deserialize\n        );\n        let serde_skip_hidden_column = matches!(entity_serde_variant.1, WithSerde::Serialize);\n\n        reader.read_until(b'\\n', &mut Vec::new())?;\n\n        let mut line = String::new();\n        while reader.read_line(&mut line)? > 0 {\n            lines.push(line.to_owned());\n            line.clear();\n        }\n        let content = lines.join(\"\");\n        let expected: TokenStream = content.parse().unwrap();\n        println!(\"{:?}\", entity_serde_variant.1);\n        let generated = generator(\n            cake_entity,\n            &entity_serde_variant.1,\n            &default_column_option(),\n            &entity_serde_variant.2,\n            serde_skip_deserializing_primary_key,\n            serde_skip_hidden_column,\n            &TokenStream::new(),\n            &TokenStream::new(),\n            &TokenStream::new(),\n            false,\n            true,\n        )\n        .into_iter()\n        .fold(TokenStream::new(), |mut acc, tok| {\n            acc.extend(tok);\n            acc\n        });\n\n        assert_eq!(expected.to_string(), generated.to_string());\n        Ok(())\n    }\n\n    #[test]\n    fn test_gen_with_attributes() -> io::Result<()> {\n        let cake_entity = setup().get(0).unwrap().clone();\n\n        assert_eq!(cake_entity.get_table_name_snake_case(), \"cake\");\n\n        // Compact code blocks\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/compact_with_attributes/cake_none.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_compact_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/compact_with_attributes/cake_one.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_compact_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &bonus_attributes([r#\"serde(rename_all = \"camelCase\")\"#]),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/compact_with_attributes/cake_multiple.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_compact_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &bonus_attributes([r#\"serde(rename_all = \"camelCase\")\"#, \"ts(export)\"]),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n\n        // Expanded code blocks\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/expanded_with_attributes/cake_none.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/expanded_with_attributes/cake_one.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &bonus_attributes([r#\"serde(rename_all = \"camelCase\")\"#]),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/expanded_with_attributes/cake_multiple.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_expanded_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &bonus_attributes([r#\"serde(rename_all = \"camelCase\")\"#, \"ts(export)\"]),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n\n        // Frontend code blocks\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/frontend_with_attributes/cake_none.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_frontend_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &TokenStream::new(),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/frontend_with_attributes/cake_one.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_frontend_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &bonus_attributes([r#\"serde(rename_all = \"camelCase\")\"#]),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n        assert_eq!(\n            comparable_file_string(include_str!(\n                \"../../tests/frontend_with_attributes/cake_multiple.rs\"\n            ))?,\n            generated_to_string(EntityWriter::gen_frontend_code_blocks(\n                &cake_entity,\n                &WithSerde::None,\n                &default_column_option(),\n                &None,\n                false,\n                false,\n                &TokenStream::new(),\n                &bonus_attributes([r#\"serde(rename_all = \"camelCase\")\"#, \"ts(export)\"]),\n                &TokenStream::new(),\n                false,\n                true,\n            ))\n        );\n\n        Ok(())\n    }\n\n    fn generated_to_string(generated: Vec<TokenStream>) -> String {\n        generated\n            .into_iter()\n            .fold(TokenStream::new(), |mut acc, tok| {\n                acc.extend(tok);\n                acc\n            })\n            .to_string()\n    }\n\n    fn comparable_file_string(file: &str) -> io::Result<String> {\n        let mut reader = BufReader::new(file.as_bytes());\n        let mut lines: Vec<String> = Vec::new();\n\n        reader.read_until(b'\\n', &mut Vec::new())?;\n\n        let mut line = String::new();\n        while reader.read_line(&mut line)? > 0 {\n            lines.push(line.to_owned());\n            line.clear();\n        }\n        let content = lines.join(\"\");\n        let expected: TokenStream = content.parse().unwrap();\n\n        Ok(expected.to_string())\n    }\n\n    #[test]\n    fn test_gen_postgres() -> io::Result<()> {\n        let entities = vec![\n            // This tests that the JsonBinary column type is annotated\n            // correctly in compact entity form. More information can be found\n            // in this issue:\n            //\n            // https://github.com/SeaQL/sea-orm/issues/1344\n            Entity {\n                table_name: \"task\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"payload\".to_owned(),\n                        col_type: ColumnType::Json,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"payload_binary\".to_owned(),\n                        col_type: ColumnType::JsonBinary,\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![],\n                conjunct_relations: vec![],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n        ];\n        const ENTITY_FILES: [&str; 1] = [include_str!(\"../../tests/postgres/binary_json.rs\")];\n\n        const ENTITY_FILES_EXPANDED: [&str; 1] =\n            [include_str!(\"../../tests/postgres/binary_json_expanded.rs\")];\n\n        assert_eq!(entities.len(), ENTITY_FILES.len());\n\n        for (i, entity) in entities.iter().enumerate() {\n            assert_eq!(\n                parse_from_file(ENTITY_FILES[i].as_bytes())?.to_string(),\n                EntityWriter::gen_compact_code_blocks(\n                    entity,\n                    &crate::WithSerde::None,\n                    &default_column_option(),\n                    &None,\n                    false,\n                    false,\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    false,\n                    true,\n                )\n                .into_iter()\n                .skip(1)\n                .fold(TokenStream::new(), |mut acc, tok| {\n                    acc.extend(tok);\n                    acc\n                })\n                .to_string()\n            );\n            assert_eq!(\n                parse_from_file(ENTITY_FILES_EXPANDED[i].as_bytes())?.to_string(),\n                EntityWriter::gen_expanded_code_blocks(\n                    entity,\n                    &crate::WithSerde::None,\n                    &default_column_option(),\n                    &Some(\"schema_name\".to_owned()),\n                    false,\n                    false,\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    false,\n                    true,\n                )\n                .into_iter()\n                .skip(1)\n                .fold(TokenStream::new(), |mut acc, tok| {\n                    acc.extend(tok);\n                    acc\n                })\n                .to_string()\n            );\n        }\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_gen_import_active_enum() -> io::Result<()> {\n        let entities = vec![\n            Entity {\n                table_name: \"tea_pairing\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"first_tea\".to_owned(),\n                        col_type: ColumnType::Enum {\n                            name: SeaRc::new(Alias::new(\"tea_enum\")),\n                            variants: vec![\n                                SeaRc::new(Alias::new(\"everyday_tea\")),\n                                SeaRc::new(Alias::new(\"breakfast_tea\")),\n                            ],\n                        },\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"second_tea\".to_owned(),\n                        col_type: ColumnType::Enum {\n                            name: SeaRc::new(Alias::new(\"tea_enum\")),\n                            variants: vec![\n                                SeaRc::new(Alias::new(\"everyday_tea\")),\n                                SeaRc::new(Alias::new(\"breakfast_tea\")),\n                            ],\n                        },\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![],\n                conjunct_relations: vec![],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n            Entity {\n                table_name: \"tea_pairing_with_size\".to_owned(),\n                columns: vec![\n                    Column {\n                        name: \"id\".to_owned(),\n                        col_type: ColumnType::Integer,\n                        auto_increment: true,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"first_tea\".to_owned(),\n                        col_type: ColumnType::Enum {\n                            name: SeaRc::new(Alias::new(\"tea_enum\")),\n                            variants: vec![\n                                SeaRc::new(Alias::new(\"everyday_tea\")),\n                                SeaRc::new(Alias::new(\"breakfast_tea\")),\n                            ],\n                        },\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"second_tea\".to_owned(),\n                        col_type: ColumnType::Enum {\n                            name: SeaRc::new(Alias::new(\"tea_enum\")),\n                            variants: vec![\n                                SeaRc::new(Alias::new(\"everyday_tea\")),\n                                SeaRc::new(Alias::new(\"breakfast_tea\")),\n                            ],\n                        },\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                    Column {\n                        name: \"size\".to_owned(),\n                        col_type: ColumnType::Enum {\n                            name: SeaRc::new(Alias::new(\"tea_size\")),\n                            variants: vec![\n                                SeaRc::new(Alias::new(\"small\")),\n                                SeaRc::new(Alias::new(\"medium\")),\n                                SeaRc::new(Alias::new(\"huge\")),\n                            ],\n                        },\n                        auto_increment: false,\n                        not_null: true,\n                        unique: false,\n                        unique_key: None,\n                    },\n                ],\n                relations: vec![],\n                conjunct_relations: vec![],\n                primary_keys: vec![PrimaryKey {\n                    name: \"id\".to_owned(),\n                }],\n            },\n        ];\n\n        assert_eq!(\n            quote!(\n                use super::sea_orm_active_enums::TeaEnum;\n            )\n            .to_string(),\n            EntityWriter::gen_import_active_enum(&entities[0]).to_string()\n        );\n\n        assert_eq!(\n            quote!(\n                use super::sea_orm_active_enums::TeaEnum;\n                use super::sea_orm_active_enums::TeaSize;\n            )\n            .to_string(),\n            EntityWriter::gen_import_active_enum(&entities[1]).to_string()\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_gen_dense_code_blocks() -> io::Result<()> {\n        let entities = setup();\n        const ENTITY_FILES: [&str; 13] = [\n            include_str!(\"../../tests/dense/cake.rs\"),\n            include_str!(\"../../tests/dense/cake_filling.rs\"),\n            include_str!(\"../../tests/dense/cake_filling_price.rs\"),\n            include_str!(\"../../tests/dense/filling.rs\"),\n            include_str!(\"../../tests/dense/fruit.rs\"),\n            include_str!(\"../../tests/dense/vendor.rs\"),\n            include_str!(\"../../tests/dense/rust_keyword.rs\"),\n            include_str!(\"../../tests/dense/cake_with_float.rs\"),\n            include_str!(\"../../tests/dense/cake_with_double.rs\"),\n            include_str!(\"../../tests/dense/collection.rs\"),\n            include_str!(\"../../tests/dense/collection_float.rs\"),\n            include_str!(\"../../tests/dense/parent.rs\"),\n            include_str!(\"../../tests/dense/child.rs\"),\n        ];\n\n        assert_eq!(entities.len(), ENTITY_FILES.len());\n\n        for (i, entity) in entities.iter().enumerate() {\n            assert_eq!(\n                parse_from_file(ENTITY_FILES[i].as_bytes())?.to_string(),\n                EntityWriter::gen_dense_code_blocks(\n                    entity,\n                    &crate::WithSerde::None,\n                    &default_column_option(),\n                    &None,\n                    false,\n                    false,\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    &TokenStream::new(),\n                    false,\n                    true,\n                )\n                .into_iter()\n                .skip(1)\n                .fold(TokenStream::new(), |mut acc, tok| {\n                    acc.extend(tok);\n                    acc\n                })\n                .to_string()\n            );\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/error.rs",
    "content": "use std::{error, fmt, io};\n\n#[derive(Debug)]\npub enum Error {\n    StdIoError(io::Error),\n    TransformError(String),\n}\n\nimpl fmt::Display for Error {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match self {\n            Self::StdIoError(e) => write!(f, \"{e:?}\"),\n            Self::TransformError(e) => write!(f, \"{e:?}\"),\n        }\n    }\n}\n\nimpl error::Error for Error {\n    fn source(&self) -> Option<&(dyn error::Error + 'static)> {\n        match self {\n            Self::StdIoError(e) => Some(e),\n            Self::TransformError(_) => None,\n        }\n    }\n}\n\nimpl From<io::Error> for Error {\n    fn from(io_err: io::Error) -> Self {\n        Self::StdIoError(io_err)\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/lib.rs",
    "content": "mod entity;\nmod error;\nmod merge;\nmod util;\n\npub use entity::*;\npub use error::*;\npub use merge::*;\n\n#[cfg(test)]\nmod tests_cfg;\n"
  },
  {
    "path": "sea-orm-codegen/src/merge/extract.rs",
    "content": "use super::is_active_model_behavior_impl;\nuse syn::File;\nuse syn::Item;\nuse syn::ItemEnum;\nuse syn::ItemImpl;\nuse syn::ItemStruct;\nuse syn::ItemUse;\n\npub(super) fn extract_active_model_behavior_impls(file: &File) -> impl Iterator<Item = &ItemImpl> {\n    file.items.iter().filter_map(|item| match item {\n        Item::Impl(item_impl) if is_active_model_behavior_impl(item_impl) => Some(item_impl),\n        _ => None,\n    })\n}\n\npub(super) fn extract_top_level_uses(file: &File) -> impl Iterator<Item = &ItemUse> {\n    file.items.iter().filter_map(|item| match item {\n        Item::Use(item_use) => Some(item_use),\n        _ => None,\n    })\n}\n\npub(super) fn find_model_struct(file: &File) -> Option<&ItemStruct> {\n    file.items.iter().find_map(|item| {\n        if let Item::Struct(item_struct) = item {\n            if item_struct.ident == \"Model\" {\n                return Some(item_struct);\n            }\n        }\n        None\n    })\n}\n\npub(super) fn find_relation_enum(file: &File) -> Option<&ItemEnum> {\n    file.items.iter().find_map(|item| {\n        if let Item::Enum(item_enum) = item {\n            if item_enum.ident == \"Relation\" {\n                return Some(item_enum);\n            }\n        }\n        None\n    })\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/merge/mod.rs",
    "content": "use std::collections::{HashMap, HashSet};\n\nuse prettyplease::unparse;\nuse syn::fold::{self, Fold};\nuse syn::{\n    Attribute, Fields, Ident, Item, ItemImpl, Path, parse::Parser, parse_file,\n    punctuated::Punctuated,\n};\nuse syn::{ItemUse, Meta};\n\nmod extract;\nuse extract::*;\n\n#[derive(Default)]\nstruct OldIndex<'a> {\n    model_attrs: &'a [Attribute],\n    model_field_attrs: HashMap<&'a Ident, &'a [Attribute]>,\n\n    relation_attrs: &'a [Attribute],\n    relation_variant_attrs: HashMap<&'a Ident, &'a [Attribute]>,\n}\n\nimpl<'a> OldIndex<'a> {\n    fn from_file(file: &'a syn::File) -> OldIndex<'a> {\n        let mut idx = OldIndex::default();\n\n        if let Some(model) = find_model_struct(file) {\n            idx.model_attrs = &model.attrs;\n            if let Fields::Named(named) = &model.fields {\n                for field in &named.named {\n                    if let Some(ident) = &field.ident {\n                        idx.model_field_attrs.insert(ident, &field.attrs);\n                    }\n                }\n            }\n        }\n\n        if let Some(relation) = find_relation_enum(file) {\n            idx.relation_attrs = &relation.attrs;\n            for variant in &relation.variants {\n                idx.relation_variant_attrs\n                    .insert(&variant.ident, &variant.attrs);\n            }\n        }\n\n        idx\n    }\n}\n\nstruct Merger<'a> {\n    old: OldIndex<'a>,\n    seen_use: HashSet<ItemUse>,\n    extra_uses: Vec<&'a syn::ItemUse>,\n    old_behaviors: Vec<&'a syn::ItemImpl>,\n}\n\nimpl<'a> Merger<'a> {\n    fn new(\n        old: OldIndex<'a>,\n        extra_uses: Vec<&'a syn::ItemUse>,\n        old_behaviors: Vec<&'a syn::ItemImpl>,\n    ) -> Self {\n        Self {\n            old,\n            seen_use: HashSet::new(),\n            extra_uses,\n            old_behaviors,\n        }\n    }\n}\n\nimpl<'a> Fold for Merger<'a> {\n    fn fold_item_struct(&mut self, i: syn::ItemStruct) -> syn::ItemStruct {\n        let mut i = fold::fold_item_struct(self, i);\n        if i.ident == \"Model\" {\n            merge_item_attributes(&mut i.attrs, self.old.model_attrs);\n            if let Fields::Named(named) = &mut i.fields {\n                for field in &mut named.named {\n                    if let Some(ident) = &field.ident {\n                        if let Some(old_attrs) = self.old.model_field_attrs.get(ident) {\n                            merge_item_attributes(&mut field.attrs, old_attrs);\n                        }\n                    }\n                }\n            }\n        }\n        i\n    }\n\n    fn fold_item_enum(&mut self, i: syn::ItemEnum) -> syn::ItemEnum {\n        let mut i = fold::fold_item_enum(self, i);\n        if i.ident == \"Relation\" {\n            merge_item_attributes(&mut i.attrs, self.old.relation_attrs);\n            for variant in &mut i.variants {\n                if let Some(old_attrs) = self.old.relation_variant_attrs.get(&variant.ident) {\n                    merge_item_attributes(&mut variant.attrs, old_attrs);\n                }\n            }\n        }\n        i\n    }\n\n    fn fold_file(&mut self, mut file: syn::File) -> syn::File {\n        let mut uses: Vec<Item> = Vec::new();\n        let mut others: Vec<Item> = Vec::new();\n\n        for item in file.items {\n            match item {\n                Item::Use(u) => {\n                    let u = fold::fold_item_use(self, u);\n                    if self.seen_use.insert(u.clone()) {\n                        uses.push(Item::Use(u));\n                    }\n                }\n                Item::Impl(i) => {\n                    if is_active_model_behavior_impl(&i) {\n                        continue;\n                    }\n                    let i = fold::fold_item_impl(self, i);\n                    others.push(Item::Impl(i));\n                }\n                other => {\n                    let other = fold::fold_item(self, other);\n                    others.push(other);\n                }\n            }\n        }\n\n        for &u in &self.extra_uses {\n            if self.seen_use.insert(u.clone()) {\n                uses.push(Item::Use(u.clone()));\n            }\n        }\n\n        for &i in &self.old_behaviors {\n            others.push(Item::Impl(i.clone()));\n        }\n\n        file.items = {\n            let mut v = Vec::with_capacity(uses.len() + others.len());\n            v.extend(uses);\n            v.extend(others);\n            v\n        };\n        file\n    }\n}\n\n#[derive(Debug, Default)]\n#[doc(hidden)]\npub struct MergeReport {\n    pub output: String,\n    pub warnings: Vec<String>,\n    pub fallback_applied: bool,\n}\n\nimpl MergeReport {\n    fn fallback(old_src: &str, new_src: &str) -> Self {\n        let mut warnings = Vec::new();\n        let mut appended = String::from(new_src);\n\n        warnings.push(\n            \"Parsing failed. The previous file content has been preserved as comments at the end.\"\n                .to_owned(),\n        );\n\n        if !appended.ends_with(\"\\n\\n\") {\n            appended.push('\\n');\n        }\n\n        appended.push_str(\n            \"// --- Preserved original file content (could not be merged automatically) ---\\n\",\n        );\n        appended.push_str(\"/*\\n\");\n        appended.push_str(old_src);\n        if !old_src.ends_with('\\n') {\n            appended.push('\\n');\n        }\n        appended.push_str(\"*/\\n\\n\");\n\n        MergeReport {\n            output: appended,\n            warnings,\n            fallback_applied: true,\n        }\n    }\n}\n\n#[doc(hidden)]\npub fn merge_entity_files(old_src: &str, new_src: &str) -> Result<String, MergeReport> {\n    let new_file = match parse_file(new_src) {\n        Ok(file) => file,\n        Err(err) => {\n            let mut report = MergeReport::fallback(old_src, new_src);\n            report.warnings.push(format!(\n                \"Unable to parse new file, generated fallback: {err}\"\n            ));\n            return Err(report);\n        }\n    };\n\n    let old_file = match parse_file(old_src) {\n        Ok(file) => file,\n        Err(err) => {\n            let mut report = MergeReport::fallback(old_src, new_src);\n            report.warnings.push(format!(\n                \"Unable to parse old file, generated fallback: {err}\"\n            ));\n            return Err(report);\n        }\n    };\n\n    let old_index = OldIndex::from_file(&old_file);\n    let extra_uses = extract_top_level_uses(&old_file).collect::<Vec<_>>();\n    let old_behaviors = extract_active_model_behavior_impls(&old_file).collect::<Vec<_>>();\n    let mut folder = Merger::new(old_index, extra_uses, old_behaviors);\n    let merged_file = folder.fold_file(new_file);\n\n    let output = render_file_with_spacing(merged_file);\n    Ok(output)\n}\n\nfn merge_item_attributes(new_attrs: &mut Vec<Attribute>, old_attrs: &[Attribute]) {\n    merge_derives(new_attrs, old_attrs);\n\n    let mut path_idx_map = HashMap::<Path, usize>::new();\n    let mut doc_attr_set = HashSet::<Attribute>::new();\n\n    for (idx, attr) in new_attrs.iter().enumerate() {\n        if is_doc_attribute(attr) {\n            doc_attr_set.insert(attr.clone());\n            continue;\n        }\n        if attr.path().is_ident(\"derive\") {\n            continue;\n        }\n        path_idx_map.entry(attr.path().clone()).or_insert(idx);\n    }\n\n    for old_attr in old_attrs {\n        if old_attr.path().is_ident(\"derive\") {\n            continue;\n        }\n\n        if is_doc_attribute(old_attr) {\n            if !doc_attr_set.contains(old_attr) {\n                doc_attr_set.insert(old_attr.clone());\n                new_attrs.push(old_attr.clone());\n            }\n            continue;\n        }\n\n        if let Some(&idx) = path_idx_map.get(old_attr.path()) {\n            let current = &new_attrs[idx];\n            if let Some(merged) = merge_non_derive_attribute(old_attr, current) {\n                new_attrs[idx] = merged;\n            }\n        } else {\n            path_idx_map.insert(old_attr.path().clone(), new_attrs.len());\n            new_attrs.push(old_attr.clone());\n        }\n    }\n}\n\nfn merge_derives(new_attrs: &mut Vec<Attribute>, old_attrs: &[Attribute]) {\n    let mut derive_paths: Vec<Path> = Vec::new();\n    let mut seen = HashSet::new();\n    let mut insert_index = None;\n    let mut idx = 0usize;\n    while idx < new_attrs.len() {\n        if new_attrs[idx].path().is_ident(\"derive\") {\n            insert_index.get_or_insert(idx);\n            if let Some(paths) = parse_derive_paths(&new_attrs[idx]) {\n                for path in paths {\n                    if seen.insert(path.clone()) {\n                        derive_paths.push(path);\n                    }\n                }\n            }\n            new_attrs.remove(idx);\n        } else {\n            idx += 1;\n        }\n    }\n\n    for attr in old_attrs\n        .iter()\n        .filter(|attr| attr.path().is_ident(\"derive\"))\n    {\n        if let Some(paths) = parse_derive_paths(attr) {\n            for path in paths {\n                if seen.insert(path.clone()) {\n                    derive_paths.push(path);\n                }\n            }\n        }\n    }\n\n    if derive_paths.is_empty() {\n        return;\n    }\n\n    if insert_index.is_none() {\n        insert_index = Some(\n            new_attrs\n                .iter()\n                .position(|attr| !is_doc_attribute(attr))\n                .unwrap_or(0),\n        );\n    }\n\n    let derive_attr: Attribute = syn::parse_quote!(#[derive(#(#derive_paths),*)]);\n    new_attrs.insert(insert_index.unwrap_or(0), derive_attr);\n}\n\nfn parse_derive_paths(attr: &Attribute) -> Option<Vec<Path>> {\n    attr.parse_args_with(Punctuated::<Path, syn::Token![,]>::parse_terminated)\n        .ok()\n        .map(|punct| punct.into_iter().collect())\n}\n\nfn merge_non_derive_attribute(old_attr: &Attribute, new_attr: &Attribute) -> Option<Attribute> {\n    use syn::{Token, punctuated::Punctuated};\n\n    let parse_attr = |attr: &Attribute| {\n        attr.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)\n            .ok()\n    };\n\n    let old_args = parse_attr(old_attr)?;\n    let new_args = parse_attr(new_attr)?;\n\n    fn meta_key(meta: &Meta) -> &Path {\n        match meta {\n            Meta::Path(p) => p,\n            Meta::NameValue(nv) => &nv.path,\n            Meta::List(list) => &list.path,\n        }\n    }\n\n    let mut seen_keys = HashSet::<Path>::new();\n    let mut merged: Vec<Meta> = Vec::new();\n\n    for m in old_args.into_iter() {\n        // Always preserve old attribute values on key conflict\n        seen_keys.insert(meta_key(&m).clone());\n        merged.push(m);\n    }\n\n    for m in new_args.into_iter() {\n        let key = meta_key(&m);\n        if !seen_keys.contains(key) {\n            seen_keys.insert(key.clone());\n            merged.push(m);\n        }\n    }\n\n    let path = old_attr.path();\n    let tokens = quote::quote!(#[#path(#(#merged),*)]);\n    Attribute::parse_outer\n        .parse2(tokens)\n        .ok()\n        .and_then(|v| v.into_iter().next())\n}\n\nfn is_active_model_behavior_impl(item_impl: &ItemImpl) -> bool {\n    let trait_ident = item_impl\n        .trait_\n        .as_ref()\n        .and_then(|(_, path, _)| path.segments.last())\n        .map(|segment| &segment.ident);\n    let self_ident = match item_impl.self_ty.as_ref() {\n        syn::Type::Path(type_path) => type_path.path.segments.last().map(|seg| &seg.ident),\n        _ => None,\n    };\n    matches!(trait_ident, Some(ident) if ident == \"ActiveModelBehavior\")\n        && matches!(self_ident, Some(ident) if ident == \"ActiveModel\")\n}\n\nfn is_doc_attribute(attr: &Attribute) -> bool {\n    attr.path().is_ident(\"doc\")\n}\n\nfn render_file_with_spacing(file: syn::File) -> String {\n    fn trim_trailing_newlines(s: &str) -> &str {\n        s.trim_end_matches(['\\n', '\\r'])\n    }\n\n    fn render_items_with_sep(items: &[Item], separator: &str) -> Option<String> {\n        let mut rendered_parts = Vec::with_capacity(items.len());\n        for item in items {\n            let single_item_file = syn::File {\n                shebang: None,\n                attrs: Vec::new(),\n                items: vec![item.clone()],\n            };\n            let rendered = unparse(&single_item_file);\n            let trimmed = trim_trailing_newlines(&rendered);\n            if !trimmed.is_empty() {\n                rendered_parts.push(trimmed.to_owned());\n            }\n        }\n        if rendered_parts.is_empty() {\n            None\n        } else {\n            Some(rendered_parts.join(separator))\n        }\n    }\n\n    let syn::File {\n        shebang,\n        attrs,\n        items,\n    } = file;\n\n    let (use_items, other_items): (Vec<Item>, Vec<Item>) =\n        items.into_iter().partition(|it| matches!(it, Item::Use(_)));\n\n    let mut out = String::new();\n\n    if let Some(s) = shebang {\n        out.push_str(s.trim_end_matches('\\n'));\n        out.push('\\n');\n    }\n\n    if !attrs.is_empty() {\n        if !out.is_empty() && !out.ends_with('\\n') {\n            out.push('\\n');\n        }\n        let attrs_file = syn::File {\n            shebang: None,\n            attrs,\n            items: vec![],\n        };\n        let rendered = unparse(&attrs_file);\n        let trimmed = trim_trailing_newlines(&rendered);\n        if !trimmed.is_empty() {\n            out.push_str(trimmed);\n            out.push('\\n');\n            out.push('\\n');\n        }\n    }\n\n    if let Some(block) = render_items_with_sep(&use_items, \"\\n\") {\n        if !out.is_empty() && !out.ends_with('\\n') {\n            out.push('\\n');\n        }\n        if !block.is_empty() {\n            out.push_str(&block);\n            out.push('\\n');\n        }\n    }\n\n    if let Some(block) = render_items_with_sep(&other_items, \"\\n\\n\") {\n        if !out.is_empty() && !out.ends_with(\"\\n\\n\") {\n            if out.ends_with('\\n') {\n                out.push('\\n');\n            } else {\n                out.push_str(\"\\n\\n\");\n            }\n        }\n        out.push_str(&block);\n        out.push('\\n');\n    }\n\n    if !out.ends_with('\\n') {\n        out.push('\\n');\n    }\n\n    out\n}\n\n#[cfg(test)]\nmod tests {\n    use indoc::indoc;\n\n    use super::*;\n\n    #[test]\n    fn merge_preserves_behavior_and_attributes() {\n        let old_file = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n            use crate::helpers::Helper;\n\n            #[derive(Clone, Debug, DeriveEntityModel, serde::Serialize)]\n            #[sea_orm(table_name = \"posts\")]\n            #[serde(rename_all = \"camelCase\")]\n            /// Old model docs\n            pub struct Model {\n                /// Old id docs\n                #[serde(rename = \"postId\")]\n                #[cfg(feature = \"serde\")]\n                pub id: i32,\n                pub title: String,\n            }\n\n            #[derive(DeriveRelation, Eq, PartialEq)]\n            #[ts(export)]\n            pub enum Relation {\n                #[sea_orm(has_one = \"super::super::MyEntity\")]\n                MyRelation,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {\n                fn custom(&self) -> Helper {\n                    Helper::default()\n                }\n            }\n            \"#\n        };\n\n        let curr = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            #[derive(Clone, Debug, DeriveEntityModel)]\n            #[sea_orm(schema_name = \"public\")]\n            pub struct Model {\n                pub id: i32,\n                pub title: String,\n            }\n\n            #[derive(DeriveRelation)]\n            pub enum Relation {\n                MyRelation,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {}\n            \"#\n        };\n\n        let merged = merge_entity_files(old_file, curr).expect(\"merge failed\");\n        let expected = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n            use crate::helpers::Helper;\n\n            #[derive(Clone, Debug, DeriveEntityModel, serde::Serialize)]\n            #[sea_orm(table_name = \"posts\", schema_name = \"public\")]\n            #[serde(rename_all = \"camelCase\")]\n            /// Old model docs\n            pub struct Model {\n                /// Old id docs\n                #[serde(rename = \"postId\")]\n                #[cfg(feature = \"serde\")]\n                pub id: i32,\n                pub title: String,\n            }\n\n            #[derive(DeriveRelation, Eq, PartialEq)]\n            #[ts(export)]\n            pub enum Relation {\n                #[sea_orm(has_one = \"super::super::MyEntity\")]\n                MyRelation,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {\n                fn custom(&self) -> Helper {\n                    Helper::default()\n                }\n            }\n            \"#\n        };\n\n        assert_eq!(merged, expected);\n    }\n\n    #[test]\n    fn merge_handles_field_changes() {\n        let old_src = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            #[derive(DeriveEntityModel)]\n            pub struct Model {\n                #[serde(default)]\n                pub id: i32,\n                #[serde(rename = \"name\")]\n                pub name: String,\n                #[serde(rename = \"foo\")]\n                pub removed: bool,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {}\n            \"#};\n\n        let new_src = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            #[derive(DeriveEntityModel)]\n            pub struct Model {\n                pub id: i32,\n                pub name: String,\n                #[serde(rename = \"bar\")]\n                pub added: String,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {}\n            \"#};\n\n        let merged = merge_entity_files(old_src, new_src).expect(\"merge should succeed\");\n\n        let expected = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            #[derive(DeriveEntityModel)]\n            pub struct Model {\n                #[serde(default)]\n                pub id: i32,\n                #[serde(rename = \"name\")]\n                pub name: String,\n                #[serde(rename = \"bar\")]\n                pub added: String,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {}\n            \"#\n        };\n\n        assert_eq!(merged, expected);\n    }\n\n    #[test]\n    fn complex_use() {\n        let old_src = indoc! {r#\"\n            use crate::{\n                B::{self, C},\n                A,\n                D as E,\n            };\n            use self::{\n                helper::Tool as ToolAlias,\n                super::shared::Common,\n            };\n\n            pub struct Placeholder;\n            \"#\n        };\n\n        let new_src = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            pub struct Placeholder;\n            \"#\n        };\n\n        let merged = merge_entity_files(old_src, new_src).expect(\"merge should succeed\");\n\n        let expected = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n            use crate::{\n                B::{self, C},\n                A, D as E,\n            };\n            use self::{helper::Tool as ToolAlias, super::shared::Common};\n\n            pub struct Placeholder;\n            \"#\n        };\n\n        assert_eq!(merged, expected);\n    }\n\n    #[test]\n    fn conv_to_comment_fallback() {\n        let old_src = indoc! {r#\"\n            this is not valid rust\n            impl ActiveModelBehavior for ActiveModel {\n                fn something(&self) {}\n            }\n            \"#\n        };\n\n        let new_src = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            #[derive(DeriveEntityModel)]\n            pub struct Model {\n                pub id: i32,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {}\n            \"#\n        };\n\n        let report = merge_entity_files(old_src, new_src).unwrap_err();\n        assert!(report.fallback_applied);\n\n        let expect = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            #[derive(DeriveEntityModel)]\n            pub struct Model {\n                pub id: i32,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {}\n\n            // --- Preserved original file content (could not be merged automatically) ---\n            /*\n            this is not valid rust\n            impl ActiveModelBehavior for ActiveModel {\n                fn something(&self) {}\n            }\n            */\n\n        \"#};\n\n        assert_eq!(report.output, expect)\n    }\n\n    #[test]\n    fn conflict_attrs_should_never_be_overwritten() {\n        let old_src = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            #[derive(DeriveEntityModel)]\n            #[serde(rename_all = \"camelCase\")]\n            pub struct Model {\n                #[serde(rename_all = \"foo\")]\n                pub id: i32,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {}\n        \"#};\n\n        let new_src = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            #[derive(DeriveEntityModel)]\n            #[serde(rename_all = \"snake_case\")]\n            pub struct Model {\n                #[serde(rename_all = \"bar\")]\n                pub id: i32,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {}\n        \"#};\n\n        let merged = merge_entity_files(old_src, new_src).expect(\"merge should succeed\");\n        let expected = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            #[derive(DeriveEntityModel)]\n            #[serde(rename_all = \"camelCase\")]\n            pub struct Model {\n                #[serde(rename_all = \"foo\")]\n                pub id: i32,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {}\n        \"#};\n\n        assert_eq!(merged, expected);\n    }\n\n    #[test]\n    fn conflict_attrs_should_be_merged() {\n        let old_src = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            #[derive(DeriveEntityModel)]\n            pub struct Model {\n                #[serde(rename = \"oldId\")]\n                pub id: i32,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {}\n        \"#};\n\n        let new_src = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            #[derive(DeriveEntityModel)]\n            pub struct Model {\n                #[serde(rename = \"newId\", default)]\n                pub id: i32,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {}\n        \"#};\n\n        let merged = merge_entity_files(old_src, new_src).expect(\"merge should succeed\");\n        let expected = indoc! {r#\"\n            use sea_orm::entity::prelude::*;\n\n            #[derive(DeriveEntityModel)]\n            pub struct Model {\n                #[serde(rename = \"oldId\", default)]\n                pub id: i32,\n            }\n\n            impl ActiveModelBehavior for ActiveModel {}\n        \"#};\n\n        assert_eq!(merged, expected);\n    }\n}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/compact/indexes.rs",
    "content": "//! An entity definition for testing table index creation.\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"indexes\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub indexes_id: i32,\n    #[sea_orm(unique)]\n    pub unique_attr: i32,\n    #[sea_orm(unique_key = \"my_unique\")]\n    pub unique_key_a: String,\n    #[sea_orm(unique_key = \"my_unique\")]\n    pub unique_key_b: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/compact/mod.rs",
    "content": "pub mod indexes;\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/dense/indexes.rs",
    "content": "//! An entity definition for testing table index creation.\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"indexes\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub indexes_id: i32,\n    #[sea_orm(unique)]\n    pub unique_attr: i32,\n    #[sea_orm(unique_key = \"my_unique\")]\n    pub unique_key_a: String,\n    #[sea_orm(unique_key = \"my_unique\")]\n    pub unique_key_b: String,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/dense/mod.rs",
    "content": "pub mod indexes;\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/duplicated_many_to_many_paths/bills.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bills\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub user_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::users::Entity\",\n        from = \"Column::UserId\",\n        to = \"super::users::Column::Id\",\n        on_update = \"NoAction\",\n        on_delete = \"NoAction\",\n    )]\n    Users,\n    #[sea_orm(has_many = \"super::users_saved_bills::Entity\")]\n    UsersSavedBills,\n    #[sea_orm(has_many = \"super::users_votes::Entity\")]\n    UsersVotes,\n}\n\nimpl Related<super::users::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Users.def()\n    }\n}\n\nimpl Related<super::users_saved_bills::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::UsersSavedBills.def()\n    }\n}\n\nimpl Related<super::users_votes::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::UsersVotes.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/duplicated_many_to_many_paths/mod.rs",
    "content": "pub mod prelude;\n\npub mod bills;\npub mod users;\npub mod users_saved_bills;\npub mod users_votes;\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/duplicated_many_to_many_paths/prelude.rs",
    "content": "pub use super::bills::Entity as Bills;\npub use super::users::Entity as Users;\npub use super::users_saved_bills::Entity as UsersSavedBills;\npub use super::users_votes::Entity as UsersVotes;\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/duplicated_many_to_many_paths/users.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"users\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\")]\n    pub email: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::bills::Entity\")]\n    Bills,\n    #[sea_orm(has_many = \"super::users_saved_bills::Entity\")]\n    UsersSavedBills,\n    #[sea_orm(has_many = \"super::users_votes::Entity\")]\n    UsersVotes,\n}\n\nimpl Related<super::bills::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bills.def()\n    }\n}\n\nimpl Related<super::users_saved_bills::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::UsersSavedBills.def()\n    }\n}\n\nimpl Related<super::users_votes::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::UsersVotes.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/duplicated_many_to_many_paths/users_saved_bills.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"users_saved_bills\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub user_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub bill_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::bills::Entity\",\n        from = \"Column::BillId\",\n        to = \"super::bills::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\",\n    )]\n    Bills,\n    #[sea_orm(\n        belongs_to = \"super::users::Entity\",\n        from = \"Column::UserId\",\n        to = \"super::users::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\",\n    )]\n    Users,\n}\n\nimpl Related<super::bills::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bills.def()\n    }\n}\n\nimpl Related<super::users::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Users.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/duplicated_many_to_many_paths/users_votes.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"users_votes\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub user_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub bill_id: i32,\n    pub vote: bool,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::bills::Entity\",\n        from = \"Column::BillId\",\n        to = \"super::bills::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\",\n    )]\n    Bills,\n    #[sea_orm(\n        belongs_to = \"super::users::Entity\",\n        from = \"Column::UserId\",\n        to = \"super::users::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\",\n    )]\n    Users,\n}\n\nimpl Related<super::bills::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bills.def()\n    }\n}\n\nimpl Related<super::users::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Users.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/many_to_many/bills.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bills\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub user_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::users::Entity\",\n        from = \"Column::UserId\",\n        to = \"super::users::Column::Id\",\n        on_update = \"NoAction\",\n        on_delete = \"NoAction\",\n    )]\n    Users,\n    #[sea_orm(has_many = \"super::users_votes::Entity\")]\n    UsersVotes,\n}\n\nimpl Related<super::users_votes::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::UsersVotes.def()\n    }\n}\n\nimpl Related<super::users::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::users_votes::Relation::Users.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::users_votes::Relation::Bills.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/many_to_many/mod.rs",
    "content": "pub mod prelude;\n\npub mod bills;\npub mod users;\npub mod users_votes;\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/many_to_many/prelude.rs",
    "content": "pub use super::bills::Entity as Bills;\npub use super::users::Entity as Users;\npub use super::users_votes::Entity as UsersVotes;\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/many_to_many/users.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"users\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\")]\n    pub email: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::bills::Entity\")]\n    Bills,\n    #[sea_orm(has_many = \"super::users_votes::Entity\")]\n    UsersVotes,\n}\n\nimpl Related<super::users_votes::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::UsersVotes.def()\n    }\n}\n\nimpl Related<super::bills::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::users_votes::Relation::Bills.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::users_votes::Relation::Users.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/many_to_many/users_votes.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"users_votes\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub user_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub bill_id: i32,\n    pub vote: bool,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::bills::Entity\",\n        from = \"Column::BillId\",\n        to = \"super::bills::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\",\n    )]\n    Bills,\n    #[sea_orm(\n        belongs_to = \"super::users::Entity\",\n        from = \"Column::UserId\",\n        to = \"super::users::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\",\n    )]\n    Users,\n}\n\nimpl Related<super::bills::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bills.def()\n    }\n}\n\nimpl Related<super::users::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Users.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/many_to_many_multiple/bills.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bills\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub user_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::users::Entity\",\n        from = \"Column::UserId\",\n        to = \"super::users::Column::Id\",\n        on_update = \"NoAction\",\n        on_delete = \"NoAction\",\n    )]\n    Users,\n}\n\nimpl Related<super::users::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Users.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/many_to_many_multiple/mod.rs",
    "content": "pub mod prelude;\n\npub mod bills;\npub mod users;\npub mod users_votes;\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/many_to_many_multiple/prelude.rs",
    "content": "pub use super::bills::Entity as Bills;\npub use super::users::Entity as Users;\npub use super::users_votes::Entity as UsersVotes;\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/many_to_many_multiple/users.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"users\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\")]\n    pub email: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::bills::Entity\")]\n    Bills,\n}\n\nimpl Related<super::bills::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bills.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/many_to_many_multiple/users_votes.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"users_votes\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub user_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub bill_id: i32,\n    pub user_idd: Option<i32> ,\n    pub bill_idd: Option<i32> ,\n    pub vote: bool,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::bills::Entity\",\n        from = \"Column::BillIdd\",\n        to = \"super::bills::Column::Id\",\n    )]\n    Bills2,\n    #[sea_orm(\n        belongs_to = \"super::bills::Entity\",\n        from = \"Column::BillId\",\n        to = \"super::bills::Column::Id\",\n    )]\n    Bills1,\n    #[sea_orm(\n        belongs_to = \"super::users::Entity\",\n        from = \"Column::UserIdd\",\n        to = \"super::users::Column::Id\",\n    )]\n    Users2,\n    #[sea_orm(\n        belongs_to = \"super::users::Entity\",\n        from = \"Column::UserId\",\n        to = \"super::users::Column::Id\",\n    )]\n    Users1,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/mod.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod compact;\npub mod dense;\npub mod duplicated_many_to_many_paths;\npub mod many_to_many;\npub mod many_to_many_multiple;\npub mod self_referencing;\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/self_referencing/bills.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bills\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub self_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"Entity\",\n        from = \"Column::SelfId\",\n        to = \"Column::Id\",\n    )]\n    SelfRef,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/self_referencing/mod.rs",
    "content": "pub mod prelude;\n\npub mod bills;\npub mod users;\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/self_referencing/prelude.rs",
    "content": "pub use super::bills::Entity as Bills;\npub use super::users::Entity as Users;\n"
  },
  {
    "path": "sea-orm-codegen/src/tests_cfg/self_referencing/users.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"users\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub self_id: Option<i32> ,\n    pub self_idd: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"Entity\",\n        from = \"Column::SelfId\",\n        to = \"Column::Id\",\n    )]\n    SelfRef2,\n    #[sea_orm(\n        belongs_to = \"Entity\",\n        from = \"Column::SelfIdd\",\n        to = \"Column::Id\",\n    )]\n    SelfRef1,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/src/util.rs",
    "content": "pub(crate) fn escape_rust_keyword<T>(string: T) -> String\nwhere\n    T: ToString,\n{\n    let string = string.to_string();\n    if RUST_KEYWORDS.iter().any(|s| s.eq(&string)) {\n        format!(\"r#{string}\")\n    } else if RUST_SPECIAL_KEYWORDS.iter().any(|s| s.eq(&string)) {\n        format!(\"{string}_\")\n    } else {\n        string\n    }\n}\n\npub(crate) const RUST_KEYWORDS: [&str; 49] = [\n    \"as\", \"async\", \"await\", \"break\", \"const\", \"continue\", \"dyn\", \"else\", \"enum\", \"extern\", \"false\",\n    \"fn\", \"for\", \"if\", \"impl\", \"in\", \"let\", \"loop\", \"match\", \"mod\", \"move\", \"mut\", \"pub\", \"ref\",\n    \"return\", \"static\", \"struct\", \"super\", \"trait\", \"true\", \"type\", \"union\", \"unsafe\", \"use\",\n    \"where\", \"while\", \"abstract\", \"become\", \"box\", \"do\", \"final\", \"macro\", \"override\", \"priv\",\n    \"try\", \"typeof\", \"unsized\", \"virtual\", \"yield\",\n];\n\npub(crate) const RUST_SPECIAL_KEYWORDS: [&str; 3] = [\"crate\", \"Self\", \"self\"];\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/cake.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/cake_filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"_cake_filling_\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub filling_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\",\n    )]\n    Cake,\n    #[sea_orm(\n        belongs_to = \"super::filling::Entity\",\n        from = \"Column::FillingId\",\n        to = \"super::filling::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\",\n    )]\n    Filling,\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Filling.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/cake_filling_price.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake_filling_price\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub filling_id: i32,\n    pub price: Decimal,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake_filling::Entity\",\n        from = \"(Column::CakeId, Column::FillingId)\",\n        to = \"(super::cake_filling::Column::CakeId, super::cake_filling::Column::FillingId)\",\n    )]\n    CakeFilling,\n}\n\nimpl Related<super::cake_filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::CakeFilling.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}"
  },
  {
    "path": "sea-orm-codegen/tests/compact/cake_with_double.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake_with_double\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n    #[sea_orm(column_type = \"Double\", nullable)]\n    pub price: Option<f64> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::CakeWithDouble.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/cake_with_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake_with_float\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n    #[sea_orm(column_type = \"Float\", nullable)]\n    pub price: Option<f32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::CakeWithFloat.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/child.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"child\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub parent_id1: i32,\n    pub parent_id2: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::parent::Entity\",\n        from = \"(Column::ParentId1, Column::ParentId2)\",\n        to = \"(super::parent::Column::Id1, super::parent::Column::Id2)\",\n    )]\n    Parent,\n}\n\nimpl Related<super::parent::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Parent.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/collection.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"collection\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub integers: Vec<i32> ,\n    pub integers_opt: Option<Vec<i32> > ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/collection_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"collection_float\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub floats: Vec<f32> ,\n    pub doubles: Vec<f64> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"filling\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Cake.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Filling.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/fruit.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"fruit\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub cake_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n    )]\n    Cake,\n    #[sea_orm(has_many = \"super::vendor::Entity\")]\n    Vendor,\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl Related<super::vendor::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Vendor.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/mod.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub mod prelude;\n\npub mod cake;\npub mod cake_filling;\npub mod filling;\npub mod fruit;\npub mod vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/parent.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"parent\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id1: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id2: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::child::Entity\")]\n    Child,\n}\n\nimpl Related<super::child::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Child.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/prelude.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub use super::cake::Entity as Cake;\npub use super::cake_filling::Entity as CakeFilling;\npub use super::filling::Entity as Filling;\npub use super::fruit::Entity as Fruit;\npub use super::vendor::Entity as Vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/rust_keyword.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"rust_keyword\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub testing: i8,\n    pub rust: u8,\n    pub keywords: i16,\n    pub r#type: u16,\n    pub r#typeof: i32,\n    pub crate_: u32,\n    pub self_: i64,\n    pub self_id1: u64,\n    pub self_id2: i32,\n    pub fruit_id1: i32,\n    pub fruit_id2: i32,\n    pub cake_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"Entity\",\n        from = \"Column::SelfId1\",\n        to = \"Column::Id\",\n    )]\n    SelfRef1,\n    #[sea_orm(\n        belongs_to = \"Entity\",\n        from = \"Column::SelfId2\",\n        to = \"Column::Id\",\n    )]\n    SelfRef2,\n    #[sea_orm(\n        belongs_to = \"super::fruit::Entity\",\n        from = \"Column::FruitId1\",\n        to = \"super::fruit::Column::Id\",\n    )]\n    Fruit1,\n    #[sea_orm(\n        belongs_to = \"super::fruit::Entity\",\n        from = \"Column::FruitId2\",\n        to = \"super::fruit::Column::Id\",\n    )]\n    Fruit2,\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n    )]\n    Cake,\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact/vendor.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"vendor\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_name = \"_name_\")]\n    pub name: String,\n    #[sea_orm(column_name = \"fruitId\")]\n    pub fruit_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::fruit::Entity\",\n        from = \"Column::FruitId\",\n        to = \"super::fruit::Column::Id\",\n    )]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_attributes/cake_multiple.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\n#[serde(rename_all = \"camelCase\")]\n#[ts(export)]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_attributes/cake_none.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_attributes/cake_one.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\n#[serde(rename_all = \"camelCase\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_derives/cake_multiple.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, ts_rs::TS, utoipa::ToSchema)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_derives/cake_none.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_derives/cake_one.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, ts_rs::TS)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/cake.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/cake_filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"_cake_filling_\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub filling_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\",\n    )]\n    Cake,\n    #[sea_orm(\n        belongs_to = \"super::filling::Entity\",\n        from = \"Column::FillingId\",\n        to = \"super::filling::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\",\n    )]\n    Filling,\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Filling.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/cake_filling_price.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"cake_filling_price\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub filling_id: i32,\n    pub price: Decimal,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake_filling::Entity\",\n        from = \"(Column::CakeId, Column::FillingId)\",\n        to = \"(super::cake_filling::Column::CakeId, super::cake_filling::Column::FillingId)\",\n    )]\n    CakeFilling,\n}\n\nimpl Related<super::cake_filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::CakeFilling.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/cake_with_double.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"cake_with_double\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n    #[sea_orm(column_type = \"Double\", nullable)]\n    pub price: Option<f64> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::CakeWithDouble.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/cake_with_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"cake_with_float\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n    #[sea_orm(column_type = \"Float\", nullable)]\n    pub price: Option<f32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::CakeWithFloat.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/child.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"child\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub parent_id1: i32,\n    pub parent_id2: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::parent::Entity\",\n        from = \"(Column::ParentId1, Column::ParentId2)\",\n        to = \"(super::parent::Column::Id1, super::parent::Column::Id2)\",\n    )]\n    Parent,\n}\n\nimpl Related<super::parent::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Parent.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/collection.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"collection\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub integers: Vec<i32> ,\n    pub integers_opt: Option<Vec<i32> > ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/collection_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"collection_float\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub floats: Vec<f32> ,\n    pub doubles: Vec<f64> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"filling\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Cake.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Filling.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/fruit.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"fruit\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub cake_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n    )]\n    Cake,\n    #[sea_orm(has_many = \"super::vendor::Entity\")]\n    Vendor,\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl Related<super::vendor::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Vendor.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/mod.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub mod prelude;\n\npub mod cake;\npub mod cake_filling;\npub mod filling;\npub mod fruit;\npub mod vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/parent.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"parent\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id1: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id2: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::child::Entity\")]\n    Child,\n}\n\nimpl Related<super::child::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Child.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/prelude.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub use super::cake::Entity as Cake;\npub use super::cake_filling::Entity as CakeFilling;\npub use super::filling::Entity as Filling;\npub use super::fruit::Entity as Fruit;\npub use super::vendor::Entity as Vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/rust_keyword.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"rust_keyword\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub testing: i8,\n    pub rust: u8,\n    pub keywords: i16,\n    pub r#type: u16,\n    pub r#typeof: i32,\n    pub crate_: u32,\n    pub self_: i64,\n    pub self_id1: u64,\n    pub self_id2: i32,\n    pub fruit_id1: i32,\n    pub fruit_id2: i32,\n    pub cake_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"Entity\",\n        from = \"Column::SelfId1\",\n        to = \"Column::Id\",\n    )]\n    SelfRef1,\n    #[sea_orm(\n        belongs_to = \"Entity\",\n        from = \"Column::SelfId2\",\n        to = \"Column::Id\",\n    )]\n    SelfRef2,\n    #[sea_orm(\n        belongs_to = \"super::fruit::Entity\",\n        from = \"Column::FruitId1\",\n        to = \"super::fruit::Column::Id\",\n    )]\n    Fruit1,\n    #[sea_orm(\n        belongs_to = \"super::fruit::Entity\",\n        from = \"Column::FruitId2\",\n        to = \"super::fruit::Column::Id\",\n    )]\n    Fruit2,\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n    )]\n    Cake,\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_schema_name/vendor.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"schema_name\", table_name = \"vendor\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_name = \"_name_\")]\n    pub name: String,\n    #[sea_orm(column_name = \"fruitId\")]\n    pub fruit_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::fruit::Entity\",\n        from = \"Column::FruitId\",\n        to = \"super::fruit::Column::Id\",\n    )]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_serde/cake_both.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_serde/cake_deserialize.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\nuse serde::Deserialize;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Deserialize)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_serde/cake_none.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_serde/cake_serialize.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\nuse serde::Serialize;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/compact_with_serde/cake_serialize_with_hidden_column.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\nuse serde::Serialize;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_name = \"_name\", column_type = \"Text\", nullable)]\n    #[serde(skip)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/cake.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n    #[sea_orm(has_many)]\n    pub fruits: HasMany<super::fruit::Entity> ,\n    #[sea_orm(has_many, via = \"cake_filling\")]\n    pub fillings: HasMany<super::filling::Entity> ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/cake_filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"_cake_filling_\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub filling_id: i32,\n    #[sea_orm(belongs_to, from = \"cake_id\", to = \"id\", on_update = \"Cascade\", on_delete = \"Cascade\")]\n    pub cake: HasOne<super::cake::Entity> ,\n    #[sea_orm(belongs_to, from = \"filling_id\", to = \"id\", on_update = \"Cascade\", on_delete = \"Cascade\")]\n    pub filling: HasOne<super::filling::Entity> ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/cake_filling_price.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake_filling_price\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub filling_id: i32,\n    pub price: Decimal,\n    #[sea_orm(\n        belongs_to,\n        from = \"(cake_id, filling_id)\",\n        to = \"(cake_id, filling_id)\"\n    )]\n    pub cake_filling: HasOne<super::cake_filling::Entity> ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}"
  },
  {
    "path": "sea-orm-codegen/tests/dense/cake_with_double.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake_with_double\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n    #[sea_orm(column_type = \"Double\", nullable)]\n    pub price: Option<f64> ,\n    #[sea_orm(has_many)]\n    pub fruits: HasMany<super::fruit::Entity> ,\n    #[sea_orm(has_many, via = \"cake_filling\")]\n    pub fillings: HasMany<super::filling::Entity> ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/cake_with_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake_with_float\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n    #[sea_orm(column_type = \"Float\", nullable)]\n    pub price: Option<f32> ,\n    #[sea_orm(has_many)]\n    pub fruits: HasMany<super::fruit::Entity> ,\n    #[sea_orm(has_many, via = \"cake_filling\")]\n    pub fillings: HasMany<super::filling::Entity> ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/child.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"child\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub parent_id1: i32,\n    pub parent_id2: i32,\n    #[sea_orm(belongs_to, from = \"(parent_id1, parent_id2)\", to = \"(id1, id2)\")]\n    pub parent: HasOne<super::parent::Entity> ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/collection.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"collection\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub integers: Vec<i32> ,\n    pub integers_opt: Option<Vec<i32> > ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/collection_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"collection_float\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub floats: Vec<f32> ,\n    pub doubles: Vec<f64> ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"filling\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(has_many, via = \"cake_filling\")]\n    pub cakes: HasMany<super::cake::Entity> ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/fruit.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"fruit\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub cake_id: Option<i32> ,\n    #[sea_orm(belongs_to, from = \"cake_id\", to = \"id\")]\n    pub cake: HasOne<super::cake::Entity> ,\n    #[sea_orm(has_many)]\n    pub vendors: HasMany<super::vendor::Entity> ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/mod.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub mod prelude;\n\npub mod cake;\npub mod cake_filling;\npub mod filling;\npub mod fruit;\npub mod vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/parent.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"parent\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id1: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id2: i32,\n    #[sea_orm(has_many)]\n    pub children: HasMany<super::child::Entity> ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/prelude.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub use super::cake::Entity as Cake;\npub use super::cake_filling::Entity as CakeFilling;\npub use super::filling::Entity as Filling;\npub use super::fruit::Entity as Fruit;\npub use super::vendor::Entity as Vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/rust_keyword.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"rust_keyword\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub testing: i8,\n    pub rust: u8,\n    pub keywords: i16,\n    pub r#type: u16,\n    pub r#typeof: i32,\n    pub crate_: u32,\n    pub self_: i64,\n    pub self_id1: u64,\n    pub self_id2: i32,\n    pub fruit_id1: i32,\n    pub fruit_id2: i32,\n    pub cake_id: i32,\n    #[sea_orm(self_ref, relation_enum = \"SelfRef1\", from = \"self_id1\", to = \"id\")]\n    pub rust_keyword_1: HasOne<Entity> ,\n    #[sea_orm(self_ref, relation_enum = \"SelfRef2\", from = \"self_id2\", to = \"id\")]\n    pub rust_keyword_2: HasOne<Entity> ,\n    #[sea_orm(belongs_to, relation_enum = \"Fruit1\", from = \"fruit_id1\", to = \"id\")]\n    pub fruit_1: HasOne<super::fruit::Entity> ,\n    #[sea_orm(belongs_to, relation_enum = \"Fruit2\", from = \"fruit_id2\", to = \"id\")]\n    pub fruit_2: HasOne<super::fruit::Entity> ,\n    #[sea_orm(belongs_to, from = \"cake_id\", to = \"id\")]\n    pub cake: HasOne<super::cake::Entity> ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/dense/vendor.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"vendor\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_name = \"_name_\")]\n    pub name: String,\n    #[sea_orm(column_name = \"fruitId\")]\n    pub fruit_id: Option<i32> ,\n    #[sea_orm(belongs_to, from = \"fruit_id\", to = \"id\")]\n    pub fruit: HasOne<super::fruit::Entity> ,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/cake.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/cake_filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"_cake_filling_\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub cake_id: i32,\n    pub filling_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    CakeId,\n    FillingId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    CakeId,\n    FillingId,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = (i32, i32);\n\n    fn auto_increment() -> bool {\n        false\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Cake,\n    Filling,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::CakeId => ColumnType::Integer.def(),\n            Self::FillingId => ColumnType::Integer.def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Cake => Entity::belongs_to(super::cake::Entity)\n                .from(Column::CakeId)\n                .to(super::cake::Column::Id)\n                .into(),\n            Self::Filling => Entity::belongs_to(super::filling::Entity)\n                .from(Column::FillingId)\n                .to(super::filling::Column::Id)\n                .into(),\n        }\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Filling.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/cake_filling_price.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake_filling_price\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub cake_id: i32,\n    pub filling_id: i32,\n    pub price: Decimal,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    CakeId,\n    FillingId,\n    Price,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    CakeId,\n    FillingId,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = (i32, i32);\n\n    fn auto_increment() -> bool {\n        false\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    CakeFilling,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::CakeId => ColumnType::Integer.def(),\n            Self::FillingId => ColumnType::Integer.def(),\n            Self::Price => ColumnType::Decimal(None).def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::CakeFilling => Entity::belongs_to(super::cake_filling::Entity)\n                .from((Column::CakeId, Column::FillingId))\n                .to((\n                    super::cake_filling::Column::CakeId,\n                    super::cake_filling::Column::FillingId\n                ))\n                .into(),\n        }\n    }\n}\n\nimpl Related<super::cake_filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::CakeFilling.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/cake_with_double.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake_with_double\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n    pub price: Option<f64> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n    Price,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n            Self::Price => ColumnType::Double.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::CakeWithDouble.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/cake_with_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake_with_float\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n    pub price: Option<f32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n    Price,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n            Self::Price => ColumnType::Float.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::CakeWithFloat.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/child.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"child\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub parent_id1: i32,\n    pub parent_id2: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    ParentId1,\n    ParentId2,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Parent,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::ParentId1 => ColumnType::Integer.def(),\n            Self::ParentId2 => ColumnType::Integer.def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Parent => Entity::belongs_to(super::parent::Entity)\n                .from((Column::ParentId1, Column::ParentId2))\n                .to((super::parent::Column::Id1, super::parent::Column::Id2))\n                .into(),\n        }\n    }\n}\n\nimpl Related<super::parent::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Parent.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/collection.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"collection\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub integers: Vec<i32> ,\n    pub integers_opt: Option<Vec<i32> > ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Integers,\n    IntegersOpt,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Integers => ColumnType::Array(RcOrArc::new(ColumnType::Integer)).def(),\n            Self::IntegersOpt => ColumnType::Array(RcOrArc::new(ColumnType::Integer)).def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        panic!(\"No RelationDef\")\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/collection_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"collection_float\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\npub struct Model {\n    pub id: i32,\n    pub floats: Vec<f32> ,\n    pub doubles: Vec<f64> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Floats,\n    Doubles,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Floats => ColumnType::Array(RcOrArc::new(ColumnType::Float)).def(),\n            Self::Doubles => ColumnType::Array(RcOrArc::new(ColumnType::Double)).def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        panic!(\"No RelationDef\")\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"filling\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::N(255u32)).def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        panic!(\"No RelationDef\")\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Cake.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Filling.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/fruit.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"fruit\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n    pub cake_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n    CakeId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Cake,\n    Vendor,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::N(255u32)).def(),\n            Self::CakeId => ColumnType::Integer.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Cake => Entity::belongs_to(super::cake::Entity)\n                .from(Column::CakeId)\n                .to(super::cake::Column::Id)\n                .into(),\n            Self::Vendor => Entity::has_many(super::vendor::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl Related<super::vendor::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Vendor.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/mod.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub mod prelude;\n\npub mod cake;\npub mod cake_filling;\npub mod filling;\npub mod fruit;\npub mod vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/parent.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"parent\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id1: i32,\n    pub id2: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id1,\n    Id2,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id1,\n    Id2,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = (i32, i32);\n    fn auto_increment() -> bool {\n        false\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Child,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id1 => ColumnType::Integer.def(),\n            Self::Id2 => ColumnType::Integer.def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Child => Entity::has_many(super::child::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::child::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Child.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/prelude.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub use super::cake::Entity as Cake;\npub use super::cake_filling::Entity as CakeFilling;\npub use super::filling::Entity as Filling;\npub use super::fruit::Entity as Fruit;\npub use super::vendor::Entity as Vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/rust_keyword.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"rust_keyword\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub testing: i8,\n    pub rust: u8,\n    pub keywords: i16,\n    pub r#type: u16,\n    pub r#typeof: i32,\n    pub crate_: u32,\n    pub self_: i64,\n    pub self_id1: u64,\n    pub self_id2: i32,\n    pub fruit_id1: i32,\n    pub fruit_id2: i32,\n    pub cake_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Testing,\n    Rust,\n    Keywords,\n    Type,\n    Typeof,\n    Crate,\n    Self_,\n    SelfId1,\n    SelfId2,\n    FruitId1,\n    FruitId2,\n    CakeId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    SelfRef1,\n    SelfRef2,\n    Fruit1,\n    Fruit2,\n    Cake,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Testing => ColumnType::TinyInteger.def(),\n            Self::Rust => ColumnType::TinyUnsigned.def(),\n            Self::Keywords => ColumnType::SmallInteger.def(),\n            Self::Type => ColumnType::SmallUnsigned.def(),\n            Self::Typeof => ColumnType::Integer.def(),\n            Self::Crate => ColumnType::Unsigned.def(),\n            Self::Self_ => ColumnType::BigInteger.def(),\n            Self::SelfId1 => ColumnType::BigUnsigned.def(),\n            Self::SelfId2 => ColumnType::Integer.def(),\n            Self::FruitId1 => ColumnType::Integer.def(),\n            Self::FruitId2 => ColumnType::Integer.def(),\n            Self::CakeId => ColumnType::Integer.def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::SelfRef1 => Entity::belongs_to(Entity)\n                .from(Column::SelfId1)\n                .to(Column::Id)\n                .into(),\n            Self::SelfRef2 => Entity::belongs_to(Entity)\n                .from(Column::SelfId2)\n                .to(Column::Id)\n                .into(),\n            Self::Fruit1 => Entity::belongs_to(super::fruit::Entity)\n                .from(Column::FruitId1)\n                .to(super::fruit::Column::Id)\n                .into(),\n            Self::Fruit2 => Entity::belongs_to(super::fruit::Entity)\n                .from(Column::FruitId2)\n                .to(super::fruit::Column::Id)\n                .into(),\n            Self::Cake => Entity::belongs_to(super::cake::Entity)\n                .from(Column::CakeId)\n                .to(super::cake::Column::Id)\n                .into(),\n        }\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded/vendor.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"vendor\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n    pub fruit_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    #[sea_orm(column_name = \"_name_\")]\n    Name,\n    #[sea_orm(column_name = \"fruitId\")]\n    FruitId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::N(255u32)).def(),\n            Self::FruitId => ColumnType::Integer.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::belongs_to(super::fruit::Entity)\n                .from(Column::FruitId)\n                .to(super::fruit::Column::Id)\n                .into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_attributes/cake_multiple.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\n#[serde(rename_all = \"camelCase\")]\n#[ts(export)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_attributes/cake_none.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_attributes/cake_one.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\n#[serde(rename_all = \"camelCase\")]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_column_derives/cake_multiple.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn, async_graphql::Enum, Eq, PartialEq)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_column_derives/cake_none.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_column_derives/cake_one.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn, async_graphql::Enum)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_derives/cake_multiple.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, ts_rs::TS, utoipa::ToSchema)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_derives/cake_none.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_derives/cake_one.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, ts_rs::TS)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/cake.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/cake_filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"_cake_filling_\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub cake_id: i32,\n    pub filling_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    CakeId,\n    FillingId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    CakeId,\n    FillingId,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = (i32, i32);\n\n    fn auto_increment() -> bool {\n        false\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Cake,\n    Filling,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::CakeId => ColumnType::Integer.def(),\n            Self::FillingId => ColumnType::Integer.def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Cake => Entity::belongs_to(super::cake::Entity)\n                .from(Column::CakeId)\n                .to(super::cake::Column::Id)\n                .into(),\n            Self::Filling => Entity::belongs_to(super::filling::Entity)\n                .from(Column::FillingId)\n                .to(super::filling::Column::Id)\n                .into(),\n        }\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Filling.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/cake_filling_price.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"cake_filling_price\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub cake_id: i32,\n    pub filling_id: i32,\n    pub price: Decimal,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    CakeId,\n    FillingId,\n    Price,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    CakeId,\n    FillingId,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = (i32, i32);\n\n    fn auto_increment() -> bool {\n        false\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    CakeFilling,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::CakeId => ColumnType::Integer.def(),\n            Self::FillingId => ColumnType::Integer.def(),\n            Self::Price => ColumnType::Decimal(None).def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::CakeFilling => Entity::belongs_to(super::cake_filling::Entity)\n                .from((Column::CakeId, Column::FillingId))\n                .to((\n                    super::cake_filling::Column::CakeId,\n                    super::cake_filling::Column::FillingId\n                ))\n                .into(),\n        }\n    }\n}\n\nimpl Related<super::cake_filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::CakeFilling.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/cake_with_double.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"cake_with_double\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n    pub price: Option<f64> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n    Price,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n            Self::Price => ColumnType::Double.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::CakeWithDouble.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/cake_with_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"cake_with_float\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n    pub price: Option<f32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n    Price,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n            Self::Price => ColumnType::Float.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::CakeWithFloat.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/child.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"child\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub parent_id1: i32,\n    pub parent_id2: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    ParentId1,\n    ParentId2,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Parent,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::ParentId1 => ColumnType::Integer.def(),\n            Self::ParentId2 => ColumnType::Integer.def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Parent => Entity::belongs_to(super::parent::Entity)\n                .from((Column::ParentId1, Column::ParentId2))\n                .to((super::parent::Column::Id1, super::parent::Column::Id2))\n                .into(),\n        }\n    }\n}\n\nimpl Related<super::parent::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Parent.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/collection.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"collection\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub integers: Vec<i32> ,\n    pub integers_opt: Option<Vec<i32> > ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Integers,\n    IntegersOpt,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Integers => ColumnType::Array(RcOrArc::new(ColumnType::Integer)).def(),\n            Self::IntegersOpt => ColumnType::Array(RcOrArc::new(ColumnType::Integer)).def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        panic!(\"No RelationDef\")\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/collection_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"collection_float\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\npub struct Model {\n    pub id: i32,\n    pub floats: Vec<f32> ,\n    pub doubles: Vec<f64> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Floats,\n    Doubles,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Floats => ColumnType::Array(RcOrArc::new(ColumnType::Float)).def(),\n            Self::Doubles => ColumnType::Array(RcOrArc::new(ColumnType::Double)).def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        panic!(\"No RelationDef\")\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"filling\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::N(255u32)).def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        panic!(\"No RelationDef\")\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Cake.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Filling.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/fruit.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"fruit\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n    pub cake_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n    CakeId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Cake,\n    Vendor,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::N(255u32)).def(),\n            Self::CakeId => ColumnType::Integer.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Cake => Entity::belongs_to(super::cake::Entity)\n                .from(Column::CakeId)\n                .to(super::cake::Column::Id)\n                .into(),\n            Self::Vendor => Entity::has_many(super::vendor::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl Related<super::vendor::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Vendor.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/mod.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub mod prelude;\n\npub mod cake;\npub mod cake_filling;\npub mod filling;\npub mod fruit;\npub mod vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/parent.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"parent\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id1: i32,\n    pub id2: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id1,\n    Id2,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id1,\n    Id2,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = (i32, i32);\n    fn auto_increment() -> bool {\n        false\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Child,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id1 => ColumnType::Integer.def(),\n            Self::Id2 => ColumnType::Integer.def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Child => Entity::has_many(super::child::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::child::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Child.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/prelude.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub use super::cake::Entity as Cake;\npub use super::cake_filling::Entity as CakeFilling;\npub use super::filling::Entity as Filling;\npub use super::fruit::Entity as Fruit;\npub use super::vendor::Entity as Vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/rust_keyword.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"rust_keyword\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub testing: i8,\n    pub rust: u8,\n    pub keywords: i16,\n    pub r#type: u16,\n    pub r#typeof: i32,\n    pub crate_: u32,\n    pub self_: i64,\n    pub self_id1: u64,\n    pub self_id2: i32,\n    pub fruit_id1: i32,\n    pub fruit_id2: i32,\n    pub cake_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Testing,\n    Rust,\n    Keywords,\n    Type,\n    Typeof,\n    Crate,\n    Self_,\n    SelfId1,\n    SelfId2,\n    FruitId1,\n    FruitId2,\n    CakeId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    SelfRef1,\n    SelfRef2,\n    Fruit1,\n    Fruit2,\n    Cake,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Testing => ColumnType::TinyInteger.def(),\n            Self::Rust => ColumnType::TinyUnsigned.def(),\n            Self::Keywords => ColumnType::SmallInteger.def(),\n            Self::Type => ColumnType::SmallUnsigned.def(),\n            Self::Typeof => ColumnType::Integer.def(),\n            Self::Crate => ColumnType::Unsigned.def(),\n            Self::Self_ => ColumnType::BigInteger.def(),\n            Self::SelfId1 => ColumnType::BigUnsigned.def(),\n            Self::SelfId2 => ColumnType::Integer.def(),\n            Self::FruitId1 => ColumnType::Integer.def(),\n            Self::FruitId2 => ColumnType::Integer.def(),\n            Self::CakeId => ColumnType::Integer.def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::SelfRef1 => Entity::belongs_to(Entity)\n                .from(Column::SelfId1)\n                .to(Column::Id)\n                .into(),\n            Self::SelfRef2 => Entity::belongs_to(Entity)\n                .from(Column::SelfId2)\n                .to(Column::Id)\n                .into(),\n            Self::Fruit1 => Entity::belongs_to(super::fruit::Entity)\n                .from(Column::FruitId1)\n                .to(super::fruit::Column::Id)\n                .into(),\n            Self::Fruit2 => Entity::belongs_to(super::fruit::Entity)\n                .from(Column::FruitId2)\n                .to(super::fruit::Column::Id)\n                .into(),\n            Self::Cake => Entity::belongs_to(super::cake::Entity)\n                .from(Column::CakeId)\n                .to(super::cake::Column::Id)\n                .into(),\n        }\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_schema_name/vendor.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> & 'static str {\n        \"vendor\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n    pub fruit_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    #[sea_orm(column_name = \"_name_\")]\n    Name,\n    #[sea_orm(column_name = \"fruitId\")]\n    FruitId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::N(255u32)).def(),\n            Self::FruitId => ColumnType::Integer.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::belongs_to(super::fruit::Entity)\n                .from(Column::FruitId)\n                .to(super::fruit::Column::Id)\n                .into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_serde/cake_both.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\nuse serde::{Deserialize,Serialize};\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, Serialize, Deserialize)]\npub struct Model {\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_serde/cake_deserialize.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\nuse serde::Deserialize;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, Deserialize)]\npub struct Model {\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_serde/cake_none.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_serde/cake_serialize.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\nuse serde::Serialize;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, Serialize)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/expanded_with_serde/cake_serialize_with_hidden_column.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\nuse serde::Serialize;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq, Serialize)]\npub struct Model {\n    pub id: i32,\n    #[serde(skip)]\n    pub name: Option<String> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    #[sea_orm(column_name = \"_name\")]\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/cake.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/cake_filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub cake_id: i32,\n    pub filling_id: i32,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/cake_filling_price.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub cake_id: i32,\n    pub filling_id: i32,\n    pub price: Decimal,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/cake_with_double.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n    pub price: Option<f64> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/cake_with_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n    pub price: Option<f32> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/child.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub parent_id1: i32,\n    pub parent_id2: i32,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/collection.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub integers: Vec<i32> ,\n    pub integers_opt: Option<Vec<i32> > ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/collection_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\n#[derive(Clone, Debug, PartialEq)]\npub struct Model {\n    pub id: i32,\n    pub floats: Vec<f32> ,\n    pub doubles: Vec<f64> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/fruit.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n    pub cake_id: Option<i32> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/mod.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub mod prelude;\n\npub mod cake;\npub mod cake_filling;\npub mod filling;\npub mod fruit;\npub mod vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/parent.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id1: i32,\n    pub id2: i32,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/prelude.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub use super::cake::Model as Cake;\npub use super::cake_filling::Model as CakeFilling;\npub use super::filling::Model as Filling;\npub use super::fruit::Model as Fruit;\npub use super::vendor::Model as Vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/rust_keyword.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub testing: i8,\n    pub rust: u8,\n    pub keywords: i16,\n    pub r#type: u16,\n    pub r#typeof: i32,\n    pub crate_: u32,\n    pub self_: i64,\n    pub self_id1: u64,\n    pub self_id2: i32,\n    pub fruit_id1: i32,\n    pub fruit_id2: i32,\n    pub cake_id: i32,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend/vendor.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n    pub fruit_id: Option<i32> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_attributes/cake_multiple.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\n#[serde(rename_all = \"camelCase\")]\n#[ts(export)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_attributes/cake_none.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_attributes/cake_one.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\n#[serde(rename_all = \"camelCase\")]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_derives/cake_multiple.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq, ts_rs::TS, utoipa::ToSchema)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_derives/cake_none.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_derives/cake_one.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq, ts_rs::TS)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/cake.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/cake_filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub cake_id: i32,\n    pub filling_id: i32,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/cake_filling_price.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub cake_id: i32,\n    pub filling_id: i32,\n    pub price: Decimal,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/cake_with_double.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n    pub price: Option<f64> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/cake_with_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n    pub price: Option<f32> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/child.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub parent_id1: i32,\n    pub parent_id2: i32,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/collection.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub integers: Vec<i32> ,\n    pub integers_opt: Option<Vec<i32> > ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/collection_float.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.10.0\n\n#[derive(Clone, Debug, PartialEq)]\npub struct Model {\n    pub id: i32,\n    pub floats: Vec<f32> ,\n    pub doubles: Vec<f64> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/filling.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/fruit.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n    pub cake_id: Option<i32> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/mod.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub mod prelude;\n\npub mod cake;\npub mod cake_filling;\npub mod filling;\npub mod fruit;\npub mod vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/parent.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id1: i32,\n    pub id2: i32,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/prelude.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\npub use super::cake::Model as Cake;\npub use super::cake_filling::Model as CakeFilling;\npub use super::filling::Model as Filling;\npub use super::fruit::Model as Fruit;\npub use super::vendor::Model as Vendor;\n"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/rust_keyword.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub testing: i8,\n    pub rust: u8,\n    pub keywords: i16,\n    pub r#type: u16,\n    pub r#typeof: i32,\n    pub crate_: u32,\n    pub self_: i64,\n    pub self_id1: u64,\n    pub self_id2: i32,\n    pub fruit_id1: i32,\n    pub fruit_id2: i32,\n    pub cake_id: i32,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_schema_name/vendor.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n    pub fruit_id: Option<i32> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_serde/cake_both.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]\npub struct Model {\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_serde/cake_deserialize.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse serde::Deserialize;\n\n#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]\npub struct Model {\n    #[serde(skip_deserializing)]\n    pub id: i32,\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_serde/cake_none.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_serde/cake_serialize.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse serde::Serialize;\n\n#[derive(Clone, Debug, PartialEq, Eq, Serialize)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/frontend_with_serde/cake_serialize_with_hidden_column.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse serde::Serialize;\n\n#[derive(Clone, Debug, PartialEq, Eq, Serialize)]\npub struct Model {\n    pub id: i32,\n    #[serde(skip)]\n    pub name: Option<String> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/postgres/binary_json.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n//! \n//! This file tests that the JsonBinary column type is annotated correctly is\n//! compact entity form. More information can be found in this issue:\n//! \n//! https://github.com/SeaQL/sea-orm/issues/1344\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"task\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub payload: Json,\n    #[sea_orm(column_type = \"JsonBinary\")]\n    pub payload_binary: Json,\n}\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/postgres/binary_json_expanded.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n//!\n//! This file tests that the JsonBinary column type is annotated correctly is\n//! expanded entity form. More information can be found in this issue:\n//!\n//! https://github.com/SeaQL/sea-orm/issues/1344\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option< &str > {\n        Some(\"schema_name\")\n    }\n    fn table_name(&self) -> & 'static str {\n        \"task\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub payload: Json,\n    pub payload_binary: Json,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Payload,\n    PayloadBinary,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {}\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            // This is the part that is being tested.\n            Self::Payload => ColumnType::Json.def(),\n            Self::PayloadBinary => ColumnType::JsonBinary.def(),\n        }\n    }\n}\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        panic!(\"No RelationDef\")\n    }\n}\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-codegen/tests/with_seaography/cake.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub name: Option<String> ,\n    pub base_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n    #[sea_orm(has_one = \"Entity\")]\n    SelfRef ,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]\npub enum RelatedEntity {\n    #[sea_orm(entity = \"super::fruit::Entity\")]\n    Fruit,\n    #[sea_orm(entity = \"Entity\", def = \"Relation::SelfRef.def()\")]\n    SelfRef,\n    #[sea_orm(entity = \"Entity\", def = \"Relation::SelfRef.def().rev()\")]\n    SelfRefReverse,\n    #[sea_orm(entity = \"super::filling::Entity\")]\n    Filling\n}\n"
  },
  {
    "path": "sea-orm-codegen/tests/with_seaography/cake_expanded.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nuse sea_orm::entity::prelude:: * ;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> & 'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n    pub base_id: Option<i32> ,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n    BaseId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n    SelfRef ,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::Text.def().null(),\n            Self::BaseId => ColumnType::Integer.def().null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n            Self::SelfRef => Entity::has_one(Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]\npub enum RelatedEntity {\n    #[sea_orm(entity = \"super::fruit::Entity\")]\n    Fruit,\n    #[sea_orm(entity = \"Entity\", def = \"Relation::SelfRef.def()\")]\n    SelfRef,\n    #[sea_orm(entity = \"Entity\", def = \"Relation::SelfRef.def().rev()\")]\n    SelfRefReverse,\n    #[sea_orm(entity = \"super::filling::Entity\")]\n    Filling\n}\n"
  },
  {
    "path": "sea-orm-codegen/tests/with_seaography/cake_frontend.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Model {\n    pub id: i32,\n    pub name: Option<String> ,\n    pub base_id: Option<i32> ,\n}"
  },
  {
    "path": "sea-orm-codegen/tests/with_seaography/mod.rs",
    "content": "//! SeaORM Entity. Generated by sea-orm-codegen 0.1.0\n\nseaography::register_entity_modules!([\n    cake,\n    cake_filling,\n    cake_filling_price,\n    filling,\n    fruit,\n    vendor,\n    rust_keyword,\n    cake_with_float,\n    cake_with_double,\n    collection,\n    collection_float,\n    parent,\n    child,\n]);\n\nseaography::register_active_enums!([\n    sea_orm_active_enums::CoinflipResultType,\n    sea_orm_active_enums::MediaType,\n]);\n"
  },
  {
    "path": "sea-orm-macros/Cargo.toml",
    "content": "[package]\nauthors       = [\"Billy Chan <ccw.billy.123@gmail.com>\"]\ncategories    = [\"database\"]\ndescription   = \"Derive macros for SeaORM\"\ndocumentation = \"https://docs.rs/sea-orm\"\nedition       = \"2024\"\nhomepage      = \"https://www.sea-ql.org/SeaORM\"\nkeywords      = [\"async\", \"orm\", \"mysql\", \"postgres\", \"sqlite\"]\nlicense       = \"MIT OR Apache-2.0\"\nname          = \"sea-orm-macros\"\nrepository    = \"https://github.com/SeaQL/sea-orm\"\nrust-version  = \"1.85.0\"\nversion       = \"2.0.0-rc.37\"\n\n[lib]\nname       = \"sea_orm_macros\"\npath       = \"src/lib.rs\"\nproc-macro = true\n\n[dependencies]\nbae = { version = \"0.2\", package = \"sea-bae\", default-features = false, optional = true }\nheck = { version = \"0.5\", default-features = false }\nitertools = \"0.14\"\npluralizer = { version = \"0.5\" }\nproc-macro-crate = { version = \"3.2.0\", optional = true }\nproc-macro2 = { version = \"1\", default-features = false }\nquote = { version = \"1\", default-features = false }\nsyn = { version = \"2\", default-features = false, features = [\n    \"parsing\",\n    \"proc-macro\",\n    \"derive\",\n    \"printing\",\n] }\nunicode-ident = { version = \"1\" }\n\n[dev-dependencies]\nsea-orm = { path = \"../\", default-features = false, features = [\n    \"macros\",\n    \"tests-cfg\",\n] }\nserde = { version = \"1.0\", features = [\"derive\"] }\n\n[features]\nasync           = []\ndefault         = [\"derive\"]\nderive          = [\"bae\"]\nentity-registry = []\npostgres-array  = []\nseaography      = [\"proc-macro-crate\"]\nstrum           = []\nwith-arrow      = []\nwith-json       = []\n"
  },
  {
    "path": "sea-orm-macros/src/derives/active_enum.rs",
    "content": "use super::case_style::{CaseStyle, CaseStyleHelpers};\nuse super::util::camel_case_with_escaped_non_uax31;\nuse heck::ToUpperCamelCase;\nuse proc_macro2::TokenStream;\nuse quote::{format_ident, quote, quote_spanned};\nuse syn::{Expr, Lit, LitInt, LitStr, UnOp, parse};\n\nstruct ActiveEnum {\n    ident: syn::Ident,\n    enum_name: String,\n    rs_type: TokenStream,\n    db_type: TokenStream,\n    is_string: bool,\n    variants: Vec<ActiveEnumVariant>,\n    rename_all: Option<CaseStyle>,\n}\n\nstruct ActiveEnumVariant {\n    ident: syn::Ident,\n    string_value: Option<LitStr>,\n    num_value: Option<LitInt>,\n    rename: Option<CaseStyle>,\n}\n\nenum Error {\n    InputNotEnum,\n    Syn(syn::Error),\n    TT(TokenStream),\n}\n\nimpl ActiveEnum {\n    fn new(input: syn::DeriveInput) -> Result<Self, Error> {\n        let ident_span = input.ident.span();\n        let ident = input.ident;\n\n        let mut enum_name = ident.to_string().to_upper_camel_case();\n        let mut rs_type = Err(Error::TT(quote_spanned! {\n            ident_span => compile_error!(\"Missing macro attribute `rs_type`\");\n        }));\n        let mut db_type = Err(Error::TT(quote_spanned! {\n            ident_span => compile_error!(\"Missing macro attribute `db_type`\");\n        }));\n        let mut rename_all = None;\n\n        input\n            .attrs\n            .iter()\n            .filter(|attr| attr.path().is_ident(\"sea_orm\"))\n            .try_for_each(|attr| {\n                attr.parse_nested_meta(|meta| {\n                    if meta.path.is_ident(\"rs_type\") {\n                        let litstr: LitStr = meta.value()?.parse()?;\n                        rs_type =\n                            syn::parse_str::<TokenStream>(&litstr.value()).map_err(Error::Syn);\n                    } else if meta.path.is_ident(\"db_type\") {\n                        let litstr: LitStr = meta.value()?.parse()?;\n                        let s = litstr.value();\n                        match s.as_ref() {\n                            \"Enum\" => {\n                                db_type = Ok(quote! {\n                                    Enum {\n                                        name: <Self as sea_orm::ActiveEnum>::name(),\n                                        variants: Self::iden_values(),\n                                    }\n                                })\n                            }\n                            _ => {\n                                db_type = syn::parse_str::<TokenStream>(&s).map_err(Error::Syn);\n                            }\n                        }\n                    } else if meta.path.is_ident(\"enum_name\") {\n                        let litstr: LitStr = meta.value()?.parse()?;\n                        enum_name = litstr.value();\n                    } else if meta.path.is_ident(\"rename_all\") {\n                        rename_all = Some((&meta).try_into()?);\n                    } else {\n                        return Err(meta.error(format!(\n                            \"Unknown attribute parameter found: {:?}\",\n                            meta.path.get_ident()\n                        )));\n                    }\n                    Ok(())\n                })\n                .map_err(Error::Syn)\n            })?;\n\n        let variant_vec = match input.data {\n            syn::Data::Enum(syn::DataEnum { variants, .. }) => variants,\n            _ => return Err(Error::InputNotEnum),\n        };\n\n        let mut is_string = rename_all.is_some();\n        let mut is_int = false;\n        let mut variants = Vec::new();\n\n        for variant in variant_vec {\n            let variant_span = variant.ident.span();\n            let mut string_value = None;\n            let mut num_value = None;\n            let mut rename_rule = None;\n\n            for attr in variant.attrs.iter() {\n                if !attr.path().is_ident(\"sea_orm\") {\n                    continue;\n                }\n                attr.parse_nested_meta(|meta| {\n                    if meta.path.is_ident(\"string_value\") {\n                        is_string = true;\n                        string_value = Some(meta.value()?.parse::<LitStr>()?);\n                    } else if meta.path.is_ident(\"num_value\") {\n                        is_int = true;\n                        num_value = Some(meta.value()?.parse::<LitInt>()?);\n                    } else if meta.path.is_ident(\"display_value\") {\n                        // This is a placeholder to prevent the `display_value` proc_macro attribute of `DeriveDisplay`\n                        // to be considered unknown attribute parameter\n                        meta.value()?.parse::<LitStr>()?;\n                    } else if meta.path.is_ident(\"rename\") {\n                        is_string = true;\n                        rename_rule = Some((&meta).try_into()?);\n                    } else {\n                        return Err(meta.error(format!(\n                            \"Unknown attribute parameter found: {:?}\",\n                            meta.path.get_ident()\n                        )));\n                    }\n\n                    Ok(())\n                })\n                .map_err(Error::Syn)?;\n            }\n\n            if is_string && is_int {\n                return Err(Error::TT(quote_spanned! {\n                    ident_span => compile_error!(\"All enum variants should specify the same `*_value` macro attribute, either `string_value` or `num_value` but not both\");\n                }));\n            }\n\n            if string_value.is_none() && num_value.is_none() && rename_rule.or(rename_all).is_none()\n            {\n                match variant.discriminant {\n                    Some((_, Expr::Lit(exprlit))) => {\n                        if let Lit::Int(litint) = exprlit.lit {\n                            is_int = true;\n                            num_value = Some(litint);\n                        } else {\n                            return Err(Error::TT(quote_spanned! {\n                                variant_span => compile_error!(\"Enum variant discriminant is not an integer\");\n                            }));\n                        }\n                    }\n                    //rust doesn't provide negative variants in enums as a single LitInt, this workarounds that\n                    Some((_, Expr::Unary(exprnlit))) => {\n                        if let UnOp::Neg(_) = exprnlit.op {\n                            if let Expr::Lit(exprlit) = *exprnlit.expr {\n                                if let Lit::Int(litint) = exprlit.lit {\n                                    let negative_token = quote! { -#litint };\n                                    let litint = parse(negative_token.into()).unwrap();\n\n                                    is_int = true;\n                                    num_value = Some(litint);\n                                }\n                            }\n                        } else {\n                            return Err(Error::TT(quote_spanned! {\n                                variant_span => compile_error!(\"Only - token is supported in enum variants, not ! and *\");\n                            }));\n                        }\n                    }\n                    _ => {\n                        return Err(Error::TT(quote_spanned! {\n                            variant_span => compile_error!(\"Missing macro attribute, either `string_value`, `num_value` or `rename` should be specified or specify repr[X] and have a value for every entry\");\n                        }));\n                    }\n                }\n            }\n\n            variants.push(ActiveEnumVariant {\n                ident: variant.ident,\n                string_value,\n                num_value,\n                rename: rename_rule,\n            });\n        }\n\n        Ok(ActiveEnum {\n            ident,\n            enum_name,\n            rs_type: rs_type?,\n            db_type: db_type?,\n            is_string,\n            variants,\n            rename_all,\n        })\n    }\n\n    fn expand(&self) -> syn::Result<TokenStream> {\n        let expanded_impl_active_enum = self.impl_active_enum();\n\n        Ok(expanded_impl_active_enum)\n    }\n\n    fn impl_active_enum(&self) -> TokenStream {\n        let Self {\n            ident,\n            enum_name,\n            rs_type,\n            db_type,\n            is_string,\n            variants,\n            rename_all,\n        } = self;\n\n        let variant_idents: Vec<syn::Ident> = variants\n            .iter()\n            .map(|variant| variant.ident.clone())\n            .collect();\n\n        let variant_values: Vec<TokenStream> = variants\n            .iter()\n            .map(|variant| {\n                let variant_span = variant.ident.span();\n\n                if let Some(string_value) = &variant.string_value {\n                    let string = string_value.value();\n                    quote! { #string }\n                } else if let Some(num_value) = &variant.num_value {\n                    quote! { #num_value }\n                } else if let Some(rename_rule) = variant.rename.or(*rename_all) {\n                    let variant_ident = variant.ident.convert_case(Some(rename_rule));\n                    quote! { #variant_ident }\n                } else {\n                    quote_spanned! {\n                        variant_span => compile_error!(\"Missing macro attribute, either `string_value`, `num_value` or `rename_all` should be specified\");\n                    }\n                }\n            })\n            .collect();\n\n        let val = if *is_string {\n            quote! { v.as_ref() }\n        } else {\n            quote! { v }\n        };\n\n        let enum_name_iden = format_ident!(\"{}Enum\", ident);\n\n        let str_variants: Vec<String> = variants\n            .iter()\n            .filter_map(|variant| {\n                variant\n                    .string_value\n                    .as_ref()\n                    .map(|string_value| string_value.value())\n                    .or(variant\n                        .rename\n                        .map(|rename| variant.ident.convert_case(Some(rename))))\n                    .or_else(|| rename_all.map(|rule| variant.ident.convert_case(Some(rule))))\n            })\n            .collect();\n\n        let impl_enum_variant_iden = if !str_variants.is_empty() {\n            let enum_variant_iden = format_ident!(\"{}Variant\", ident);\n            let enum_variants: Vec<syn::Ident> = str_variants\n                .iter()\n                .map(|v| {\n                    let v_cleaned = camel_case_with_escaped_non_uax31(v);\n\n                    format_ident!(\"{}\", v_cleaned)\n                })\n                .collect();\n\n            quote!(\n                #[doc = \" Generated by sea-orm-macros\"]\n                #[derive(Debug, Clone, PartialEq, Eq, sea_orm::EnumIter)]\n                pub enum #enum_variant_iden {\n                    #(\n                        #[doc = \" Generated by sea-orm-macros\"]\n                        #enum_variants,\n                    )*\n                }\n\n                #[automatically_derived]\n                impl sea_orm::Iden for #enum_variant_iden {\n                    fn unquoted(&self) -> &str {\n                        match self {\n                            #(\n                                Self::#enum_variants => #str_variants,\n                            )*\n                        }\n                    }\n                }\n\n                #[automatically_derived]\n                impl #ident {\n                    #[doc = \" Generated by sea-orm-macros\"]\n                    pub fn iden_values() -> Vec<sea_orm::sea_query::DynIden> {\n                        <#enum_variant_iden as sea_orm::strum::IntoEnumIterator>::iter()\n                            .map(|v| sea_orm::sea_query::SeaRc::new(v) as sea_orm::sea_query::DynIden)\n                            .collect()\n                    }\n                }\n            )\n        } else {\n            quote!()\n        };\n\n        let impl_not_u8 = if cfg!(feature = \"postgres-array\") {\n            quote!(\n                #[automatically_derived]\n                impl sea_orm::sea_query::postgres_array::NotU8 for #ident {}\n            )\n        } else {\n            quote!()\n        };\n\n        let impl_try_getable_array = if cfg!(feature = \"postgres-array\") {\n            quote!(\n                #[automatically_derived]\n                impl sea_orm::TryGetableArray for #ident {\n                    fn try_get_by<I: sea_orm::ColIdx>(res: &sea_orm::QueryResult, index: I) -> std::result::Result<Vec<Self>, sea_orm::TryGetError> {\n                        <<Self as sea_orm::ActiveEnum>::Value as sea_orm::ActiveEnumValue>::try_get_vec_by(res, index)?\n                            .into_iter()\n                            .map(|value| <Self as sea_orm::ActiveEnum>::try_from_value(&value).map_err(Into::into))\n                            .collect()\n                    }\n                }\n            )\n        } else {\n            quote!()\n        };\n\n        quote!(\n            #[doc = \" Generated by sea-orm-macros\"]\n            #[derive(Debug, Clone, PartialEq, Eq)]\n            pub struct #enum_name_iden;\n\n            #[automatically_derived]\n            impl sea_orm::Iden for #enum_name_iden {\n                fn unquoted(&self) -> &str {\n                    #enum_name\n                }\n            }\n\n            #impl_enum_variant_iden\n\n            #[automatically_derived]\n            impl sea_orm::ActiveEnum for #ident {\n                type Value = #rs_type;\n\n                type ValueVec = Vec<#rs_type>;\n\n                fn name() -> sea_orm::sea_query::DynIden {\n                    sea_orm::sea_query::SeaRc::new(#enum_name_iden) as sea_orm::sea_query::DynIden\n                }\n\n                fn to_value(&self) -> <Self as sea_orm::ActiveEnum>::Value {\n                    match self {\n                        #( Self::#variant_idents => #variant_values, )*\n                    }\n                    .to_owned()\n                }\n\n                fn try_from_value(v: &<Self as sea_orm::ActiveEnum>::Value) -> std::result::Result<Self, sea_orm::DbErr> {\n                    match #val {\n                        #( #variant_values => Ok(Self::#variant_idents), )*\n                        _ => Err(sea_orm::DbErr::Type(format!(\n                            \"unexpected value for {} enum: {}\",\n                            stringify!(#ident),\n                            v\n                        ))),\n                    }\n                }\n\n                fn db_type() -> sea_orm::ColumnDef {\n                    sea_orm::prelude::ColumnTypeTrait::def(sea_orm::ColumnType::#db_type)\n                }\n            }\n\n            #impl_try_getable_array\n\n            #[automatically_derived]\n            #[allow(clippy::from_over_into)]\n            impl Into<sea_orm::sea_query::Value> for #ident {\n                fn into(self) -> sea_orm::sea_query::Value {\n                    <Self as sea_orm::ActiveEnum>::to_value(&self).into()\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::TryGetable for #ident {\n                fn try_get_by<I: sea_orm::ColIdx>(res: &sea_orm::QueryResult, idx: I) -> std::result::Result<Self, sea_orm::TryGetError> {\n                    let value = <<Self as sea_orm::ActiveEnum>::Value as sea_orm::TryGetable>::try_get_by(res, idx)?;\n                    <Self as sea_orm::ActiveEnum>::try_from_value(&value).map_err(sea_orm::TryGetError::DbErr)\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::sea_query::ValueType for #ident {\n                fn try_from(v: sea_orm::sea_query::Value) -> std::result::Result<Self, sea_orm::sea_query::ValueTypeErr> {\n                    let value = <<Self as sea_orm::ActiveEnum>::Value as sea_orm::sea_query::ValueType>::try_from(v)?;\n                    <Self as sea_orm::ActiveEnum>::try_from_value(&value).map_err(|_| sea_orm::sea_query::ValueTypeErr)\n                }\n\n                fn type_name() -> String {\n                    <<Self as sea_orm::ActiveEnum>::Value as sea_orm::sea_query::ValueType>::type_name()\n                }\n\n                fn array_type() -> sea_orm::sea_query::ArrayType {\n                    <<Self as sea_orm::ActiveEnum>::Value as sea_orm::sea_query::ValueType>::array_type()\n                }\n\n                fn column_type() -> sea_orm::sea_query::ColumnType {\n                    <Self as sea_orm::ActiveEnum>::db_type()\n                        .get_column_type()\n                        .to_owned()\n                        .into()\n                }\n\n                fn enum_type_name() -> Option<&'static str> {\n                    Some(stringify!(#ident))\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::sea_query::Nullable for #ident {\n                fn null() -> sea_orm::sea_query::Value {\n                    <<Self as sea_orm::ActiveEnum>::Value as sea_orm::sea_query::Nullable>::null()\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::IntoActiveValue<#ident> for #ident {\n                fn into_active_value(self) -> sea_orm::ActiveValue<#ident> {\n                    sea_orm::ActiveValue::set(self)\n                }\n            }\n\n            #impl_not_u8\n        )\n    }\n}\n\npub fn expand_derive_active_enum(input: syn::DeriveInput) -> syn::Result<TokenStream> {\n    let ident_span = input.ident.span();\n\n    match ActiveEnum::new(input) {\n        Ok(model) => model.expand(),\n        Err(Error::InputNotEnum) => Ok(quote_spanned! {\n            ident_span => compile_error!(\"you can only derive ActiveEnum on enums\");\n        }),\n        Err(Error::TT(token_stream)) => Ok(token_stream),\n        Err(Error::Syn(e)) => Err(e),\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/active_enum_display.rs",
    "content": "use super::case_style::CaseStyle;\nuse proc_macro2::TokenStream;\nuse quote::{ToTokens, quote, quote_spanned};\nuse syn::{LitInt, LitStr};\n\nenum Error {\n    InputNotEnum,\n    Syn(syn::Error),\n}\n\nstruct Display {\n    ident: syn::Ident,\n    variants: Vec<DisplayVariant>,\n}\n\nstruct DisplayVariant {\n    ident: syn::Ident,\n    display_value: TokenStream,\n}\n\nimpl Display {\n    fn new(input: syn::DeriveInput) -> Result<Self, Error> {\n        let ident = input.ident;\n\n        let variant_vec = match input.data {\n            syn::Data::Enum(syn::DataEnum { variants, .. }) => variants,\n            _ => return Err(Error::InputNotEnum),\n        };\n\n        let mut variants = Vec::new();\n        for variant in variant_vec {\n            let mut display_value = variant.ident.to_string().to_token_stream();\n\n            for attr in variant.attrs.iter() {\n                if !attr.path().is_ident(\"sea_orm\") {\n                    continue;\n                }\n                attr.parse_nested_meta(|meta| {\n                    if meta.path.is_ident(\"string_value\") {\n                        meta.value()?.parse::<LitStr>()?;\n                    } else if meta.path.is_ident(\"num_value\") {\n                        meta.value()?.parse::<LitInt>()?;\n                    } else if meta.path.is_ident(\"display_value\") {\n                        display_value = meta.value()?.parse::<LitStr>()?.to_token_stream();\n                    } else if meta.path.is_ident(\"rename\") {\n                        CaseStyle::try_from(&meta)?;\n                    } else {\n                        return Err(meta.error(format!(\n                            \"Unknown attribute parameter found: {:?}\",\n                            meta.path.get_ident()\n                        )));\n                    }\n\n                    Ok(())\n                })\n                .map_err(Error::Syn)?;\n            }\n            variants.push(DisplayVariant {\n                ident: variant.ident,\n                display_value,\n            });\n        }\n        Ok(Display { ident, variants })\n    }\n\n    fn expand(&self) -> syn::Result<TokenStream> {\n        let expanded_impl_active_enum_display = self.impl_active_enum_display();\n\n        Ok(expanded_impl_active_enum_display)\n    }\n\n    fn impl_active_enum_display(&self) -> TokenStream {\n        let Self { ident, variants } = self;\n\n        let variant_idents: Vec<_> = variants\n            .iter()\n            .map(|variant| variant.ident.clone())\n            .collect();\n\n        let variant_display: Vec<_> = variants\n            .iter()\n            .map(|variant| variant.display_value.to_owned())\n            .collect();\n\n        quote!(\n            #[automatically_derived]\n            impl std::fmt::Display for #ident {\n                fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n                    write!(f, \"{}\", match self {\n                        #( Self::#variant_idents => #variant_display, )*\n                    })\n                }\n            }\n        )\n    }\n}\n\npub fn expand_derive_active_enum_display(input: syn::DeriveInput) -> syn::Result<TokenStream> {\n    let ident_span = input.ident.span();\n\n    match Display::new(input) {\n        Ok(model) => model.expand(),\n        Err(Error::InputNotEnum) => Ok(quote_spanned! {\n            ident_span => compile_error!(\"you can only derive EnumDisplay on enums\");\n        }),\n        Err(Error::Syn(e)) => Err(e),\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/active_model.rs",
    "content": "use super::util::{\n    escape_rust_keyword, field_not_ignored, format_field_ident, trim_starting_raw_identifier,\n};\nuse heck::ToUpperCamelCase;\nuse proc_macro2::{Ident, TokenStream};\nuse quote::{format_ident, quote};\nuse syn::{Data, DataStruct, Expr, Fields, LitStr, Type};\n\npub(crate) struct DeriveActiveModel {\n    model: Ident,\n    fields: Vec<Ident>,\n    names: Vec<Ident>,\n    types: Vec<Type>,\n}\n\nimpl DeriveActiveModel {\n    pub fn new(ident: &Ident, data: &Data) -> syn::Result<Self> {\n        let all_fields = match data {\n            Data::Struct(DataStruct {\n                fields: Fields::Named(named),\n                ..\n            }) => &named.named,\n            _ => {\n                return Err(syn::Error::new_spanned(\n                    ident,\n                    \"You can only derive DeriveActiveModel on structs\",\n                ));\n            }\n        };\n\n        let mut fields = Vec::new();\n        let mut names = Vec::new();\n        let mut types = Vec::new();\n\n        for field in all_fields.iter().filter(|f| field_not_ignored(f)) {\n            fields.push(format_field_ident(field));\n\n            let ident = field.ident.as_ref().unwrap().to_string();\n            let ident = trim_starting_raw_identifier(ident).to_upper_camel_case();\n            let ident = escape_rust_keyword(ident);\n            let mut ident = format_ident!(\"{}\", &ident);\n            field\n                .attrs\n                .iter()\n                .filter(|attr| attr.path().is_ident(\"sea_orm\"))\n                .try_for_each(|attr| {\n                    attr.parse_nested_meta(|meta| {\n                        if meta.path.is_ident(\"enum_name\") {\n                            let litstr: LitStr = meta.value()?.parse()?;\n                            ident = syn::parse_str(&litstr.value()).unwrap();\n                        } else {\n                            // Reads the value expression to advance the parse stream.\n                            // Some parameters, such as `primary_key`, do not have any value,\n                            // so ignoring an error occurred here.\n                            let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();\n                        }\n\n                        Ok(())\n                    })\n                })?;\n\n            names.push(ident);\n            types.push(field.ty.clone());\n        }\n\n        Ok(DeriveActiveModel {\n            model: ident.clone(),\n            fields,\n            names,\n            types,\n        })\n    }\n}\n\nimpl DeriveActiveModel {\n    fn define_active_model(&self) -> TokenStream {\n        let fields = &self.fields;\n        let types = &self.types;\n        quote!(\n            #[doc = \" Generated by sea-orm-macros\"]\n            #[derive(Clone, Debug, PartialEq)]\n            pub struct ActiveModel {\n                #(\n                    #[doc = \" Generated by sea-orm-macros\"]\n                    pub #fields: sea_orm::ActiveValue<#types>\n                ),*\n            }\n        )\n    }\n\n    fn impl_active_model(&self) -> TokenStream {\n        let mut ts = self.impl_active_model_convert();\n        ts.extend(self.impl_active_model_trait());\n        ts\n    }\n\n    fn impl_active_model_convert(&self) -> TokenStream {\n        let model = &self.model;\n        let fields = &self.fields;\n\n        quote!(\n            #[automatically_derived]\n            impl std::default::Default for ActiveModel {\n                fn default() -> Self {\n                    <Self as sea_orm::ActiveModelBehavior>::new()\n                }\n            }\n\n            #[automatically_derived]\n            impl std::convert::From<#model> for ActiveModel {\n                fn from(m: #model) -> Self {\n                    Self {\n                        #(#fields: sea_orm::ActiveValue::Unchanged(m.#fields)),*\n                    }\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::IntoActiveModel<ActiveModel> for #model {\n                fn into_active_model(self) -> ActiveModel {\n                    self.into()\n                }\n            }\n        )\n    }\n\n    fn impl_active_model_trait(&self) -> TokenStream {\n        let fields = &self.fields;\n        let methods = self.impl_active_model_trait_methods();\n\n        quote! {\n            #[automatically_derived]\n            impl sea_orm::ActiveModelTrait for ActiveModel {\n                type Entity = Entity;\n\n                #methods\n\n                fn default() -> Self {\n                    Self {\n                        #(#fields: sea_orm::ActiveValue::NotSet),*\n                    }\n                }\n            }\n        }\n    }\n\n    pub fn impl_active_model_trait_methods(&self) -> TokenStream {\n        let fields = &self.fields;\n        let names = &self.names;\n\n        quote!(\n            fn take(&mut self, c: <Self::Entity as sea_orm::EntityTrait>::Column) -> sea_orm::ActiveValue<sea_orm::Value> {\n                match c {\n                    #(<Self::Entity as sea_orm::EntityTrait>::Column::#names => {\n                        let mut value = sea_orm::ActiveValue::NotSet;\n                        std::mem::swap(&mut value, &mut self.#fields);\n                        value.into_wrapped_value()\n                    },)*\n                    _ => sea_orm::ActiveValue::NotSet,\n                }\n            }\n\n            fn get(&self, c: <Self::Entity as sea_orm::EntityTrait>::Column) -> sea_orm::ActiveValue<sea_orm::Value> {\n                match c {\n                    #(<Self::Entity as sea_orm::EntityTrait>::Column::#names => self.#fields.clone().into_wrapped_value(),)*\n                    _ => sea_orm::ActiveValue::NotSet,\n                }\n            }\n\n            fn set_if_not_equals(&mut self, c: <Self::Entity as sea_orm::EntityTrait>::Column, v: sea_orm::Value) {\n                match c {\n                    #(<Self::Entity as sea_orm::EntityTrait>::Column::#names => self.#fields.set_if_not_equals(v.unwrap()),)*\n                    _ => (),\n                }\n            }\n\n            fn try_set(&mut self, c: <Self::Entity as sea_orm::EntityTrait>::Column, v: sea_orm::Value) -> Result<(), sea_orm::DbErr> {\n                match c {\n                    #(<Self::Entity as sea_orm::EntityTrait>::Column::#names => self.#fields = sea_orm::ActiveValue::Set(sea_orm::sea_query::ValueType::try_from(v).map_err(|e| sea_orm::DbErr::Type(e.to_string()))?),)*\n                    _ => return Err(sea_orm::DbErr::Type(format!(\"ActiveModel does not have this field: {:?}\", sea_orm::ColumnTrait::as_column_ref(&c)))),\n                }\n                Ok(())\n            }\n\n            fn not_set(&mut self, c: <Self::Entity as sea_orm::EntityTrait>::Column) {\n                match c {\n                    #(<Self::Entity as sea_orm::EntityTrait>::Column::#names => self.#fields = sea_orm::ActiveValue::NotSet,)*\n                    _ => (),\n                }\n            }\n\n            fn is_not_set(&self, c: <Self::Entity as sea_orm::EntityTrait>::Column) -> bool {\n                match c {\n                    #(<Self::Entity as sea_orm::EntityTrait>::Column::#names => self.#fields.is_not_set(),)*\n                    _ => panic!(\"This ActiveModel does not have this field\"),\n                }\n            }\n\n            fn reset(&mut self, c: <Self::Entity as sea_orm::EntityTrait>::Column) {\n                match c {\n                    #(<Self::Entity as sea_orm::EntityTrait>::Column::#names => self.#fields.reset(),)*\n                    _ => panic!(\"This ActiveModel does not have this field\"),\n                }\n            }\n\n            fn default_values() -> Self {\n                use sea_orm::value::{DefaultActiveValue, DefaultActiveValueNone, DefaultActiveValueNotSet};\n                let mut default = <Self as sea_orm::ActiveModelTrait>::default();\n                #(default.#fields = (&default.#fields).default_value();)*\n                default\n            }\n        )\n    }\n}\n\nfn derive_into_model(ident: &Ident, data: &Data) -> syn::Result<TokenStream> {\n    let model_fields = match data {\n        Data::Struct(DataStruct {\n            fields: Fields::Named(named),\n            ..\n        }) => &named.named,\n        _ => {\n            return Err(syn::Error::new_spanned(\n                ident,\n                \"You can only derive DeriveActiveModel on structs\",\n            ));\n        }\n    };\n\n    let active_model_field: Vec<Ident> = model_fields\n        .iter()\n        .filter(|f| field_not_ignored(f))\n        .map(format_field_ident)\n        .collect();\n\n    let model_field: Vec<Ident> = model_fields.iter().map(format_field_ident).collect();\n\n    let ignore_attr: Vec<bool> = model_fields.iter().map(|f| !field_not_ignored(f)).collect();\n\n    let model_field_value: Vec<TokenStream> = model_field\n        .iter()\n        .zip(ignore_attr)\n        .map(|(field, ignore)| {\n            if ignore {\n                quote! {\n                    Default::default()\n                }\n            } else {\n                quote! {\n                    a.#field.unwrap()\n                }\n            }\n        })\n        .collect();\n\n    Ok(quote!(\n        #[automatically_derived]\n        impl std::convert::TryFrom<ActiveModel> for #ident {\n            type Error = sea_orm::DbErr;\n            fn try_from(a: ActiveModel) -> Result<Self, sea_orm::DbErr> {\n                #(if a.#active_model_field.is_not_set() {\n                    return Err(sea_orm::DbErr::AttrNotSet(stringify!(#active_model_field).to_owned()));\n                })*\n                Ok(\n                    Self {\n                        #(#model_field: #model_field_value),*\n                    }\n                )\n            }\n        }\n\n        #[automatically_derived]\n        impl sea_orm::TryIntoModel<#ident> for ActiveModel {\n            fn try_into_model(self) -> Result<#ident, sea_orm::DbErr> {\n                self.try_into()\n            }\n        }\n    ))\n}\n\npub fn expand_derive_active_model(ident: &Ident, data: &Data) -> syn::Result<TokenStream> {\n    let derive_active_model = DeriveActiveModel::new(ident, data)?;\n\n    let define_active_model = derive_active_model.define_active_model();\n    let impl_active_model = derive_active_model.impl_active_model();\n    let derive_into_model = derive_into_model(ident, data)?;\n\n    Ok(quote!(\n        #define_active_model\n\n        #impl_active_model\n\n        #derive_into_model\n    ))\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/active_model_behavior.rs",
    "content": "use proc_macro2::{Ident, TokenStream};\nuse quote::quote;\nuse syn::Data;\n\n/// Method to derive an implementation of [ActiveModelBehavior](sea_orm::ActiveModelBehavior)\npub fn expand_derive_active_model_behavior(_ident: Ident, _data: Data) -> syn::Result<TokenStream> {\n    Ok(quote!(\n        #[automatically_derived]\n        impl sea_orm::ActiveModelBehavior for ActiveModel {}\n    ))\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/active_model_ex.rs",
    "content": "use super::active_model::DeriveActiveModel;\nuse super::attributes::compound_attr;\nuse super::util::{extract_compound_entity, field_not_ignored_compound, is_compound_field};\nuse proc_macro2::{Ident, TokenStream};\nuse quote::{format_ident, quote};\nuse std::collections::HashMap;\nuse syn::{Attribute, Data, Expr, Fields, LitStr, Type};\n\npub fn expand_derive_active_model_ex(\n    ident: &Ident,\n    data: &Data,\n    attrs: &[Attribute],\n) -> syn::Result<TokenStream> {\n    let mut compact = false;\n    let mut model_fields = Vec::new();\n    let mut ignored_model_fields = Vec::new();\n    let mut field_types: Vec<Type> = Vec::new();\n    let mut scalar_fields = Vec::new();\n    let mut compound_fields = Vec::new();\n    let mut belongs_to_fields = Vec::new();\n    let mut belongs_to_self_fields = Vec::new();\n    let mut has_one_fields = Vec::new();\n    let mut has_many_fields = Vec::new();\n    let mut has_many_self_fields = Vec::new();\n    let mut has_many_via_fields = Vec::new();\n    let mut has_many_via_self_fields = Vec::new();\n\n    let (async_, await_) = async_await();\n\n    attrs\n        .iter()\n        .filter(|attr| attr.path().is_ident(\"sea_orm\"))\n        .try_for_each(|attr| {\n            attr.parse_nested_meta(|meta| {\n                if meta.path.is_ident(\"compact_model\") {\n                    compact = true;\n                } else {\n                    // Reads the value expression to advance the parse stream.\n                    let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();\n                }\n                Ok(())\n            })\n        })?;\n\n    let mut entity_count = HashMap::new();\n\n    if let Data::Struct(item_struct) = &data {\n        if let Fields::Named(fields) = &item_struct.fields {\n            for field in fields.named.iter() {\n                if field.ident.is_some() && field_not_ignored_compound(field) {\n                    let field_type = &field.ty;\n                    let field_type = quote! { #field_type }\n                        .to_string() // e.g.: \"Option < String >\"\n                        .replace(' ', \"\"); // Remove spaces\n\n                    if is_compound_field(&field_type) {\n                        let entity_path = extract_compound_entity(&field_type);\n                        *entity_count.entry(entity_path.to_owned()).or_insert(0) += 1;\n                    }\n                }\n            }\n        }\n    }\n\n    if let Data::Struct(item_struct) = &data {\n        if let Fields::Named(fields) = &item_struct.fields {\n            for field in fields.named.iter() {\n                if let Some(ident) = &field.ident {\n                    if field_not_ignored_compound(field) {\n                        let field_type = &field.ty;\n                        let field_type = quote! { #field_type }\n                            .to_string() // e.g.: \"Option < String >\"\n                            .replace(' ', \"\"); // Remove spaces\n\n                        let ty = if is_compound_field(&field_type) {\n                            compound_fields.push(ident);\n                            let entity_path = extract_compound_entity(&field_type);\n\n                            if !compact {\n                                let compound_attrs =\n                                    compound_attr::SeaOrm::from_attributes(&field.attrs)?;\n                                if let Some(relation_enum) = compound_attrs.relation_enum {\n                                    if compound_attrs.self_ref.is_some()\n                                        && compound_attrs.via.is_none()\n                                        && compound_attrs.from.is_some()\n                                        && compound_attrs.to.is_some()\n                                    {\n                                        belongs_to_self_fields\n                                            .push((ident.clone(), relation_enum.clone()));\n                                    } else if compound_attrs.self_ref.is_some()\n                                        && compound_attrs.relation_reverse.is_some()\n                                        && compound_attrs.via.is_none()\n                                        && compound_attrs.from.is_none()\n                                        && compound_attrs.to.is_none()\n                                    {\n                                        has_many_self_fields\n                                            .push((ident.clone(), relation_enum.clone()));\n                                    }\n                                } else if *entity_count.get(entity_path).unwrap() == 1 {\n                                    // can only Related to another Entity once\n                                    if compound_attrs.belongs_to.is_some() {\n                                        belongs_to_fields.push(ident.clone());\n                                    } else if compound_attrs.has_one.is_some() {\n                                        has_one_fields.push(ident.clone());\n                                    } else if compound_attrs.has_many.is_some()\n                                        && compound_attrs.via.is_none()\n                                    {\n                                        has_many_fields.push(ident.clone());\n                                    } else if compound_attrs.has_many.is_some()\n                                        && compound_attrs.via.is_some()\n                                    {\n                                        has_many_via_fields.push((\n                                            ident.clone(),\n                                            compound_attrs.via.as_ref().unwrap().value(),\n                                        ));\n                                    }\n                                }\n                                if compound_attrs.self_ref.is_some()\n                                    && compound_attrs.via.is_some()\n                                    && compound_attrs.reverse.is_none()\n                                {\n                                    #[allow(clippy::unnecessary_unwrap)]\n                                    has_many_via_self_fields.push((\n                                        ident.clone(),\n                                        compound_attrs.via.as_ref().unwrap().value(),\n                                        false,\n                                    ));\n                                } else if compound_attrs.self_ref.is_some()\n                                    && compound_attrs.via.is_some()\n                                    && compound_attrs.reverse.is_some()\n                                {\n                                    #[allow(clippy::unnecessary_unwrap)]\n                                    has_many_via_self_fields.push((\n                                        ident.clone(),\n                                        compound_attrs.via.as_ref().unwrap().value(),\n                                        true,\n                                    ));\n                                }\n                            }\n\n                            if field_type.starts_with(\"HasOne<\") {\n                                syn::parse_str(&format!(\"HasOneModel < {entity_path} >\"))?\n                            } else {\n                                syn::parse_str(&format!(\"HasManyModel < {entity_path} >\"))?\n                            }\n                        } else {\n                            scalar_fields.push(ident);\n                            syn::parse_str(&format!(\"sea_orm::ActiveValue < {field_type} >\"))?\n                        };\n                        model_fields.push(ident);\n                        field_types.push(ty);\n                    } else {\n                        ignored_model_fields.push(ident);\n                    }\n                }\n            }\n        }\n    }\n\n    let active_model_trait_methods =\n        DeriveActiveModel::new(ident, data)?.impl_active_model_trait_methods();\n\n    let active_model_action = expand_active_model_action(\n        &belongs_to_fields,\n        &belongs_to_self_fields,\n        &has_one_fields,\n        &has_many_fields,\n        &has_many_self_fields,\n        &has_many_via_fields,\n        &has_many_via_self_fields,\n    );\n\n    let active_model_setters = expand_active_model_setters(data)?;\n\n    let mut is_changed_expr = quote!(false);\n\n    for field in scalar_fields.iter() {\n        is_changed_expr.extend(quote!(|| self.#field.is_set()));\n    }\n    for field in compound_fields.iter() {\n        is_changed_expr.extend(quote!(|| self.#field.is_changed()));\n    }\n\n    Ok(quote! {\n        #[doc = \" Generated by sea-orm-macros\"]\n        #[derive(Clone, Debug, PartialEq)]\n        pub struct ActiveModelEx {\n            #(\n                #[doc = \" Generated by sea-orm-macros\"]\n                pub #model_fields: #field_types\n            ),*\n        }\n\n        impl ActiveModel {\n            #[doc = \" Generated by sea-orm-macros\"]\n            pub fn into_ex(self) -> ActiveModelEx {\n                self.into()\n            }\n        }\n\n        #[automatically_derived]\n        impl sea_orm::ActiveModelTrait for ActiveModelEx {\n            type Entity = Entity;\n\n            #active_model_trait_methods\n\n            /// Returns true if any field is set or changed. This is recursive.\n            fn is_changed(&self) -> bool {\n                #is_changed_expr\n            }\n\n            fn default() -> Self {\n                <ActiveModel as sea_orm::ActiveModelBehavior>::new().into()\n            }\n        }\n\n        impl ActiveModelEx {\n            #[doc = \" Generated by sea-orm-macros\"]\n            pub fn new() -> Self {\n                <Self as sea_orm::ActiveModelTrait>::default()\n            }\n\n            #active_model_action\n\n            #active_model_setters\n        }\n\n        #[automatically_derived]\n        impl std::default::Default for ActiveModelEx {\n            fn default() -> Self {\n                <Self as sea_orm::ActiveModelTrait>::default()\n            }\n        }\n\n        #[automatically_derived]\n        impl std::convert::From<ActiveModel> for ActiveModelEx {\n            fn from(m: ActiveModel) -> Self {\n                Self {\n                    #(#scalar_fields: m.#scalar_fields,)*\n                    #(#compound_fields: Default::default(),)*\n                }\n            }\n        }\n\n        #[automatically_derived]\n        impl std::convert::From<ActiveModelEx> for ActiveModel {\n            fn from(m: ActiveModelEx) -> Self {\n                Self {\n                    #(#scalar_fields: m.#scalar_fields,)*\n                }\n            }\n        }\n\n        #[automatically_derived]\n        impl std::convert::From<ModelEx> for ActiveModelEx {\n            fn from(m: ModelEx) -> Self {\n                Self {\n                    #(#scalar_fields: sea_orm::ActiveValue::Unchanged(m.#scalar_fields),)*\n                    #(#compound_fields: m.#compound_fields.into_active_model(),)*\n                }\n            }\n        }\n\n        #[automatically_derived]\n        impl std::convert::TryFrom<ActiveModelEx> for ModelEx {\n            type Error = sea_orm::DbErr;\n            fn try_from(a: ActiveModelEx) -> Result<Self, sea_orm::DbErr> {\n                #(if a.#scalar_fields.is_not_set() {\n                    return Err(sea_orm::DbErr::AttrNotSet(stringify!(#scalar_fields).to_owned()));\n                })*\n                Ok(\n                    Self {\n                        #(#scalar_fields: a.#scalar_fields.unwrap(),)*\n                        #(#compound_fields: a.#compound_fields.try_into_model()?,)*\n                        #(#ignored_model_fields: Default::default(),)*\n                    }\n                )\n            }\n        }\n\n        #[automatically_derived]\n        impl sea_orm::IntoActiveModel<ActiveModelEx> for ModelEx {\n            fn into_active_model(self) -> ActiveModelEx {\n                self.into()\n            }\n        }\n\n        #[automatically_derived]\n        impl sea_orm::TryIntoModel<ModelEx> for ActiveModelEx {\n            fn try_into_model(self) -> Result<ModelEx, sea_orm::DbErr> {\n                self.try_into()\n            }\n        }\n\n        impl Model {\n            #[doc = \" Generated by sea-orm-macros\"]\n            pub #async_ fn cascade_delete<'a, C>(self, db: &'a C) -> Result<sea_orm::DeleteResult, sea_orm::DbErr>\n            where\n                C: sea_orm::TransactionTrait,\n            {\n                self.into_ex().delete(db)#await_\n            }\n        }\n\n        impl ModelEx {\n            #[doc = \" Generated by sea-orm-macros\"]\n            pub #async_ fn delete<'a, C>(self, db: &'a C) -> Result<sea_orm::DeleteResult, sea_orm::DbErr>\n            where\n                C: sea_orm::TransactionTrait,\n            {\n                let active_model: ActiveModelEx = self.into();\n                active_model.delete(db)#await_\n            }\n        }\n\n        impl ActiveModel {\n            #[doc = \" Generated by sea-orm-macros\"]\n            pub fn builder() -> ActiveModelEx {\n                ActiveModelEx::new()\n            }\n        }\n    })\n}\n\nfn expand_active_model_action(\n    belongs_to: &[Ident],\n    belongs_to_self: &[(Ident, LitStr)],\n    has_one: &[Ident],\n    has_many: &[Ident],\n    has_many_self: &[(Ident, LitStr)],\n    has_many_via: &[(Ident, String)],\n    has_many_via_self: &[(Ident, String, bool)],\n) -> TokenStream {\n    let mut belongs_to_action = TokenStream::new();\n    let mut belongs_to_after_action = TokenStream::new();\n    let mut has_one_before_action = TokenStream::new();\n    let mut has_one_action = TokenStream::new();\n    let mut has_one_delete = TokenStream::new();\n    let mut has_many_before_action = TokenStream::new();\n    let mut has_many_action = TokenStream::new();\n    let mut has_many_delete = TokenStream::new();\n    let mut has_many_via_before_action = TokenStream::new();\n    let mut has_many_via_action = TokenStream::new();\n    let mut has_many_via_delete = TokenStream::new();\n\n    let (async_, await_) = async_await();\n    let box_pin = if cfg!(feature = \"async\") {\n        quote!(Box::pin)\n    } else {\n        quote!()\n    };\n\n    for field in belongs_to {\n        belongs_to_action.extend(quote! {\n            let #field = if let Some(model) = self.#field.take() {\n                if model.is_update() {\n                    // has primary key\n                    self.set_parent_key(&model)?;\n                    if model.is_changed() {\n                        let model = #box_pin(model.action(action, db))#await_?;\n                        Some(model)\n                    } else {\n                        Some(model)\n                    }\n                } else {\n                    // new model\n                    let model = #box_pin(model.action(action, db))#await_?;\n                    self.set_parent_key(&model)?;\n                    Some(model)\n                }\n            } else {\n                None\n            };\n        });\n\n        belongs_to_after_action.extend(quote! {\n            if let Some(#field) = #field {\n                model.#field = HasOneModel::set(#field);\n            }\n        });\n    }\n\n    for (field, relation_enum) in belongs_to_self {\n        let relation_enum = Ident::new(&relation_enum.value(), relation_enum.span());\n        let relation_enum = quote!(Relation::#relation_enum);\n\n        // belongs to is the exception where action is performed before self\n        belongs_to_action.extend(quote! {\n            let #field = if let Some(model) = self.#field.take() {\n                if model.is_update() {\n                    // has primary key\n                    self.set_parent_key_for(&model, #relation_enum)?;\n                    if model.is_changed() {\n                        let model = #box_pin(model.action(action, db))#await_?;\n                        Some(model)\n                    } else {\n                        Some(model)\n                    }\n                } else {\n                    // new model\n                    let model = #box_pin(model.action(action, db))#await_?;\n                    self.set_parent_key_for(&model, #relation_enum)?;\n                    Some(model)\n                }\n            } else {\n                None\n            };\n        });\n\n        belongs_to_after_action.extend(quote! {\n            if let Some(#field) = #field {\n                model.#field = HasOneModel::set(#field);\n            }\n        });\n    }\n\n    let delete_associated_model = quote! {\n        let mut item = item.into_active_model();\n        if item.clear_parent_key::<Entity>()? {\n            item.update(db)#await_?;\n        } else {\n            deleted.merge(item.into_ex().delete(db)#await_?); // deep delete\n        }\n    };\n\n    for field in has_one {\n        has_one_before_action.extend(quote! {\n            let #field = self.#field.take();\n        });\n\n        has_one_action.extend(quote! {\n            if let Some(mut #field) = #field {\n                #field.set_parent_key(&model)?;\n                if #field.is_changed() {\n                    model.#field = HasOneModel::set(#box_pin(#field.action(action, db))#await_?);\n                } else {\n                    model.#field = HasOneModel::set(#field);\n                }\n            }\n        });\n\n        has_one_delete.extend(quote! {\n            if let Some(item) = self.find_related_of(self.#field.empty_slice()).one(db)#await_? {\n                #delete_associated_model\n            }\n        });\n    }\n\n    for field in has_many {\n        has_many_before_action.extend(quote! {\n            let #field = self.#field.take();\n        });\n\n        has_many_action.extend(quote! {\n            if #field.is_replace() {\n                for item in model.find_related_of(#field.as_slice()).all(db)#await_? {\n                    if !#field.find(&item) {\n                        #delete_associated_model\n                    }\n                }\n            }\n            model.#field = #field.empty_holder();\n            for mut #field in #field.into_vec() {\n                #field.set_parent_key(&model)?;\n                if #field.is_changed() {\n                    model.#field.push(#box_pin(#field.action(action, db))#await_?);\n                } else {\n                    model.#field.push(#field);\n                }\n            }\n        });\n\n        has_many_delete.extend(quote! {\n            for item in self.find_related_of(self.#field.as_slice()).all(db)#await_? {\n                #delete_associated_model\n            }\n        });\n    }\n\n    for (field, relation_enum) in has_many_self {\n        let relation_enum = Ident::new(&relation_enum.value(), relation_enum.span());\n        let relation_enum = quote!(Relation::#relation_enum);\n\n        let delete_associated_model = quote! {\n            let mut item = item.into_active_model();\n            if item.clear_parent_key_for_self_rev(#relation_enum)? {\n                item.update(db)#await_?;\n            } else {\n                // attempt to cascade delete may lead to infinite recursion\n                return Err(sea_orm::DbErr::RecordNotUpdated);\n            }\n        };\n\n        has_many_before_action.extend(quote! {\n            let #field = self.#field.take();\n        });\n\n        has_many_action.extend(quote! {\n            if #field.is_replace() {\n                for item in model.find_belongs_to_self(#relation_enum, db.get_database_backend())?.all(db)#await_? {\n                    if !#field.find(&item) {\n                        #delete_associated_model\n                    }\n                }\n            }\n            model.#field = #field.empty_holder();\n            for mut #field in #field.into_vec() {\n                #field.set_parent_key_for_self_rev(&model, #relation_enum)?;\n                if #field.is_changed() {\n                    model.#field.push(#box_pin(#field.action(action, db))#await_?);\n                } else {\n                    model.#field.push(#field);\n                }\n            }\n        });\n\n        has_many_delete.extend(quote! {\n            for item in self.find_belongs_to_self(#relation_enum, db.get_database_backend())?.all(db)#await_? {\n                #delete_associated_model\n            }\n        });\n    }\n\n    for (field, via_entity) in has_many_via {\n        let mut via_entity = via_entity.as_str();\n        if let Some((prefix, _)) = via_entity.split_once(\"::\") {\n            via_entity = prefix;\n        }\n\n        let related_entity: TokenStream = format!(\"super::{via_entity}::Entity\").parse().unwrap();\n\n        has_many_via_before_action.extend(quote! {\n            let #field = self.#field.take();\n        });\n\n        has_many_via_action.extend(quote! {\n            model.#field = #field.empty_holder();\n            for item in #field.into_vec() {\n                if item.is_update() {\n                    // has primary key\n                    if item.is_changed() {\n                        model.#field.push(#box_pin(item.action(action, db))#await_?);\n                    } else {\n                        model.#field.push(item);\n                    }\n                } else {\n                    // new model\n                    model.#field.push(#box_pin(item.action(action, db))#await_?);\n                }\n            }\n            model.establish_links(\n                #related_entity,\n                model.#field.as_slice(),\n                model.#field.is_replace(),\n                db\n            )#await_?;\n        });\n\n        has_many_via_delete.extend(quote! {\n            deleted.merge(self.delete_links(#related_entity, db)#await_?);\n        });\n    }\n\n    for (field, via_entity, reverse) in has_many_via_self {\n        let related_entity: TokenStream = format!(\"super::{via_entity}::Entity\").parse().unwrap();\n        let establish_links = Ident::new(\n            if *reverse {\n                \"establish_links_self_rev\"\n            } else {\n                \"establish_links_self\"\n            },\n            field.span(),\n        );\n\n        has_many_via_before_action.extend(quote! {\n            let #field = self.#field.take();\n        });\n\n        has_many_via_action.extend(quote! {\n            model.#field = #field.empty_holder();\n            for item in #field.into_vec() {\n                if item.is_update() {\n                    // has primary key\n                    if item.is_changed() {\n                        model.#field.push(#box_pin(item.action(action, db))#await_?);\n                    } else {\n                        model.#field.push(item);\n                    }\n                } else {\n                    // new model\n                    model.#field.push(#box_pin(item.action(action, db))#await_?);\n                }\n            }\n            model.#establish_links(\n                #related_entity,\n                model.#field.as_slice(),\n                model.#field.is_replace(),\n                db\n            )#await_?;\n        });\n\n        has_many_via_delete.extend(quote! {\n            deleted.merge(self.delete_links_self(#related_entity, db)#await_?);\n        });\n    }\n\n    quote! {\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub #async_ fn insert<'a, C>(self, db: &'a C) -> Result<ModelEx, sea_orm::DbErr>\n        where\n            C: sea_orm::TransactionTrait,\n        {\n            let active_model = self.action(sea_orm::ActiveModelAction::Insert, db)#await_?;\n            active_model.try_into()\n        }\n\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub #async_ fn update<'a, C>(self, db: &'a C) -> Result<ModelEx, sea_orm::DbErr>\n        where\n            C: sea_orm::TransactionTrait,\n        {\n            let active_model = self.action(sea_orm::ActiveModelAction::Update, db)#await_?;\n            active_model.try_into()\n        }\n\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub #async_ fn save<'a, C>(self, db: &'a C) -> Result<Self, sea_orm::DbErr>\n        where\n            C: sea_orm::TransactionTrait,\n        {\n            self.action(sea_orm::ActiveModelAction::Save, db)#await_\n        }\n\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub #async_ fn delete<'a, C>(self, db: &'a C) -> Result<sea_orm::DeleteResult, sea_orm::DbErr>\n        where\n            C: sea_orm::TransactionTrait,\n        {\n            use sea_orm::{IntoActiveModel, TransactionSession};\n\n            let txn = db.begin()#await_?;\n            let db = &txn;\n            let mut deleted = sea_orm::DeleteResult::empty();\n\n            #has_one_delete\n            #has_many_delete\n            #has_many_via_delete\n\n            let model: ActiveModel = self.into();\n            deleted.merge(model.delete(db)#await_?);\n\n            txn.commit()#await_?;\n\n            Ok(deleted)\n        }\n\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub #async_ fn action<'a, C>(mut self, action: sea_orm::ActiveModelAction, db: &'a C) -> Result<Self, sea_orm::DbErr>\n        where\n            C: sea_orm::TransactionTrait,\n        {\n            use sea_orm::{HasOneModel, HasManyModel, IntoActiveModel, TransactionSession};\n            let txn = db.begin()#await_?;\n            let db = &txn;\n            let mut deleted = sea_orm::DeleteResult::empty();\n\n            #belongs_to_action\n            #has_one_before_action\n            #has_many_before_action\n            #has_many_via_before_action\n\n            let model: ActiveModel = self.into();\n\n            let mut model: Self = if model.is_changed() {\n                match action {\n                    sea_orm::ActiveModelAction::Insert => model.insert(db)#await_,\n                    sea_orm::ActiveModelAction::Update => model.update(db)#await_,\n                    sea_orm::ActiveModelAction::Save => if !model.is_update() {\n                        model.insert(db)#await_\n                    } else {\n                        model.update(db)#await_\n                    },\n                }?.into_ex().into()\n            } else {\n                model.into()\n            };\n\n            #belongs_to_after_action\n            #has_one_action\n            #has_many_action\n            #has_many_via_action\n\n            txn.commit()#await_?;\n\n            Ok(model)\n        }\n    }\n}\n\nfn expand_active_model_setters(data: &Data) -> syn::Result<TokenStream> {\n    let mut setters = TokenStream::new();\n\n    if let Data::Struct(item_struct) = &data {\n        if let Fields::Named(fields) = &item_struct.fields {\n            for field in &fields.named {\n                if let Some(ident) = &field.ident {\n                    let field_type = &field.ty;\n                    let field_type_str = quote! { #field_type }\n                        .to_string() // e.g.: \"Option < String >\"\n                        .replace(' ', \"\"); // Remove spaces\n\n                    let mut ignore = false;\n\n                    for attr in field.attrs.iter() {\n                        if attr.path().is_ident(\"sea_orm\") {\n                            attr.parse_nested_meta(|meta| {\n                                if meta.path.is_ident(\"ignore\") {\n                                    ignore = true;\n                                } else {\n                                    // Reads the value expression to advance the parse stream.\n                                    let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();\n                                }\n\n                                Ok(())\n                            })?;\n                        }\n                    }\n\n                    if ignore {\n                        continue;\n                    }\n\n                    if is_compound_field(&field_type_str) {\n                        let entity_path = extract_compound_entity(&field_type_str);\n                        let active_model_type: Type = syn::parse_str(&format!(\n                            \"{}ActiveModelEx\",\n                            entity_path.trim_end_matches(\"Entity\")\n                        ))?;\n\n                        if field_type_str.starts_with(\"HasOne<\") {\n                            let setter = format_ident!(\"set_{}\", ident);\n\n                            setters.extend(quote! {\n                                #[doc = \" Generated by sea-orm-macros\"]\n                                pub fn #setter(mut self, v: impl Into<#active_model_type>) -> Self {\n                                    self.#ident.replace(v.into());\n                                    self\n                                }\n                            });\n                        } else {\n                            let setter = format_ident!(\n                                \"add_{}\",\n                                pluralizer::pluralize(&ident.to_string(), 1, false)\n                            );\n\n                            setters.extend(quote! {\n                                #[doc = \" Generated by sea-orm-macros\"]\n                                pub fn #setter(mut self, v: impl Into<#active_model_type>) -> Self {\n                                    self.#ident.push(v.into());\n                                    self\n                                }\n                            });\n                        }\n                    } else {\n                        let setter = format_ident!(\"set_{}\", ident);\n\n                        setters.extend(quote! {\n                            #[doc = \" Generated by sea-orm-macros\"]\n                            pub fn #setter(mut self, v: impl Into<#field_type>) -> Self {\n                                self.#ident = sea_orm::Set(v.into());\n                                self\n                            }\n                        });\n                    }\n                }\n            }\n        }\n    }\n\n    Ok(setters)\n}\n\nfn async_await() -> (TokenStream, TokenStream) {\n    if cfg!(feature = \"async\") {\n        (quote!(async), quote!(.await))\n    } else {\n        (quote!(), quote!())\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/arrow_schema.rs",
    "content": "use proc_macro2::{Ident, TokenStream};\nuse quote::{format_ident, quote};\nuse syn::{Attribute, Data, Fields, LitInt, LitStr, Type};\n\n/// Expand the DeriveArrowSchema derive macro\npub fn expand_derive_arrow_schema(\n    _ident: Ident,\n    data: Data,\n    _attrs: Vec<Attribute>,\n) -> syn::Result<TokenStream> {\n    if !cfg!(feature = \"with-arrow\") {\n        return Ok(quote!());\n    }\n\n    let mut fields_info = Vec::new();\n\n    // Parse fields\n    if let Data::Struct(item_struct) = data {\n        if let Fields::Named(fields) = &item_struct.fields {\n            for field in &fields.named {\n                if let Some(field_ident) = &field.ident {\n                    let field_name = field_ident.to_string();\n                    let field_type = &field.ty;\n\n                    // Detect if field is Option<T> for nullability\n                    let type_string = quote! { #field_type }.to_string().replace(' ', \"\");\n                    let is_nullable = type_string.starts_with(\"Option<\");\n\n                    // Parse field attributes\n                    let mut arrow_attrs = ArrowFieldAttrs::default();\n                    let mut column_type_str: Option<String> = None;\n                    let mut column_name_override: Option<String> = None;\n                    let mut arrow_field_override: Option<String> = None;\n                    let mut skip = false;\n\n                    for attr in field.attrs.iter() {\n                        if attr.path().is_ident(\"sea_orm\") {\n                            attr.parse_nested_meta(|meta| {\n                                if meta.path.is_ident(\"arrow_skip\") {\n                                    skip = true;\n                                } else if meta.path.is_ident(\"arrow_field\") {\n                                    let lit: LitStr = meta.value()?.parse()?;\n                                    arrow_field_override = Some(lit.value());\n                                } else if meta.path.is_ident(\"column_name\") {\n                                    let lit: LitStr = meta.value()?.parse()?;\n                                    column_name_override = Some(lit.value());\n                                } else if meta.path.is_ident(\"arrow_precision\") {\n                                    let lit: LitInt = meta.value()?.parse()?;\n                                    arrow_attrs.precision = Some(lit.base10_parse()?);\n                                } else if meta.path.is_ident(\"arrow_scale\") {\n                                    let lit: LitInt = meta.value()?.parse()?;\n                                    arrow_attrs.scale = Some(lit.base10_parse()?);\n                                } else if meta.path.is_ident(\"arrow_timestamp_unit\") {\n                                    let lit: LitStr = meta.value()?.parse()?;\n                                    arrow_attrs.timestamp_unit = Some(lit.value());\n                                } else if meta.path.is_ident(\"arrow_timezone\") {\n                                    let lit: LitStr = meta.value()?.parse()?;\n                                    arrow_attrs.timezone = Some(lit.value());\n                                } else if meta.path.is_ident(\"arrow_comment\") {\n                                    let lit: LitStr = meta.value()?.parse()?;\n                                    arrow_attrs.comment = Some(lit.value());\n                                } else if meta.path.is_ident(\"arrow_byte_width\") {\n                                    let lit: LitInt = meta.value()?.parse()?;\n                                    arrow_attrs.byte_width = Some(lit.base10_parse()?);\n                                } else if meta.path.is_ident(\"column_type\") {\n                                    let lit: LitStr = meta.value()?.parse()?;\n                                    column_type_str = Some(lit.value());\n                                } else if meta.path.is_ident(\"nullable\") {\n                                    arrow_attrs.nullable_attr = true;\n                                } else {\n                                    let _ = meta.value().and_then(|v| v.parse::<syn::Expr>());\n                                }\n                                Ok(())\n                            })?;\n                        }\n                    }\n\n                    if skip {\n                        continue; // Skip this field\n                    }\n\n                    // Determine final nullability\n                    let nullable = is_nullable || arrow_attrs.nullable_attr;\n\n                    // Priority: arrow_field > column_name > Rust field name\n                    let resolved_name = arrow_field_override\n                        .or(column_name_override)\n                        .unwrap_or(field_name);\n\n                    fields_info.push(ArrowFieldInfo {\n                        name: resolved_name,\n                        field_type: field_type.clone(),\n                        column_type_str,\n                        nullable,\n                        arrow_attrs,\n                    });\n                }\n            }\n        }\n    }\n\n    // Generate arrow_schema() method\n    let field_definitions = fields_info.iter().map(generate_field_definition);\n\n    let entity_name = format_ident!(\"Entity\");\n\n    Ok(quote! {\n        #[automatically_derived]\n        impl sea_orm::ArrowSchema for #entity_name {\n            fn arrow_schema() -> sea_orm::arrow::datatypes::Schema {\n                use sea_orm::arrow::datatypes::{DataType, Field, Schema, TimeUnit};\n\n                Schema::new(vec![\n                    #(#field_definitions),*\n                ])\n            }\n        }\n    })\n}\n\n#[derive(Default)]\nstruct ArrowFieldAttrs {\n    precision: Option<u8>,\n    scale: Option<i8>,\n    timestamp_unit: Option<String>,\n    timezone: Option<String>,\n    comment: Option<String>,\n    nullable_attr: bool,\n    byte_width: Option<i32>,\n}\n\nstruct ArrowFieldInfo {\n    name: String,\n    field_type: Type,\n    column_type_str: Option<String>,\n    #[allow(dead_code)]\n    nullable: bool,\n    arrow_attrs: ArrowFieldAttrs,\n}\n\nfn generate_field_definition(info: &ArrowFieldInfo) -> TokenStream {\n    let field_name = &info.name;\n    let nullable = true; // we use ActiveModel, where fields can be NotSet.\n\n    // Generate DataType based on column_type or field type\n    let data_type = if let Some(col_type_str) = &info.column_type_str {\n        column_type_to_arrow_datatype(col_type_str, &info.arrow_attrs)\n    } else {\n        rust_type_to_arrow_datatype(&info.field_type, &info.arrow_attrs)\n    };\n\n    // Add metadata if comment is present\n    if let Some(comment) = &info.arrow_attrs.comment {\n        quote! {\n            Field::new(#field_name, #data_type, #nullable)\n                .with_metadata([(\n                    \"comment\".into(),\n                    #comment.into()\n                )].into())\n        }\n    } else {\n        quote! {\n            Field::new(#field_name, #data_type, #nullable)\n        }\n    }\n}\n\n/// Map SeaORM ColumnType string to Arrow DataType\nfn column_type_to_arrow_datatype(col_type: &str, arrow_attrs: &ArrowFieldAttrs) -> TokenStream {\n    // Parse ColumnType variants\n    if col_type.starts_with(\"Decimal(\") {\n        // Extract precision and scale from Decimal(Some((p, s)))\n        let (precision, scale) = if col_type.contains(\"Some((\") {\n            // Parse \"Decimal(Some((20, 4)))\"\n            if let Some(inner) = col_type\n                .strip_prefix(\"Decimal(Some((\")\n                .and_then(|s| s.strip_suffix(\")))\"))\n            {\n                let parts: Vec<&str> = inner.split(',').map(|s| s.trim()).collect();\n                if parts.len() == 2 {\n                    let p = parts[0].parse().unwrap_or(38);\n                    let s = parts[1].parse().unwrap_or(10);\n                    (p, s)\n                } else {\n                    (38, 10)\n                }\n            } else {\n                (38, 10)\n            }\n        } else {\n            (38, 10) // Default for Decimal(None)\n        };\n\n        // Allow arrow_precision/arrow_scale to override\n        let final_precision = arrow_attrs.precision.unwrap_or(precision);\n        let final_scale = arrow_attrs.scale.unwrap_or(scale);\n\n        if final_precision <= 18 {\n            quote! { DataType::Decimal64(#final_precision, #final_scale) }\n        } else if final_precision <= 38 {\n            quote! { DataType::Decimal128(#final_precision, #final_scale) }\n        } else {\n            quote! { DataType::Decimal256(#final_precision, #final_scale) }\n        }\n    } else if col_type.starts_with(\"Money(\") {\n        let precision = arrow_attrs.precision.unwrap_or(19);\n        let scale = arrow_attrs.scale.unwrap_or(4);\n        if precision <= 18 {\n            quote! { DataType::Decimal64(#precision, #scale) }\n        } else {\n            quote! { DataType::Decimal128(#precision, #scale) }\n        }\n    } else if col_type == \"TinyInteger\" {\n        quote! { DataType::Int8 }\n    } else if col_type == \"SmallInteger\" {\n        quote! { DataType::Int16 }\n    } else if col_type == \"Integer\" {\n        quote! { DataType::Int32 }\n    } else if col_type == \"BigInteger\" {\n        quote! { DataType::Int64 }\n    } else if col_type == \"TinyUnsigned\" {\n        quote! { DataType::UInt8 }\n    } else if col_type == \"SmallUnsigned\" {\n        quote! { DataType::UInt16 }\n    } else if col_type == \"Unsigned\" {\n        quote! { DataType::UInt32 }\n    } else if col_type == \"BigUnsigned\" {\n        quote! { DataType::UInt64 }\n    } else if col_type == \"Float\" {\n        quote! { DataType::Float32 }\n    } else if col_type == \"Double\" {\n        quote! { DataType::Float64 }\n    } else if col_type == \"Boolean\" {\n        quote! { DataType::Boolean }\n    } else if col_type == \"Text\" {\n        quote! { DataType::LargeUtf8 }\n    } else if col_type.starts_with(\"String(\") {\n        // Parse String(StringLen::N(255)) or String(StringLen::None)\n        if col_type.contains(\"None\") || col_type.contains(\"Max\") {\n            quote! { DataType::LargeUtf8 }\n        } else {\n            // Try to extract length\n            if let Some(inner) = col_type\n                .strip_prefix(\"String(StringLen::N(\")\n                .and_then(|s| s.strip_suffix(\"))\"))\n            {\n                if let Ok(n) = inner.parse::<u32>() {\n                    if n <= 32767 {\n                        return quote! { DataType::Utf8 };\n                    }\n                }\n            }\n            quote! { DataType::LargeUtf8 }\n        }\n    } else if col_type.starts_with(\"Char(\") {\n        quote! { DataType::Utf8 }\n    } else if col_type == \"Date\" {\n        quote! { DataType::Date32 }\n    } else if col_type == \"Time\" {\n        quote! { DataType::Time64(TimeUnit::Microsecond) }\n    } else if col_type == \"DateTime\" || col_type == \"Timestamp\" {\n        generate_timestamp_datatype(arrow_attrs, false)\n    } else if col_type == \"TimestampWithTimeZone\" {\n        generate_timestamp_datatype(arrow_attrs, true)\n    } else if col_type.starts_with(\"Binary(\") || col_type.starts_with(\"VarBinary(\") {\n        if let Some(bw) = arrow_attrs.byte_width {\n            quote! { DataType::FixedSizeBinary(#bw) }\n        } else {\n            quote! { DataType::Binary }\n        }\n    } else if col_type == \"Json\" || col_type == \"JsonBinary\" {\n        quote! { DataType::Utf8 }\n    } else if col_type == \"Uuid\" {\n        quote! { DataType::Binary }\n    } else if col_type.starts_with(\"Enum {\") {\n        quote! { DataType::Utf8 }\n    } else {\n        // Default fallback\n        quote! { DataType::Binary }\n    }\n}\n\n/// Map Rust type to Arrow DataType (when no column_type specified)\nfn rust_type_to_arrow_datatype(field_type: &Type, arrow_attrs: &ArrowFieldAttrs) -> TokenStream {\n    let type_string = quote! { #field_type }.to_string().replace(' ', \"\");\n\n    // Strip Option<> wrapper if present\n    let inner_type = if type_string.starts_with(\"Option<\") {\n        type_string\n            .strip_prefix(\"Option<\")\n            .and_then(|s| s.strip_suffix('>'))\n            .unwrap_or(&type_string)\n    } else {\n        &type_string\n    };\n\n    match inner_type {\n        \"i8\" => quote! { DataType::Int8 },\n        \"i16\" => quote! { DataType::Int16 },\n        \"i32\" => quote! { DataType::Int32 },\n        \"i64\" => quote! { DataType::Int64 },\n        \"u8\" => quote! { DataType::UInt8 },\n        \"u16\" => quote! { DataType::UInt16 },\n        \"u32\" => quote! { DataType::UInt32 },\n        \"u64\" => quote! { DataType::UInt64 },\n        \"f32\" => quote! { DataType::Float32 },\n        \"f64\" => quote! { DataType::Float64 },\n        \"bool\" => quote! { DataType::Boolean },\n        \"String\" => quote! { DataType::Utf8 },\n        s if s.contains(\"Decimal\") => {\n            let precision = arrow_attrs.precision.unwrap_or(38);\n            let scale = arrow_attrs.scale.unwrap_or(10);\n            if precision <= 18 {\n                quote! { DataType::Decimal64(#precision, #scale) }\n            } else if precision <= 38 {\n                quote! { DataType::Decimal128(#precision, #scale) }\n            } else {\n                quote! { DataType::Decimal256(#precision, #scale) }\n            }\n        }\n        s if (s.contains(\"DateTime\") && s.contains(\"Offset\"))\n            || (s.contains(\"DateTime\") && s.contains(\"Utc\"))\n            || (s.contains(\"DateTime\") && s.contains(\"TimeZone\"))\n            || s.contains(\"Timestamp\") =>\n        {\n            generate_timestamp_datatype(arrow_attrs, true)\n        }\n        s if s.contains(\"DateTime\") => {\n            generate_timestamp_datatype(arrow_attrs, arrow_attrs.timezone.is_some())\n        }\n        s if s.contains(\"Date\") => quote! { DataType::Date32 },\n        s if s.contains(\"Time\") => quote! { DataType::Time64(TimeUnit::Microsecond) },\n        \"Vec<u8>\" => {\n            if let Some(bw) = arrow_attrs.byte_width {\n                quote! { DataType::FixedSizeBinary(#bw) }\n            } else {\n                quote! { DataType::Binary }\n            }\n        }\n        _ => quote! { DataType::Binary }, // Safe fallback\n    }\n}\n\n/// Generate timestamp DataType with optional timezone\nfn generate_timestamp_datatype(arrow_attrs: &ArrowFieldAttrs, has_timezone: bool) -> TokenStream {\n    let unit = match arrow_attrs.timestamp_unit.as_deref() {\n        Some(\"Second\") => quote! { TimeUnit::Second },\n        Some(\"Millisecond\") => quote! { TimeUnit::Millisecond },\n        Some(\"Microsecond\") => quote! { TimeUnit::Microsecond },\n        Some(\"Nanosecond\") => quote! { TimeUnit::Nanosecond },\n        _ => quote! { TimeUnit::Microsecond }, // Default\n    };\n\n    if has_timezone {\n        let tz = arrow_attrs.timezone.as_deref().unwrap_or(\"UTC\");\n        quote! { DataType::Timestamp(#unit, Some(#tz.into())) }\n    } else if let Some(tz) = &arrow_attrs.timezone {\n        quote! { DataType::Timestamp(#unit, Some(#tz.into())) }\n    } else {\n        quote! { DataType::Timestamp(#unit, None) }\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/attributes.rs",
    "content": "pub mod derive_attr {\n    use bae::FromAttributes;\n\n    /// Attributes for Models and ActiveModels\n    #[derive(Default, FromAttributes)]\n    #[allow(dead_code)]\n    pub struct SeaOrm {\n        pub column: Option<syn::Ident>,\n        pub entity: Option<syn::Ident>,\n        pub model: Option<syn::Ident>,\n        pub model_ex: Option<syn::Ident>,\n        pub active_model: Option<syn::Ident>,\n        pub active_model_ex: Option<syn::Ident>,\n        pub primary_key: Option<syn::Ident>,\n        pub relation: Option<syn::Ident>,\n        pub schema_name: Option<syn::LitStr>,\n        pub table_name: Option<syn::LitStr>,\n        pub comment: Option<syn::LitStr>,\n        pub table_iden: Option<()>,\n        pub rename_all: Option<syn::LitStr>,\n    }\n}\n\npub mod relation_attr {\n    use bae::FromAttributes;\n\n    /// Attributes for Relation enum\n    #[derive(Default, FromAttributes)]\n    pub struct SeaOrm {\n        pub belongs_to: Option<syn::Lit>,\n        pub has_one: Option<syn::Lit>,\n        pub has_many: Option<syn::Lit>,\n        pub via_rel: Option<syn::Lit>,\n        pub on_update: Option<syn::Lit>,\n        pub on_delete: Option<syn::Lit>,\n        pub on_condition: Option<syn::Lit>,\n        pub from: Option<syn::Lit>,\n        pub to: Option<syn::Lit>,\n        pub fk_name: Option<syn::Lit>,\n        pub skip_fk: Option<()>,\n        pub condition_type: Option<syn::Lit>,\n    }\n}\n\npub mod compound_attr {\n    use bae::FromAttributes;\n\n    /// Attributes for compound model fields\n    #[derive(Default, FromAttributes)]\n    pub struct SeaOrm {\n        pub has_one: Option<()>,\n        pub has_many: Option<()>,\n        pub belongs_to: Option<()>,\n        pub self_ref: Option<()>,\n        pub skip_fk: Option<()>,\n        pub via: Option<syn::LitStr>,\n        pub via_rel: Option<syn::LitStr>,\n        pub from: Option<syn::LitStr>,\n        pub to: Option<syn::LitStr>,\n        pub relation_enum: Option<syn::LitStr>,\n        pub relation_reverse: Option<syn::LitStr>,\n        pub reverse: Option<()>,\n        pub on_update: Option<syn::LitStr>,\n        pub on_delete: Option<syn::LitStr>,\n    }\n}\n\npub mod value_type_attr {\n    use bae::FromAttributes;\n\n    /// Attributes for compound model fields\n    #[derive(Default, FromAttributes)]\n    pub struct SeaOrm {\n        pub column_type: Option<syn::LitStr>,\n        pub array_type: Option<syn::LitStr>,\n        pub value_type: Option<syn::LitStr>,\n        pub from_str: Option<syn::LitStr>,\n        pub to_str: Option<syn::LitStr>,\n        pub try_from_u64: Option<()>,\n    }\n}\n\n#[cfg(feature = \"seaography\")]\npub mod related_attr {\n    use bae::FromAttributes;\n\n    /// Attributes for RelatedEntity enum\n    #[derive(Default, FromAttributes)]\n    pub struct SeaOrm {\n        ///\n        /// Allows to modify target entity\n        ///\n        /// Required on enumeration variants\n        ///\n        /// If used on enumeration attributes\n        /// it allows to specify different\n        /// Entity ident\n        pub entity: Option<syn::Lit>,\n        ///\n        /// Allows to specify RelationDef\n        ///\n        /// Optional\n        ///\n        /// If not supplied the generated code\n        /// will utilize `impl Related` trait\n        pub def: Option<syn::Lit>,\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/case_style.rs",
    "content": "//! Copied from https://github.com/Peternator7/strum/blob/master/strum_macros/src/helpers/case_style.rs\nuse heck::{\n    ToKebabCase, ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToTitleCase, ToUpperCamelCase,\n};\nuse std::str::FromStr;\nuse syn::{\n    Ident, LitStr,\n    meta::ParseNestedMeta,\n    parse::{Parse, ParseStream},\n};\n\n#[allow(clippy::enum_variant_names)]\n#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]\npub enum CaseStyle {\n    CamelCase,\n    KebabCase,\n    MixedCase,\n    ShoutySnakeCase,\n    SnakeCase,\n    TitleCase,\n    UpperCase,\n    LowerCase,\n    ScreamingKebabCase,\n    PascalCase,\n}\n\nconst VALID_CASE_STYLES: &[&str] = &[\n    \"camelCase\",\n    \"PascalCase\",\n    \"kebab-case\",\n    \"snake_case\",\n    \"SCREAMING_SNAKE_CASE\",\n    \"SCREAMING-KEBAB-CASE\",\n    \"lowercase\",\n    \"UPPERCASE\",\n    \"title_case\",\n    \"mixed_case\",\n];\n\nimpl Parse for CaseStyle {\n    fn parse(input: ParseStream) -> syn::Result<Self> {\n        let text = input.parse::<LitStr>()?;\n        let val = text.value();\n\n        val.as_str().parse().map_err(|_| {\n            syn::Error::new_spanned(\n                &text,\n                format!(\n                    \"Unexpected case style for serialize_all: `{val}`. Valid values are: `{VALID_CASE_STYLES:?}`\",\n                ),\n            )\n        })\n    }\n}\n\nimpl FromStr for CaseStyle {\n    type Err = ();\n\n    fn from_str(text: &str) -> Result<Self, ()> {\n        Ok(match text {\n            \"camel_case\" | \"PascalCase\" => CaseStyle::PascalCase,\n            \"camelCase\" => CaseStyle::CamelCase,\n            \"snake_case\" | \"snek_case\" => CaseStyle::SnakeCase,\n            \"kebab_case\" | \"kebab-case\" => CaseStyle::KebabCase,\n            \"SCREAMING-KEBAB-CASE\" => CaseStyle::ScreamingKebabCase,\n            \"shouty_snake_case\" | \"shouty_snek_case\" | \"SCREAMING_SNAKE_CASE\" => {\n                CaseStyle::ShoutySnakeCase\n            }\n            \"title_case\" => CaseStyle::TitleCase,\n            \"mixed_case\" => CaseStyle::MixedCase,\n            \"lowercase\" => CaseStyle::LowerCase,\n            \"UPPERCASE\" => CaseStyle::UpperCase,\n            _ => return Err(()),\n        })\n    }\n}\n\npub trait CaseStyleHelpers {\n    fn convert_case(&self, case_style: Option<CaseStyle>) -> String;\n}\n\nimpl CaseStyleHelpers for Ident {\n    fn convert_case(&self, case_style: Option<CaseStyle>) -> String {\n        let ident_string = self.to_string();\n        if let Some(case_style) = case_style {\n            match case_style {\n                CaseStyle::PascalCase => ident_string.to_upper_camel_case(),\n                CaseStyle::KebabCase => ident_string.to_kebab_case(),\n                CaseStyle::MixedCase => ident_string.to_lower_camel_case(),\n                CaseStyle::ShoutySnakeCase => ident_string.to_shouty_snake_case(),\n                CaseStyle::SnakeCase => ident_string.to_snake_case(),\n                CaseStyle::TitleCase => ident_string.to_title_case(),\n                CaseStyle::UpperCase => ident_string.to_uppercase(),\n                CaseStyle::LowerCase => ident_string.to_lowercase(),\n                CaseStyle::ScreamingKebabCase => ident_string.to_kebab_case().to_uppercase(),\n                CaseStyle::CamelCase => {\n                    let camel_case = ident_string.to_upper_camel_case();\n                    let mut pascal = String::with_capacity(camel_case.len());\n                    let mut it = camel_case.chars();\n                    if let Some(ch) = it.next() {\n                        pascal.extend(ch.to_lowercase());\n                    }\n                    pascal.extend(it);\n                    pascal\n                }\n            }\n        } else {\n            ident_string\n        }\n    }\n}\n\nimpl TryFrom<&ParseNestedMeta<'_>> for CaseStyle {\n    type Error = syn::Error;\n\n    fn try_from(value: &ParseNestedMeta) -> Result<Self, Self::Error> {\n        let meta_string_literal: LitStr = value.value()?.parse()?;\n        let value_string = meta_string_literal.value();\n        match CaseStyle::from_str(value_string.as_str()) {\n            Ok(rule) => Ok(rule),\n            Err(()) => Err(value.error(format!(\n                \"Unknown value for attribute parameter: `{value_string}`. Valid values are: `{VALID_CASE_STYLES:?}`\"\n            ))),\n        }\n    }\n}\n\n#[test]\nfn test_convert_case() {\n    let id = Ident::new(\"test_me\", proc_macro2::Span::call_site());\n    assert_eq!(\"testMe\", id.convert_case(Some(CaseStyle::CamelCase)));\n    assert_eq!(\"TestMe\", id.convert_case(Some(CaseStyle::PascalCase)));\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/column.rs",
    "content": "use super::is_static_iden;\nuse heck::{ToLowerCamelCase, ToSnakeCase};\nuse proc_macro2::{Ident, TokenStream};\nuse quote::{quote, quote_spanned};\nuse syn::{Data, DataEnum, Expr, Fields, LitStr, Variant};\n\n/// Derive a Column name for an enum type\npub fn impl_iden(ident: &Ident, data: &Data) -> syn::Result<TokenStream> {\n    let variants = match data {\n        syn::Data::Enum(DataEnum { variants, .. }) => variants,\n        _ => {\n            return Ok(quote_spanned! {\n                ident.span() => compile_error!(\"you can only derive DeriveColumn on enums\");\n            });\n        }\n    };\n\n    let variant: Vec<TokenStream> = variants\n        .iter()\n        .map(|Variant { ident, fields, .. }| match fields {\n            Fields::Named(_) => quote! { #ident{..} },\n            Fields::Unnamed(_) => quote! { #ident(..) },\n            Fields::Unit => quote! { #ident },\n        })\n        .collect();\n\n    let mut all_static = true;\n    let name: Vec<TokenStream> = variants\n        .iter()\n        .map(|v| {\n            let mut column_name = v.ident.to_string().to_snake_case();\n            for attr in v.attrs.iter() {\n                if !attr.path().is_ident(\"sea_orm\") {\n                    continue;\n                }\n                attr.parse_nested_meta(|meta| {\n                    if meta.path.is_ident(\"column_name\") {\n                        column_name = meta.value()?.parse::<LitStr>()?.value();\n                    } else {\n                        // Reads the value expression to advance the parse stream.\n                        // Some parameters, such as `primary_key`, do not have any value,\n                        // so ignoring an error occurred here.\n                        let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();\n                    }\n                    Ok(())\n                })?;\n            }\n            all_static &= is_static_iden(&column_name);\n            Ok::<TokenStream, syn::Error>(quote! { #column_name })\n        })\n        .collect::<Result<_, _>>()?;\n\n    let quoted = if all_static {\n        quote! {\n            fn quoted(&self) -> std::borrow::Cow<'static, str> {\n                std::borrow::Cow::Borrowed(sea_orm::IdenStatic::as_str(self))\n            }\n        }\n    } else {\n        quote! {}\n    };\n\n    Ok(quote!(\n        #[automatically_derived]\n        impl sea_orm::IdenStatic for #ident {\n            fn as_str(&self) -> &'static str {\n                match self {\n                    #(Self::#variant => #name),*\n                }\n            }\n        }\n\n        #[automatically_derived]\n        impl sea_orm::Iden for #ident {\n            #quoted\n\n            fn unquoted(&self) -> &str {\n                sea_orm::IdenStatic::as_str(self)\n            }\n        }\n    ))\n}\n\n/// Implement a column for an enum using [DeriveColumn](sea_orm::DeriveColumn)\npub fn impl_col_from_str(ident: &Ident, data: &Data) -> syn::Result<TokenStream> {\n    let data_enum = match data {\n        Data::Enum(data_enum) => data_enum,\n        _ => {\n            return Ok(quote_spanned! {\n                ident.span() => compile_error!(\"you can only derive DeriveColumn on enums\");\n            });\n        }\n    };\n\n    let columns = data_enum\n        .variants\n        .iter()\n        .map(|column| {\n            let column_iden = column.ident.clone();\n            let column_str_snake = column_iden.to_string().to_snake_case();\n            let column_str_mixed = column_iden.to_string().to_lower_camel_case();\n\n            let mut column_name = column_str_snake.clone();\n            for attr in column.attrs.iter() {\n                if !attr.path().is_ident(\"sea_orm\") {\n                    continue;\n                }\n                attr.parse_nested_meta(|meta| {\n                    if meta.path.is_ident(\"column_name\") {\n                        column_name = meta.value()?.parse::<LitStr>()?.value();\n                    } else {\n                        // Reads the value expression to advance the parse stream.\n                        // Some parameters, such as `primary_key`, do not have any value,\n                        // so ignoring an error occurred here.\n                        let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();\n                    }\n                    Ok(())\n                })?;\n            }\n            Ok::<TokenStream, syn::Error>(quote!(\n                #column_str_snake | #column_str_mixed | #column_name => Ok(#ident::#column_iden)\n            ))\n        })\n        .collect::<Result<Vec<_>, _>>()?;\n\n    Ok(quote!(\n        #[automatically_derived]\n        impl std::str::FromStr for #ident {\n            type Err = sea_orm::ColumnFromStrErr;\n\n            fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {\n                match s {\n                    #(#columns),*,\n                    _ => Err(sea_orm::ColumnFromStrErr(s.to_owned())),\n                }\n            }\n        }\n    ))\n}\n\npub fn expand_derive_column(ident: &Ident, data: &Data) -> syn::Result<TokenStream> {\n    let impl_col_from_str = impl_col_from_str(ident, data)?;\n    let impl_iden = impl_iden(ident, data)?;\n\n    Ok(quote!(\n        #impl_col_from_str\n\n        #impl_iden\n    ))\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/derive_iden.rs",
    "content": "use heck::ToSnakeCase;\nuse proc_macro2::{self, TokenStream};\nuse quote::{quote, quote_spanned};\nuse syn::{\n    DataEnum, DataStruct, DeriveInput, Expr, Fields, LitStr, Variant, punctuated::Punctuated,\n};\n\npub(super) fn is_static_iden(name: &str) -> bool {\n    // can only begin with [a-z_]\n    name.chars()\n        .take(1)\n        .all(|c| c == '_' || c.is_ascii_alphabetic())\n        && name.chars().all(|c| c == '_' || c.is_ascii_alphanumeric())\n}\n\npub(super) fn impl_iden_for_unit_struct(\n    ident: &syn::Ident,\n    iden_str: &str,\n) -> proc_macro2::TokenStream {\n    let quoted = if is_static_iden(iden_str) {\n        quote! {\n            fn quoted(&self) -> std::borrow::Cow<'static, str> {\n                std::borrow::Cow::Borrowed(#iden_str)\n            }\n        }\n    } else {\n        quote! {}\n    };\n    quote! {\n        #[automatically_derived]\n        impl sea_orm::Iden for #ident {\n            #quoted\n\n            fn unquoted(&self) -> &str {\n                #iden_str\n            }\n        }\n    }\n}\n\nfn impl_iden_for_enum(\n    ident: &syn::Ident,\n    variants: Punctuated<Variant, syn::token::Comma>,\n) -> proc_macro2::TokenStream {\n    let variants = variants.iter();\n    let mut all_static = true;\n\n    let match_pair: Vec<TokenStream> = variants\n        .map(|v| {\n            let var_ident = &v.ident;\n            let var_name = if var_ident == \"Table\" {\n                ident\n            } else {\n                var_ident\n            };\n            let mut var_name = var_name.to_string().to_snake_case();\n            v.attrs\n                .iter()\n                .filter(|attr| attr.path().is_ident(\"sea_orm\"))\n                .try_for_each(|attr| {\n                    attr.parse_nested_meta(|meta| {\n                        if meta.path.is_ident(\"iden\") {\n                            let litstr: LitStr = meta.value()?.parse()?;\n                            var_name = litstr.value();\n                        } else {\n                            // Reads the value expression to advance the parse stream.\n                            // Some parameters do not have any value,\n                            // so ignoring an error occurred here.\n                            let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();\n                        }\n                        Ok(())\n                    })\n                })\n                .expect(\"something something\");\n            all_static &= is_static_iden(&var_name);\n            quote! { Self::#var_ident => #var_name }\n        })\n        .collect();\n\n    let match_arms: TokenStream = quote! { #(#match_pair),* };\n\n    let quoted = if all_static {\n        quote! {\n            fn quoted(&self) -> std::borrow::Cow<'static, str> {\n                std::borrow::Cow::Borrowed(match self {\n                    #match_arms\n                })\n            }\n        }\n    } else {\n        quote! {}\n    };\n\n    quote! {\n        #[automatically_derived]\n        impl sea_orm::Iden for #ident {\n            #quoted\n\n            fn unquoted(&self) -> &str {\n                match self {\n                    #match_arms\n                }\n            }\n        }\n    }\n}\n\npub fn expand_derive_iden(input: DeriveInput) -> syn::Result<TokenStream> {\n    let DeriveInput { ident, data, .. } = input;\n\n    let mut new_iden: String = ident.to_string().to_snake_case();\n    input\n        .attrs\n        .iter()\n        .filter(|attr| attr.path().is_ident(\"sea_orm\"))\n        .try_for_each(|attr| {\n            attr.parse_nested_meta(|meta| {\n                if meta.path.is_ident(\"iden\") {\n                    let litstr: LitStr = meta.value()?.parse()?;\n                    new_iden = litstr.value();\n                } else {\n                    // Reads the value expression to advance the parse stream.\n                    // Some parameters do not have any value,\n                    // so ignoring an error occurred here.\n                    let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();\n                }\n                Ok(())\n            })\n        })?;\n\n    // Currently we only support enums and unit structs\n    match data {\n        syn::Data::Enum(DataEnum { variants, .. }) => {\n            if variants.is_empty() {\n                Ok(TokenStream::new())\n            } else {\n                Ok(impl_iden_for_enum(&ident, variants))\n            }\n        }\n        syn::Data::Struct(DataStruct {\n            fields: Fields::Unit,\n            ..\n        }) => Ok(impl_iden_for_unit_struct(&ident, &new_iden)),\n        _ => Ok(quote_spanned! {\n            ident.span() => compile_error!(\"you can only derive DeriveIden on unit struct or enum\");\n        }),\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/entity.rs",
    "content": "use std::iter::FromIterator;\n\nuse proc_macro2::TokenStream;\nuse quote::{format_ident, quote};\n\nuse super::{attributes::derive_attr, impl_iden_for_unit_struct};\n\nstruct DeriveEntity {\n    column_ident: syn::Ident,\n    ident: syn::Ident,\n    model_ident: syn::Ident,\n    model_ex_ident: syn::Ident,\n    active_model_ident: syn::Ident,\n    active_model_ex_ident: syn::Ident,\n    primary_key_ident: syn::Ident,\n    relation_ident: syn::Ident,\n    schema_name: Option<syn::LitStr>,\n    table_name: Option<syn::LitStr>,\n}\n\nimpl DeriveEntity {\n    fn new(input: syn::DeriveInput) -> Result<Self, syn::Error> {\n        let sea_attr = derive_attr::SeaOrm::try_from_attributes(&input.attrs)?.unwrap_or_default();\n\n        let ident = input.ident;\n        let column_ident = sea_attr.column.unwrap_or_else(|| format_ident!(\"Column\"));\n        let model_ident = sea_attr.model.unwrap_or_else(|| format_ident!(\"Model\"));\n        let model_ex_ident = sea_attr.model_ex.unwrap_or_else(|| format_ident!(\"Model\"));\n        let active_model_ident = sea_attr\n            .active_model\n            .unwrap_or_else(|| format_ident!(\"ActiveModel\"));\n        let active_model_ex_ident = sea_attr\n            .active_model_ex\n            .unwrap_or_else(|| format_ident!(\"ActiveModel\"));\n        let primary_key_ident = sea_attr\n            .primary_key\n            .unwrap_or_else(|| format_ident!(\"PrimaryKey\"));\n        let relation_ident = sea_attr\n            .relation\n            .unwrap_or_else(|| format_ident!(\"Relation\"));\n\n        let table_name = sea_attr.table_name;\n        let schema_name = sea_attr.schema_name;\n\n        Ok(DeriveEntity {\n            column_ident,\n            ident,\n            model_ident,\n            model_ex_ident,\n            active_model_ident,\n            active_model_ex_ident,\n            primary_key_ident,\n            relation_ident,\n            schema_name,\n            table_name,\n        })\n    }\n\n    fn expand(&self) -> TokenStream {\n        let expanded_impl_entity_name = self.impl_entity_name();\n        let expanded_impl_entity_trait = self.impl_entity_trait();\n        let expanded_impl_iden = self.impl_iden();\n        let expanded_impl_iden_static = self.impl_iden_static();\n        let expanded_impl_entity_registry = self.impl_entity_registry();\n\n        TokenStream::from_iter([\n            expanded_impl_entity_name,\n            expanded_impl_entity_trait,\n            expanded_impl_iden,\n            expanded_impl_iden_static,\n            expanded_impl_entity_registry,\n        ])\n    }\n\n    fn impl_entity_name(&self) -> TokenStream {\n        let ident = &self.ident;\n        let table_name = match &self.table_name {\n            Some(table_name) => table_name,\n            None => return TokenStream::new(), // No table name, do not derive EntityName\n        };\n        let expanded_schema_name = self\n            .schema_name\n            .as_ref()\n            .map(|schema| quote!(Some(#schema)))\n            .unwrap_or_else(|| quote!(None));\n\n        quote!(\n            #[automatically_derived]\n            impl sea_orm::entity::EntityName for #ident {\n                fn schema_name(&self) -> Option<&str> {\n                    #expanded_schema_name\n                }\n\n                fn table_name(&self) -> &'static str {\n                    #table_name\n                }\n            }\n        )\n    }\n\n    fn impl_entity_trait(&self) -> TokenStream {\n        let Self {\n            ident,\n            model_ident,\n            model_ex_ident,\n            active_model_ident,\n            active_model_ex_ident,\n            column_ident,\n            primary_key_ident,\n            relation_ident,\n            ..\n        } = self;\n\n        quote!(\n            #[automatically_derived]\n            impl sea_orm::entity::EntityTrait for #ident {\n                type Model = #model_ident;\n\n                type ModelEx = #model_ex_ident;\n\n                type ActiveModel = #active_model_ident;\n\n                type ActiveModelEx = #active_model_ex_ident;\n\n                type Column = #column_ident;\n\n                type PrimaryKey = #primary_key_ident;\n\n                type Relation = #relation_ident;\n            }\n        )\n    }\n\n    fn impl_iden(&self) -> TokenStream {\n        let ident = &self.ident;\n\n        match &self.table_name {\n            Some(table_name) => impl_iden_for_unit_struct(ident, &table_name.value()),\n            None => quote!(\n                #[automatically_derived]\n                impl sea_orm::Iden for #ident {\n                    fn unquoted(&self) -> &str {\n                        <Self as sea_orm::IdenStatic>::as_str(self)\n                    }\n                }\n            ),\n        }\n    }\n\n    fn impl_iden_static(&self) -> TokenStream {\n        let ident = &self.ident;\n\n        quote!(\n            #[automatically_derived]\n            impl sea_orm::IdenStatic for #ident {\n                fn as_str(&self) -> &'static str {\n                    <Self as sea_orm::EntityName>::table_name(self)\n                }\n            }\n        )\n    }\n\n    fn impl_entity_registry(&self) -> TokenStream {\n        if cfg!(feature = \"entity-registry\") {\n            quote! {\n                sea_orm::register_entity! {\n                    sea_orm::EntityRegistry {\n                        module_path: module_path!(),\n                        schema_info: |schema| sea_orm::EntitySchemaInfo::new(Entity, schema),\n                    }\n                }\n            }\n        } else {\n            quote!()\n        }\n    }\n}\n\npub fn expand_derive_entity(input: syn::DeriveInput) -> syn::Result<TokenStream> {\n    Ok(DeriveEntity::new(input)?.expand())\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/entity_loader.rs",
    "content": "use proc_macro2::TokenStream;\nuse quote::quote;\nuse std::collections::HashMap;\nuse syn::{Ident, punctuated::Punctuated, token::Comma};\n\n#[derive(Default)]\npub struct EntityLoaderSchema {\n    pub fields: Vec<EntityLoaderField>,\n}\n\npub struct EntityLoaderField {\n    pub is_one: bool,\n    pub is_self: bool,\n    pub is_reverse: bool,\n    pub field: Ident,\n    /// super::bakery::Entity\n    pub entity: String,\n    pub relation_enum: Option<syn::LitStr>,\n    pub via: Option<syn::LitStr>,\n}\n\npub fn expand_entity_loader(schema: EntityLoaderSchema) -> TokenStream {\n    let mut field_bools: Punctuated<_, Comma> = Punctuated::new();\n    let mut field_nests: Punctuated<_, Comma> = Punctuated::new();\n    let mut one_fields: Punctuated<_, Comma> = Punctuated::new();\n    let mut with_impl = TokenStream::new();\n    let mut with_nest_impl = TokenStream::new();\n    let mut select_impl = TokenStream::new();\n    let mut assemble_one = TokenStream::new();\n    let mut load_one = TokenStream::new();\n    let mut load_many = TokenStream::new();\n    let mut load_one_nest = TokenStream::new();\n    let mut load_many_nest = TokenStream::new();\n    let mut load_one_nest_nest = TokenStream::new();\n    let mut load_many_nest_nest = TokenStream::new();\n    let mut into_with_param_impl = TokenStream::new();\n    let mut arity = 1;\n\n    let (async_, await_) = if cfg!(feature = \"async\") {\n        (quote!(async), quote!(.await))\n    } else {\n        (quote!(), quote!())\n    };\n\n    let async_trait = if cfg!(feature = \"async\") {\n        quote!(#[async_trait::async_trait])\n    } else {\n        quote!()\n    };\n\n    one_fields.push(quote!(model));\n\n    let mut total_count = HashMap::new();\n    for entity_field in schema.fields.iter() {\n        *total_count.entry(&entity_field.entity).or_insert(0) += 1;\n    }\n\n    for entity_field in schema.fields.iter() {\n        let field = &entity_field.field;\n        let is_one = entity_field.is_one;\n        let is_self = entity_field.is_self;\n        let is_reverse = entity_field.is_reverse;\n        let entity: TokenStream = entity_field.entity.parse().unwrap();\n        let entity_module: TokenStream = entity_field\n            .entity\n            .trim_end_matches(\"::Entity\")\n            .parse()\n            .unwrap();\n\n        if !is_self && *total_count.get(&entity_field.entity).unwrap() != 1 {\n            // prevent impl trait for same entity twice\n            // self_ref is allowed\n            continue;\n        }\n\n        if !is_self {\n            field_bools.push(quote! {\n                #[doc = \" Generated by sea-orm-macros\"]\n                pub #field: bool\n            });\n            field_nests.push(quote! {\n                #[doc = \" Generated by sea-orm-macros\"]\n                pub #field: #entity_module::EntityLoaderWith\n            });\n\n            with_impl.extend(quote! {\n                if target == sea_orm::compound::LoadTarget::TableRef(#entity.table_ref()) {\n                    self.#field = true;\n                }\n            });\n            with_nest_impl.extend(quote! {\n                if left == sea_orm::compound::LoadTarget::TableRef(#entity.table_ref()) {\n                    self.with.#field = true;\n                    self.nest.#field.set(right);\n                    return self;\n                }\n            });\n        } else {\n            field_bools.push(quote! {\n                #[doc = \" Generated by sea-orm-macros\"]\n                pub #field: bool\n            });\n            field_nests.push(quote! {\n                #[doc = \" Generated by sea-orm-macros\"]\n                pub #field: EntityLoaderWith\n            });\n\n            if let Some(relation_enum) = &entity_field.relation_enum {\n                with_impl.extend(quote! {\n                    if let sea_orm::compound::LoadTarget::Relation(relation_enum) = &target {\n                        if relation_enum == #relation_enum {\n                            self.#field = true;\n                        }\n                    }\n                });\n            }\n\n            if let Some(via_lit) = &entity_field.via {\n                let via = Ident::new(&via_lit.value(), via_lit.span());\n                let target_type = if !is_reverse {\n                    Ident::new(\"TableRef\", via_lit.span())\n                } else {\n                    Ident::new(\"TableRefRev\", via_lit.span())\n                };\n\n                let target_entity = if !is_reverse {\n                    quote!(super::#via::Entity)\n                } else {\n                    quote!(super::#via::EntityReverse)\n                };\n\n                with_impl.extend(quote! {\n                    if target == sea_orm::compound::LoadTarget::#target_type(super::#via::Entity.table_ref()) {\n                        self.#field = true;\n                    }\n                });\n                with_nest_impl.extend(quote! {\n                    if left == sea_orm::compound::LoadTarget::#target_type(super::#via::Entity.table_ref()) {\n                        self.with.#field = true;\n                        self.nest.#field.set(right);\n                        return self;\n                    }\n                });\n\n                into_with_param_impl.extend(quote! {\n                    impl EntityLoaderWithParam for #target_entity {\n                        fn into_with_param(self) -> (sea_orm::compound::LoadTarget, Option<sea_orm::compound::LoadTarget>) {\n                            (sea_orm::compound::LoadTarget::#target_type(super::#via::Entity.table_ref()), None)\n                        }\n                    }\n\n                    impl<S> EntityLoaderWithParam for (#target_entity, S)\n                    where\n                        S: EntityTrait,\n                        Entity: Related<S>,\n                    {\n                        fn into_with_param(self) -> (sea_orm::compound::LoadTarget, Option<sea_orm::compound::LoadTarget>) {\n                            (\n                                sea_orm::compound::LoadTarget::#target_type(super::#via::Entity.table_ref()),\n                                Some(sea_orm::compound::LoadTarget::TableRef(self.1.table_ref())),\n                            )\n                        }\n                    }\n                });\n            }\n        }\n\n        if is_one && !is_self {\n            arity += 1;\n            if arity <= 3 {\n                // do not go beyond SelectThree\n                one_fields.push(quote!(#field));\n\n                select_impl.extend(quote! {\n                    let select = if self.with.#field && self.nest.#field.is_empty() {\n                        self.with.#field = false;\n                        loaded.#field = true;\n                        select.find_also(Entity, #entity)\n                    } else {\n                        select.select_also_fake(#entity)\n                    };\n                });\n\n                assemble_one.extend(quote! {\n                    if loaded.#field {\n                        model.#field = #field.map(Into::into).map(Box::new).into();\n                    }\n                });\n            }\n\n            load_one.extend(quote! {\n                if with.#field {\n                    let #field = models.as_slice().load_one_ex(#entity, db)#await_?;\n                    let #field = #entity_module::EntityLoader::load_nest(#field, &nest.#field, db)#await_?;\n\n                    for (model, #field) in models.iter_mut().zip(#field) {\n                        model.#field = #field.map(Into::into).map(Box::new).into();\n                    }\n                }\n            });\n            load_one_nest.extend(quote! {\n                if with.#field {\n                    let #field = models.as_slice().load_one_ex(#entity, db)#await_?;\n\n                    for (model, #field) in models.iter_mut().zip(#field) {\n                        if let Some(model) = model.as_mut() {\n                            model.#field = #field.map(Into::into).map(Box::new).into();\n                        }\n                    }\n                }\n            });\n            load_one_nest_nest.extend(quote! {\n                if with.#field {\n                    let #field = models.as_slice().load_one_ex(#entity, db)#await_?;\n\n                    for (models, #field) in models.iter_mut().zip(#field) {\n                        for (model, #field) in models.iter_mut().zip(#field) {\n                            model.#field = #field.map(Into::into).map(Box::new).into();\n                        }\n                    }\n                }\n            });\n        } else if !is_one && !is_self {\n            load_many.extend(quote! {\n                if with.#field {\n                    let #field = models.as_slice().load_many_ex(#entity, db)#await_?;\n                    let #field = #entity_module::EntityLoader::load_nest_nest(#field, &nest.#field, db)#await_?;\n\n                    for (model, #field) in models.iter_mut().zip(#field) {\n                        model.#field = #field.into();\n                    }\n                }\n            });\n            load_many_nest.extend(quote! {\n                if with.#field {\n                    let #field = models.as_slice().load_many_ex(#entity, db)#await_?;\n\n                    for (model, #field) in models.iter_mut().zip(#field) {\n                        if let Some(model) = model.as_mut() {\n                            model.#field = #field.into();\n                        }\n                    }\n                }\n            });\n            load_many_nest_nest.extend(quote! {\n                if with.#field {\n                    let #field = models.as_slice().load_many_ex(#entity, db)#await_?;\n\n                    for (models, #field) in models.iter_mut().zip(#field) {\n                        for (model, #field) in models.iter_mut().zip(#field) {\n                            model.#field = #field.into();\n                        }\n                    }\n                }\n            });\n        } else if is_one && is_self {\n            if let Some(relation_enum) = &entity_field.relation_enum {\n                let relation_enum = Ident::new(&relation_enum.value(), relation_enum.span());\n                load_one.extend(quote! {\n                    if with.#field {\n                        let #field = models.as_slice().load_self_ex(#entity, Relation::#relation_enum, db)#await_?;\n\n                        for (model, #field) in models.iter_mut().zip(#field) {\n                            model.#field = #field.map(Into::into).map(Box::new).into();\n                        }\n                    }\n                });\n            }\n        } else if !is_one && is_self {\n            if let Some(relation_enum) = &entity_field.relation_enum {\n                let relation_enum = Ident::new(&relation_enum.value(), relation_enum.span());\n                load_many.extend(quote! {\n                    if with.#field {\n                        let #field = models.as_slice().load_self_many_ex(#entity, Relation::#relation_enum, db)#await_?;\n\n                        for (model, #field) in models.iter_mut().zip(#field) {\n                            model.#field = #field.into();\n                        }\n                    }\n                });\n            }\n            if let Some(via) = &entity_field.via {\n                let via = Ident::new(&via.value(), via.span());\n                load_many.extend(quote! {\n                    if with.#field {\n                        let #field = models.as_slice().load_self_via_ex(super::#via::Entity, #is_reverse, db)#await_?;\n                        let #field = EntityLoader::load_nest_nest(#field, &nest.#field, db)#await_?;\n\n                        for (model, #field) in models.iter_mut().zip(#field) {\n                            model.#field = #field.into();\n                        }\n                    }\n                });\n                load_many_nest.extend(quote! {\n                    if with.#field {\n                        let #field = models.as_slice().load_self_via_ex(super::#via::Entity, #is_reverse, db)#await_?;\n\n                        for (model, #field) in models.iter_mut().zip(#field) {\n                            if let Some(model) = model.as_mut() {\n                                model.#field = #field.into();\n                            }\n                        }\n                    }\n                });\n                load_many_nest_nest.extend(quote! {\n                    if with.#field {\n                        let #field = models.as_slice().load_self_via_ex(super::#via::Entity, #is_reverse, db)#await_?;\n\n                        for (models, #field) in models.iter_mut().zip(#field) {\n                            for (model, #field) in models.iter_mut().zip(#field) {\n                                model.#field = #field.into();\n                            }\n                        }\n                    }\n                });\n            }\n        }\n    }\n\n    quote! {\n\n    #[doc = \" Generated by sea-orm-macros\"]\n    #[derive(Clone)]\n    pub struct EntityLoader {\n        select: sea_orm::Select<Entity>,\n        with: EntityLoaderWith,\n        nest: EntityLoaderNest,\n    }\n\n    #[doc = \" Generated by sea-orm-macros\"]\n    #[derive(Debug, Default, Clone, PartialEq, Eq)]\n    pub struct EntityReverse;\n\n    impl sea_orm::compound::EntityReverse for EntityReverse {\n        type Entity = Entity;\n    }\n\n    #[doc = \" Generated by sea-orm-macros\"]\n    #[derive(Debug, Default, Clone, PartialEq, Eq)]\n    pub struct EntityLoaderWith {\n        #field_bools\n    }\n\n    #[doc = \" Generated by sea-orm-macros\"]\n    #[derive(Debug, Default, Clone, PartialEq, Eq)]\n    pub struct EntityLoaderNest {\n        #field_nests\n    }\n\n    impl Entity {\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub const REVERSE: EntityReverse = EntityReverse;\n    }\n\n    impl EntityLoaderWith {\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub fn is_empty(&self) -> bool {\n            self == &Self::default()\n        }\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub fn set(&mut self, target: sea_orm::compound::LoadTarget) {\n            #with_impl\n        }\n    }\n\n    #[doc = \" Parameters for EntityLoader\"]\n    pub trait EntityLoaderWithParam {\n        #[doc = \" Generated by sea-orm-macros\"]\n        fn into_with_param(self) -> (sea_orm::compound::LoadTarget, Option<sea_orm::compound::LoadTarget>);\n    }\n\n    #[automatically_derived]\n    impl<R> EntityLoaderWithParam for R\n    where\n        R: EntityTrait,\n        Entity: Related<R>,\n    {\n        fn into_with_param(self) -> (sea_orm::compound::LoadTarget, Option<sea_orm::compound::LoadTarget>) {\n            (sea_orm::compound::LoadTarget::TableRef(self.table_ref()), None)\n        }\n    }\n\n    #[automatically_derived]\n    impl<R, S> EntityLoaderWithParam for (R, S)\n    where\n        R: EntityTrait,\n        Entity: Related<R>,\n        S: EntityTrait,\n        R: Related<S>,\n    {\n        fn into_with_param(self) -> (sea_orm::compound::LoadTarget, Option<sea_orm::compound::LoadTarget>) {\n            (\n                sea_orm::compound::LoadTarget::TableRef(self.0.table_ref()),\n                Some(sea_orm::compound::LoadTarget::TableRef(self.1.table_ref())),\n            )\n        }\n    }\n\n    #[automatically_derived]\n    impl<R, S> EntityLoaderWithParam for sea_orm::compound::EntityLoaderWithSelf<R, S>\n    where\n        R: EntityTrait,\n        Entity: Related<R>,\n        S: EntityTrait,\n        R: RelatedSelfVia<S>,\n    {\n        fn into_with_param(self) -> (sea_orm::compound::LoadTarget, Option<sea_orm::compound::LoadTarget>) {\n            (\n                sea_orm::compound::LoadTarget::TableRef(self.0.table_ref()),\n                Some(sea_orm::compound::LoadTarget::TableRef(self.1.table_ref())),\n            )\n        }\n    }\n\n    #[automatically_derived]\n    impl<R, S, SR> EntityLoaderWithParam for sea_orm::compound::EntityLoaderWithSelfRev<R, SR>\n    where\n        R: EntityTrait,\n        Entity: Related<R>,\n        S: EntityTrait,\n        R: RelatedSelfVia<S>,\n        SR: sea_orm::compound::EntityReverse<Entity = S>,\n    {\n        fn into_with_param(self) -> (sea_orm::compound::LoadTarget, Option<sea_orm::compound::LoadTarget>) {\n            (\n                sea_orm::compound::LoadTarget::TableRef(self.0.table_ref()),\n                Some(sea_orm::compound::LoadTarget::TableRefRev(S::default().table_ref())),\n            )\n        }\n    }\n\n    #[automatically_derived]\n    impl EntityLoaderWithParam for Relation {\n        fn into_with_param(self) -> (sea_orm::compound::LoadTarget, Option<sea_orm::compound::LoadTarget>) {\n            (sea_orm::compound::LoadTarget::Relation(self.name()), None)\n        }\n    }\n\n    #into_with_param_impl\n\n    #[automatically_derived]\n    impl std::fmt::Debug for EntityLoader {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            f.debug_struct(\"EntityLoader\")\n            .field(\"select\", &match (Entity::default().schema_name(), Entity::default().table_name()) {\n                (Some(s), t) => format!(\"{s}.{t}\"),\n                (None, t) => t.to_owned(),\n            })\n            .field(\"with\", &self.with)\n            .field(\"nest\", &self.nest)\n            .finish()\n        }\n    }\n\n    #[automatically_derived]\n    impl sea_orm::QueryFilter for EntityLoader {\n        type QueryStatement = <sea_orm::Select<Entity> as sea_orm::QueryFilter>::QueryStatement;\n\n        fn query(&mut self) -> &mut Self::QueryStatement {\n            sea_orm::QueryFilter::query(&mut self.select)\n        }\n    }\n\n    #[automatically_derived]\n    impl sea_orm::QueryOrder for EntityLoader {\n        type QueryStatement = <sea_orm::Select<Entity> as sea_orm::QueryOrder>::QueryStatement;\n\n        fn query(&mut self) -> &mut Self::QueryStatement {\n            sea_orm::QueryOrder::query(&mut self.select)\n        }\n    }\n\n    #[automatically_derived]\n    #async_trait\n    impl sea_orm::compound::EntityLoaderTrait<Entity> for EntityLoader {\n        type ModelEx = ModelEx;\n\n        #async_ fn fetch<C: sea_orm::ConnectionTrait>(self, db: &C, page: u64, page_size: u64) -> Result<Vec<Self::ModelEx>, sea_orm::DbErr> {\n            self.fetch(db, page, page_size)#await_\n        }\n\n        #async_ fn num_items<C: sea_orm::ConnectionTrait>(self, db: &C, page_size: u64) -> Result<u64, sea_orm::DbErr> {\n            self.select.paginate(db, page_size).num_items()#await_\n        }\n    }\n\n    impl Entity {\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub fn load() -> EntityLoader {\n            EntityLoader {\n                select: Entity::find(),\n                with: Default::default(),\n                nest: Default::default(),\n            }\n        }\n    }\n\n    impl EntityLoader {\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub #async_ fn one<C: sea_orm::ConnectionTrait>(mut self, db: &C) -> Result<Option<ModelEx>, sea_orm::DbErr> {\n            use sea_orm::QuerySelect;\n\n            self.select = self.select.limit(1);\n            Ok(self.all(db)#await_?.into_iter().next())\n        }\n\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub #async_ fn all<C: sea_orm::ConnectionTrait>(self, db: &C) -> Result<Vec<ModelEx>, sea_orm::DbErr> {\n            self.fetch(db, 0, 0)#await_\n        }\n\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub fn with<T: EntityLoaderWithParam>(mut self, param: T) -> Self {\n            match param.into_with_param() {\n                (left, None) => self.with_1(left),\n                (left, Some(right)) => self.with_2(left, right),\n            }\n        }\n\n        fn with_1(mut self, load_target: sea_orm::compound::LoadTarget) -> Self {\n            self.with.set(load_target);\n            self\n        }\n\n        fn with_2(mut self, left: sea_orm::compound::LoadTarget, right: sea_orm::compound::LoadTarget) -> Self {\n            #with_nest_impl\n            self\n        }\n\n        #[doc = \" Generated by sea-orm-macros\"]\n        #async_ fn fetch<C: sea_orm::ConnectionTrait>(mut self, db: &C, page: u64, page_size: u64) -> Result<Vec<ModelEx>, sea_orm::DbErr> {\n            let select = self.select;\n            let mut loaded = EntityLoaderWith::default();\n\n            #select_impl\n\n            let models = if page_size != 0 {\n                select.paginate(db, page_size).fetch_page(page)#await_?\n            } else {\n                select.all(db)#await_?\n            };\n\n            let models = models.into_iter().map(|(#one_fields)| {\n                let mut model = model.into_ex();\n                #assemble_one\n                model\n            }).collect::<Vec<_>>();\n\n            let models = Self::load(models, &self.with, &self.nest, db)#await_?;\n\n            Ok(models)\n        }\n\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub #async_ fn load<C: sea_orm::ConnectionTrait>(mut models: Vec<ModelEx>, with: &EntityLoaderWith, nest: &EntityLoaderNest, db: &C) -> Result<Vec<ModelEx>, DbErr> {\n            use sea_orm::LoaderTraitEx;\n            #load_one\n            #load_many\n            Ok(models)\n        }\n\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub #async_ fn load_nest<C: sea_orm::ConnectionTrait>(mut models: Vec<Option<ModelEx>>, with: &EntityLoaderWith, db: &C) -> Result<Vec<Option<ModelEx>>, DbErr> {\n            use sea_orm::LoaderTraitEx;\n            #load_one_nest\n            #load_many_nest\n            Ok(models)\n        }\n\n        #[doc = \" Generated by sea-orm-macros\"]\n        pub #async_ fn load_nest_nest<C: sea_orm::ConnectionTrait>(mut models: Vec<Vec<ModelEx>>, with: &EntityLoaderWith, db: &C) -> Result<Vec<Vec<ModelEx>>, DbErr> {\n            use sea_orm::NestedLoaderTrait;\n            #load_one_nest_nest\n            #load_many_nest_nest\n            Ok(models)\n        }\n    }\n\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/entity_model.rs",
    "content": "use super::case_style::{CaseStyle, CaseStyleHelpers};\nuse super::util::{escape_rust_keyword, trim_starting_raw_identifier};\nuse heck::{\n    ToKebabCase, ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToTitleCase, ToUpperCamelCase,\n};\nuse proc_macro2::{Ident, Span, TokenStream};\nuse quote::quote;\nuse std::str::FromStr;\nuse syn::meta::ParseNestedMeta;\nuse syn::{\n    Attribute, Data, Fields, Lit, LitStr, punctuated::Punctuated, spanned::Spanned, token::Comma,\n};\n\nconst NOT_AUTO_INCRE_TYPE_SUFFIX: [&str; 2] = [\"String\", \"Uuid\"];\n\n#[allow(dead_code)]\nfn convert_case(s: &str, case_style: CaseStyle) -> String {\n    match case_style {\n        CaseStyle::PascalCase => s.to_upper_camel_case(),\n        CaseStyle::KebabCase => s.to_kebab_case(),\n        CaseStyle::MixedCase => s.to_lower_camel_case(),\n        CaseStyle::ShoutySnakeCase => s.to_shouty_snake_case(),\n        CaseStyle::SnakeCase => s.to_snake_case(),\n        CaseStyle::TitleCase => s.to_title_case(),\n        CaseStyle::UpperCase => s.to_uppercase(),\n        CaseStyle::LowerCase => s.to_lowercase(),\n        CaseStyle::ScreamingKebabCase => s.to_kebab_case().to_uppercase(),\n        CaseStyle::CamelCase => {\n            let camel_case = s.to_upper_camel_case();\n            let mut result = String::with_capacity(camel_case.len());\n            let mut it = camel_case.chars();\n            if let Some(ch) = it.next() {\n                result.extend(ch.to_lowercase());\n            }\n            result.extend(it);\n            result\n        }\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nfn serde_deserialize_name(\n    orig: &str,\n    serde_rename: Option<&str>,\n    serde_rename_all: Option<CaseStyle>,\n) -> String {\n    if let Some(rename) = serde_rename.as_ref() {\n        return rename.to_string();\n    }\n\n    if let Some(case_style) = serde_rename_all {\n        convert_case(orig, case_style)\n    } else {\n        orig.to_string()\n    }\n}\n\nfn consume_meta(meta: ParseNestedMeta<'_>) {\n    let _ = meta.value().and_then(|v| v.parse::<syn::Expr>());\n}\n\n/// Method to derive an Model\npub fn expand_derive_entity_model(data: &Data, attrs: &[Attribute]) -> syn::Result<TokenStream> {\n    // if #[sea_orm(table_name = \"foo\", schema_name = \"bar\")] specified, create Entity struct\n    let mut table_name = None;\n    let mut comment = quote! {None};\n    let mut schema_name = quote! { None };\n    let mut table_iden = false;\n    let mut model_ex = false;\n    let mut rename_all: Option<CaseStyle> = None;\n    let mut serde_rename_all: Option<CaseStyle> = None;\n\n    // Parse #[serde(rename_all = \"...\")] at struct level\n    attrs\n        .iter()\n        .filter(|attr| attr.path().is_ident(\"serde\"))\n        .try_for_each(|attr| {\n            attr.parse_nested_meta(|meta| {\n                if meta.path.is_ident(\"rename_all\") {\n                    if let Ok(lit) = meta.value().and_then(|v| v.parse::<LitStr>()) {\n                        // #[serde(rename_all = \"camelCase\")]\n                        serde_rename_all = CaseStyle::from_str(&lit.value()).ok();\n                    } else {\n                        // #[serde(rename_all(serialize = \"...\", deserialize = \"...\"))]\n                        meta.parse_nested_meta(|nested| {\n                            if nested.path.is_ident(\"deserialize\") {\n                                let lit: LitStr = nested.value()?.parse()?;\n                                serde_rename_all = CaseStyle::from_str(&lit.value()).ok();\n                            } else {\n                                consume_meta(nested);\n                            }\n                            Ok(())\n                        })?;\n                    }\n                } else {\n                    consume_meta(meta);\n                }\n                Ok(())\n            })\n        })?;\n\n    attrs\n        .iter()\n        .filter(|attr| attr.path().is_ident(\"sea_orm\"))\n        .try_for_each(|attr| {\n            attr.parse_nested_meta(|meta| {\n                if meta.path.is_ident(\"comment\") {\n                    let name: Lit = meta.value()?.parse()?;\n                    comment = quote! { Some(#name) };\n                } else if meta.path.is_ident(\"table_name\") {\n                    table_name = Some(meta.value()?.parse::<LitStr>()?);\n                } else if meta.path.is_ident(\"schema_name\") {\n                    let name: Lit = meta.value()?.parse()?;\n                    schema_name = quote! { Some(#name) };\n                } else if meta.path.is_ident(\"table_iden\") {\n                    table_iden = true;\n                } else if meta.path.is_ident(\"model_ex\") {\n                    model_ex = true;\n                } else if meta.path.is_ident(\"rename_all\") {\n                    rename_all = Some((&meta).try_into()?);\n                } else {\n                    consume_meta(meta);\n                }\n\n                Ok(())\n            })\n        })?;\n\n    let entity_def = table_name\n        .as_ref()\n        .map(|table_name| {\n            let entity_extra_attr = if model_ex {\n                quote!(#[sea_orm(model_ex = ModelEx, active_model_ex = ActiveModelEx)])\n            } else {\n                quote!()\n            };\n            quote! {\n                #[doc = \" Generated by sea-orm-macros\"]\n                #[derive(Copy, Clone, Default, Debug, sea_orm::prelude::DeriveEntity)]\n                #entity_extra_attr\n                pub struct Entity;\n\n                #[automatically_derived]\n                impl sea_orm::prelude::EntityName for Entity {\n                    fn schema_name(&self) -> Option<&str> {\n                        #schema_name\n                    }\n\n                    fn table_name(&self) -> &'static str {\n                        #table_name\n                    }\n\n                    fn comment(&self) -> Option<&str> {\n                        #comment\n                    }\n                }\n            }\n        })\n        .unwrap_or_default();\n\n    // generate Column enum and it's ColumnTrait impl\n    let mut columns_enum: Punctuated<_, Comma> = Punctuated::new();\n    let mut columns_trait: Punctuated<_, Comma> = Punctuated::new();\n    let mut columns_enum_type_name: Punctuated<_, Comma> = Punctuated::new();\n    let mut columns_select_as: Punctuated<_, Comma> = Punctuated::new();\n    let mut columns_save_as: Punctuated<_, Comma> = Punctuated::new();\n    let mut primary_keys: Punctuated<_, Comma> = Punctuated::new();\n    let mut primary_key_types: Punctuated<_, Comma> = Punctuated::new();\n    let mut auto_increment: Option<bool> = None;\n    #[cfg(feature = \"with-json\")]\n    let mut columns_json_keys: Punctuated<_, Comma> = Punctuated::new();\n\n    if table_iden {\n        if let Some(table_name) = &table_name {\n            let table_field_name = Ident::new(\"Table\", Span::call_site());\n            columns_enum.push(quote! {\n                #[doc = \" Generated by sea-orm-macros\"]\n                #[sea_orm(table_name=#table_name)]\n                #[strum(disabled)]\n                #table_field_name\n            });\n            columns_trait.push(\n                quote! { Self::#table_field_name => panic!(\"Table cannot be used as a column\") },\n            );\n        }\n    }\n    if let Data::Struct(item_struct) = data {\n        if let Fields::Named(fields) = &item_struct.fields {\n            for field in &fields.named {\n                if let Some(ident) = &field.ident {\n                    let original_field_name = trim_starting_raw_identifier(ident);\n                    let mut field_name =\n                        Ident::new(&original_field_name.to_upper_camel_case(), ident.span());\n\n                    let mut nullable = false;\n                    let mut default_value = None;\n                    let mut comment = None;\n                    let mut default_expr = None;\n                    let mut select_as = None;\n                    let mut save_as = None;\n                    let mut unique_key = None;\n                    let mut renamed_from = None;\n                    let mut indexed = false;\n                    let mut ignore = false;\n                    let mut unique = false;\n                    let mut sql_type = None;\n                    let mut enum_name = None;\n                    let mut is_primary_key = false;\n                    let mut is_auto_increment = false;\n                    let mut extra = None;\n                    let mut seaography_ignore = false;\n                    #[cfg(feature = \"with-json\")]\n                    let mut serde_rename: Option<String> = None;\n\n                    let mut column_name = if let Some(case_style) = rename_all {\n                        Some(field_name.convert_case(Some(case_style)))\n                    } else if original_field_name\n                        != original_field_name.to_upper_camel_case().to_snake_case()\n                    {\n                        // `to_snake_case` was used to trim prefix and tailing underscore\n                        Some(original_field_name.to_snake_case())\n                    } else {\n                        None\n                    };\n\n                    // search for #[sea_orm(primary_key, auto_increment = false, column_type = \"String(StringLen::N(255))\", default_value = \"new user\", default_expr = \"gen_random_uuid()\", column_name = \"name\", enum_name = \"Name\", nullable, indexed, unique)]\n                    for attr in field.attrs.iter() {\n                        if attr.path().is_ident(\"sea_orm\") {\n                            // single param\n                            attr.parse_nested_meta(|meta| {\n                                if meta.path.is_ident(\"column_type\") {\n                                    let lit = meta.value()?.parse()?;\n                                    if let Lit::Str(litstr) = lit {\n                                        let ty: TokenStream = syn::parse_str(&litstr.value())?;\n                                        sql_type = Some(ty);\n                                    } else {\n                                        return Err(\n                                            meta.error(format!(\"Invalid column_type {lit:?}\"))\n                                        );\n                                    }\n                                } else if meta.path.is_ident(\"auto_increment\") {\n                                    let lit = meta.value()?.parse()?;\n                                    if let Lit::Bool(litbool) = lit {\n                                        is_auto_increment = litbool.value();\n                                        auto_increment = Some(litbool.value());\n                                    } else {\n                                        return Err(\n                                            meta.error(format!(\"Invalid auto_increment = {lit:?}\"))\n                                        );\n                                    }\n                                } else if meta.path.is_ident(\"comment\") {\n                                    comment = Some(meta.value()?.parse::<Lit>()?);\n                                } else if meta.path.is_ident(\"default_value\") {\n                                    default_value = Some(meta.value()?.parse::<Lit>()?);\n                                } else if meta.path.is_ident(\"default_expr\") {\n                                    let lit = meta.value()?.parse()?;\n                                    if let Lit::Str(litstr) = lit {\n                                        let value_expr: TokenStream =\n                                            syn::parse_str(&litstr.value())?;\n                                        default_expr = Some(value_expr);\n                                    } else {\n                                        return Err(\n                                            meta.error(format!(\"Invalid column_type {lit:?}\"))\n                                        );\n                                    }\n                                } else if meta.path.is_ident(\"column_name\") {\n                                    let lit = meta.value()?.parse()?;\n                                    if let Lit::Str(litstr) = lit {\n                                        column_name = Some(litstr.value());\n                                    } else {\n                                        return Err(\n                                            meta.error(format!(\"Invalid column_name {lit:?}\"))\n                                        );\n                                    }\n                                } else if meta.path.is_ident(\"enum_name\") {\n                                    let lit = meta.value()?.parse()?;\n                                    if let Lit::Str(litstr) = lit {\n                                        let ty: Ident = syn::parse_str(&litstr.value())?;\n                                        enum_name = Some(ty);\n                                    } else {\n                                        return Err(\n                                            meta.error(format!(\"Invalid enum_name {lit:?}\"))\n                                        );\n                                    }\n                                } else if meta.path.is_ident(\"select_as\") {\n                                    let lit = meta.value()?.parse()?;\n                                    if let Lit::Str(litstr) = lit {\n                                        select_as = Some(litstr.value());\n                                    } else {\n                                        return Err(\n                                            meta.error(format!(\"Invalid select_as {lit:?}\"))\n                                        );\n                                    }\n                                } else if meta.path.is_ident(\"save_as\") {\n                                    let lit = meta.value()?.parse()?;\n                                    if let Lit::Str(litstr) = lit {\n                                        save_as = Some(litstr.value());\n                                    } else {\n                                        return Err(meta.error(format!(\"Invalid save_as {lit:?}\")));\n                                    }\n                                } else if meta.path.is_ident(\"ignore\") {\n                                    ignore = true;\n                                } else if meta.path.is_ident(\"primary_key\") {\n                                    is_primary_key = true;\n                                    primary_key_types.push(field.ty.clone());\n                                } else if meta.path.is_ident(\"nullable\") {\n                                    nullable = true;\n                                } else if meta.path.is_ident(\"indexed\") {\n                                    indexed = true;\n                                } else if meta.path.is_ident(\"unique\") {\n                                    unique = true;\n                                } else if meta.path.is_ident(\"unique_key\") {\n                                    let lit = meta.value()?.parse()?;\n                                    if let Lit::Str(litstr) = lit {\n                                        unique_key = Some(litstr.value());\n                                    } else {\n                                        return Err(\n                                            meta.error(format!(\"Invalid unique_key {lit:?}\"))\n                                        );\n                                    }\n                                } else if meta.path.is_ident(\"renamed_from\") {\n                                    let lit = meta.value()?.parse()?;\n                                    if let Lit::Str(litstr) = lit {\n                                        renamed_from = Some(litstr.value());\n                                    } else {\n                                        return Err(\n                                            meta.error(format!(\"Invalid renamed_from {lit:?}\"))\n                                        );\n                                    }\n                                } else if meta.path.is_ident(\"extra\") {\n                                    let lit = meta.value()?.parse()?;\n                                    if let Lit::Str(litstr) = lit {\n                                        extra = Some(litstr.value());\n                                    } else {\n                                        return Err(meta.error(format!(\"Invalid extra {lit:?}\")));\n                                    }\n                                } else {\n                                    consume_meta(meta);\n                                }\n\n                                Ok(())\n                            })?;\n                        } else if attr.path().is_ident(\"seaography\") {\n                            attr.parse_nested_meta(|meta| {\n                                if meta.path.is_ident(\"ignore\") {\n                                    seaography_ignore = true;\n                                }\n\n                                Ok(())\n                            })?;\n                        } else if cfg!(feature = \"with-json\") && attr.path().is_ident(\"serde\") {\n                            #[cfg(feature = \"with-json\")]\n                            attr.parse_nested_meta(|meta| {\n                                if meta.path.is_ident(\"rename\") {\n                                    if let Ok(lit) = meta.value().and_then(|v| v.parse::<LitStr>())\n                                    {\n                                        // #[serde(rename = \"xxx\")]\n                                        serde_rename = Some(lit.value());\n                                    } else {\n                                        // #[serde(rename(serialize = \"...\", deserialize = \"...\"))]\n                                        meta.parse_nested_meta(|nested| {\n                                            if nested.path.is_ident(\"deserialize\") {\n                                                let lit: LitStr = nested.value()?.parse()?;\n                                                serde_rename = Some(lit.value());\n                                            } else {\n                                                consume_meta(nested);\n                                            }\n                                            Ok(())\n                                        })?;\n                                    }\n                                } else {\n                                    consume_meta(meta);\n                                }\n                                Ok(())\n                            })?;\n                        }\n                    }\n\n                    #[cfg(feature = \"with-json\")]\n                    let json_key_name = serde_deserialize_name(\n                        &original_field_name,\n                        serde_rename.as_deref(),\n                        serde_rename_all,\n                    );\n\n                    if let Some(enum_name) = enum_name {\n                        field_name = enum_name;\n                    }\n\n                    field_name = Ident::new(&escape_rust_keyword(field_name), ident.span());\n\n                    let variant_attrs = match &column_name {\n                        Some(column_name) => quote! {\n                            #[sea_orm(column_name = #column_name)]\n                            #[doc = \" Generated by sea-orm-macros\"]\n                        },\n                        None => quote! {\n                            #[doc = \" Generated by sea-orm-macros\"]\n                        },\n                    };\n\n                    let field_type = &field.ty;\n                    let field_type = quote! { #field_type }\n                        .to_string() // e.g.: \"Option < String >\"\n                        .replace(' ', \"\"); // Remove spaces\n\n                    if ignore {\n                        continue;\n                    } else {\n                        columns_enum.push(quote! {\n                            #variant_attrs\n                            #field_name\n                        });\n                        #[cfg(feature = \"with-json\")]\n                        columns_json_keys.push(quote! {\n                            Self::#field_name => #json_key_name\n                        });\n                    }\n\n                    if is_primary_key {\n                        primary_keys.push(quote! {\n                            #variant_attrs\n                            #field_name\n                        });\n                    }\n\n                    if !is_primary_key && is_auto_increment {\n                        return Err(syn::Error::new_spanned(\n                            ident,\n                            \"auto_increment can only be used on primary_key\",\n                        ));\n                    }\n\n                    if primary_key_types.len() > 1 && is_auto_increment {\n                        return Err(syn::Error::new_spanned(\n                            ident,\n                            \"auto_increment cannot be used on composite primary_key\",\n                        ));\n                    }\n\n                    if let Some(select_as) = select_as {\n                        columns_select_as.push(quote! {\n                            Self::#field_name => sea_orm::sea_query::ExprTrait::cast_as(expr, #select_as)\n                        });\n                    }\n                    if let Some(save_as) = save_as {\n                        columns_save_as.push(quote! {\n                            Self::#field_name => sea_orm::sea_query::ExprTrait::cast_as(val, #save_as)\n                        });\n                    }\n\n                    let field_type = if field_type.starts_with(\"Option<\") {\n                        nullable = true;\n                        &field_type[\"Option<\".len()..(field_type.len() - 1)] // Extract `T` out of `Option<T>`\n                    } else {\n                        field_type.as_str()\n                    };\n                    let field_span = field.span();\n\n                    if is_primary_key && auto_increment.is_none() {\n                        for suffix in NOT_AUTO_INCRE_TYPE_SUFFIX {\n                            if field_type.ends_with(suffix) {\n                                auto_increment = Some(false);\n                                break;\n                            }\n                        }\n                    }\n\n                    let sea_query_col_type =\n                        super::value_type_match::column_type_expr(sql_type, field_type, field_span);\n\n                    let col_def =\n                        quote! { sea_orm::prelude::ColumnTypeTrait::def(#sea_query_col_type) };\n\n                    let mut match_row = quote! { Self::#field_name => #col_def };\n                    if nullable {\n                        match_row = quote! { #match_row.nullable() };\n                    }\n                    if indexed {\n                        match_row = quote! { #match_row.indexed() };\n                    }\n                    if unique {\n                        match_row = quote! { #match_row.unique() };\n                    }\n                    if seaography_ignore {\n                        match_row = quote! { #match_row.seaography_ignore() };\n                    }\n                    if unique_key.is_some() {\n                        match_row = quote! { #match_row.unique_key(#unique_key) };\n                    }\n                    if renamed_from.is_some() {\n                        match_row = quote! { #match_row.renamed_from(#renamed_from) };\n                    }\n                    if let Some(default_value) = default_value {\n                        match_row = quote! { #match_row.default_value(#default_value) };\n                    }\n                    if let Some(comment) = comment {\n                        match_row = quote! { #match_row.comment(#comment) };\n                    }\n                    if let Some(default_expr) = default_expr {\n                        match_row = quote! { #match_row.default(#default_expr) };\n                    }\n                    if let Some(extra) = extra {\n                        match_row = quote! { #match_row.extra(#extra) };\n                    }\n                    // match_row = quote! { #match_row.comment() };\n                    columns_trait.push(match_row);\n\n                    let ty: syn::Type = syn::LitStr::new(field_type, field_span)\n                        .parse()\n                        .expect(\"field type error\");\n                    let enum_type_name = quote::quote_spanned! { field_span =>\n                        <#ty as sea_orm::sea_query::ValueType>::enum_type_name()\n                    };\n                    columns_enum_type_name.push(quote! {\n                        Self::#field_name => #enum_type_name\n                    });\n                }\n            }\n        }\n    }\n\n    // Add tailing comma\n    if !columns_select_as.is_empty() {\n        columns_select_as.push_punct(Comma::default());\n    }\n    if !columns_save_as.is_empty() {\n        columns_save_as.push_punct(Comma::default());\n    }\n\n    let primary_key = {\n        let auto_increment = match auto_increment {\n            Some(value) => value && primary_keys.len() == 1,\n            None => primary_keys.len() == 1,\n        };\n        let primary_key_types = if primary_key_types.len() == 1 {\n            let first = primary_key_types.first();\n            quote! { #first }\n        } else {\n            quote! { (#primary_key_types) }\n        };\n        quote! {\n            #[doc = \" Generated by sea-orm-macros\"]\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                #primary_keys\n            }\n\n            #[automatically_derived]\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = #primary_key_types;\n\n                fn auto_increment() -> bool {\n                    #auto_increment\n                }\n            }\n        }\n    };\n\n    let impl_model_ex = if model_ex {\n        quote!()\n    } else {\n        quote! {\n            impl Model {\n                #[doc = \" Generated by sea-orm-macros\"]\n                pub fn into_ex(self) -> Self {\n                    self\n                }\n            }\n        }\n    };\n\n    let with_json_impls = {\n        #[cfg(feature = \"with-json\")]\n        quote! {\n            fn json_key(&self) -> &'static str {\n                match self {\n                    #columns_json_keys\n                }\n            }\n        }\n\n        #[cfg(not(feature = \"with-json\"))]\n        quote! {}\n    };\n\n    Ok(quote! {\n        #impl_model_ex\n\n        #[doc = \" Generated by sea-orm-macros\"]\n        #[derive(Copy, Clone, Debug, sea_orm::prelude::EnumIter, sea_orm::prelude::DeriveColumn)]\n        pub enum Column {\n            #columns_enum\n        }\n\n        #[automatically_derived]\n        impl sea_orm::prelude::ColumnTrait for Column {\n            type EntityName = Entity;\n\n            fn def(&self) -> sea_orm::prelude::ColumnDef {\n                match self {\n                    #columns_trait\n                }\n            }\n\n            fn enum_type_name(&self) -> Option<&'static str> {\n                match self {\n                    #columns_enum_type_name\n                }\n            }\n\n            fn select_as(&self, expr: sea_orm::sea_query::Expr) -> sea_orm::sea_query::SimpleExpr {\n                match self {\n                    #columns_select_as\n                    _ => sea_orm::prelude::ColumnTrait::select_enum_as(self, expr),\n                }\n            }\n\n            fn save_as(&self, val: sea_orm::sea_query::Expr) -> sea_orm::sea_query::SimpleExpr {\n                match self {\n                    #columns_save_as\n                    _ => sea_orm::prelude::ColumnTrait::save_enum_as(self, val),\n                }\n            }\n\n            #with_json_impls\n        }\n\n        #entity_def\n\n        #primary_key\n    })\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/from_query_result.rs",
    "content": "use super::util::GetMeta;\nuse proc_macro2::{Ident, TokenStream};\nuse quote::{ToTokens, format_ident, quote, quote_spanned};\nuse syn::{\n    Data, DataStruct, DeriveInput, Fields, Generics, Meta, ext::IdentExt, punctuated::Punctuated,\n    token::Comma,\n};\n\n#[derive(Debug)]\nenum Error {\n    InputNotStruct,\n}\n\npub(super) enum ItemType {\n    Flat,\n    Skip,\n    Nested,\n}\n\npub(super) struct DeriveFromQueryResult {\n    pub ident: syn::Ident,\n    pub generics: Generics,\n    pub fields: Vec<FromQueryResultItem>,\n}\n\npub(super) struct FromQueryResultItem {\n    pub typ: ItemType,\n    pub ident: Ident,\n    pub alias: Option<String>,\n}\n\n/// Initially, we try to obtain the value for each field and check if it is an ordinary DB error\n/// (which we return immediatly), or a null error.\n///\n/// ### Background\n///\n/// Null errors do not necessarily mean that the deserialization as a whole fails,\n/// since structs embedding the current one might have wrapped the current one in an `Option`.\n/// In this case, we do not want to swallow other errors, which are very likely to actually be\n/// programming errors that should be noticed (and fixed).\nstruct TryFromQueryResultCheck<'a>(bool, &'a FromQueryResultItem);\n\nimpl ToTokens for TryFromQueryResultCheck<'_> {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let FromQueryResultItem { ident, typ, alias } = self.1;\n\n        match typ {\n            ItemType::Flat => {\n                let name = alias\n                    .to_owned()\n                    .unwrap_or_else(|| ident.unraw().to_string());\n                tokens.extend(quote! {\n                    let #ident = match row.try_get_nullable(pre, #name) {\n                        Err(v @ sea_orm::TryGetError::DbErr(_)) => {\n                            return Err(v);\n                        }\n                        v => v,\n                    };\n                });\n            }\n            ItemType::Skip => {\n                tokens.extend(quote! {\n                    let #ident = std::default::Default::default();\n                });\n            }\n            ItemType::Nested => {\n                let prefix = if self.0 {\n                    let name = ident.unraw().to_string();\n                    quote! { &format!(\"{pre}{}_\", #name) }\n                } else {\n                    quote! { pre }\n                };\n                tokens.extend(quote! {\n                    let #ident = match sea_orm::FromQueryResult::from_query_result_nullable(row, #prefix) {\n                        Err(v @ sea_orm::TryGetError::DbErr(_)) => {\n                            return Err(v);\n                        }\n                        v => v,\n                    };\n                });\n            }\n        }\n    }\n}\n\nstruct TryFromQueryResultAssignment<'a>(&'a FromQueryResultItem);\n\nimpl ToTokens for TryFromQueryResultAssignment<'_> {\n    fn to_tokens(&self, tokens: &mut TokenStream) {\n        let FromQueryResultItem { ident, typ, .. } = self.0;\n\n        match typ {\n            ItemType::Flat | ItemType::Nested => {\n                tokens.extend(quote! {\n                    #ident: #ident?,\n                });\n            }\n            ItemType::Skip => {\n                tokens.extend(quote! {\n                    #ident,\n                });\n            }\n        }\n    }\n}\n\nimpl DeriveFromQueryResult {\n    fn new(\n        DeriveInput {\n            ident,\n            data,\n            generics,\n            ..\n        }: DeriveInput,\n    ) -> Result<Self, Error> {\n        let parsed_fields = match data {\n            Data::Struct(DataStruct {\n                fields: Fields::Named(named),\n                ..\n            }) => named.named,\n            _ => return Err(Error::InputNotStruct),\n        };\n\n        let mut fields = Vec::with_capacity(parsed_fields.len());\n        for parsed_field in parsed_fields {\n            let mut typ = ItemType::Flat;\n            let mut alias = None;\n            for attr in parsed_field.attrs.iter() {\n                if !attr.path().is_ident(\"sea_orm\") {\n                    continue;\n                }\n                if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)\n                {\n                    for meta in list.iter() {\n                        if meta.exists(\"skip\") {\n                            typ = ItemType::Skip;\n                        } else if meta.exists(\"nested\") {\n                            typ = ItemType::Nested;\n                        } else if let Some(alias_) = meta.get_as_kv(\"from_alias\") {\n                            alias = Some(alias_);\n                        } else {\n                            alias = meta.get_as_kv(\"alias\");\n                        }\n                    }\n                }\n            }\n            let ident = format_ident!(\"{}\", parsed_field.ident.unwrap().to_string());\n            fields.push(FromQueryResultItem { typ, ident, alias });\n        }\n\n        Ok(Self {\n            ident,\n            generics,\n            fields,\n        })\n    }\n\n    fn expand(&self) -> syn::Result<TokenStream> {\n        Ok(self.impl_from_query_result(false))\n    }\n\n    pub(super) fn impl_from_query_result(&self, prefix: bool) -> TokenStream {\n        let Self {\n            ident,\n            generics,\n            fields,\n        } = self;\n\n        let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();\n\n        let ident_try_init: Vec<_> = fields\n            .iter()\n            .map(|s| TryFromQueryResultCheck(prefix, s))\n            .collect();\n        let ident_try_assign: Vec<_> = fields.iter().map(TryFromQueryResultAssignment).collect();\n\n        quote!(\n            #[automatically_derived]\n            impl #impl_generics sea_orm::FromQueryResult for #ident #ty_generics #where_clause {\n                fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> std::result::Result<Self, sea_orm::DbErr> {\n                    Ok(Self::from_query_result_nullable(row, pre)?)\n                }\n\n                fn from_query_result_nullable(row: &sea_orm::QueryResult, pre: &str) -> std::result::Result<Self, sea_orm::TryGetError> {\n                    #(#ident_try_init)*\n\n                    Ok(Self {\n                        #(#ident_try_assign)*\n                    })\n                }\n            }\n        )\n    }\n}\n\npub fn expand_derive_from_query_result(input: DeriveInput) -> syn::Result<TokenStream> {\n    let ident_span = input.ident.span();\n\n    match DeriveFromQueryResult::new(input) {\n        Ok(partial_model) => partial_model.expand(),\n        Err(Error::InputNotStruct) => Ok(quote_spanned! {\n            ident_span => compile_error!(\"you can only derive `FromQueryResult` on named struct\");\n        }),\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/into_active_model.rs",
    "content": "use proc_macro2::TokenStream;\nuse quote::{format_ident, quote, quote_spanned};\nuse syn::{Meta, PathArguments, PathSegment, punctuated::Punctuated, token::Comma};\n\nuse super::util::GetMeta;\n\nenum Error {\n    InputNotStruct,\n    Syn(syn::Error),\n}\n\n/// Matches all potential ways to convert struct fields into ActiveModel ones\npub(super) enum IntoActiveModelField {\n    /// `IntoActiveValue::into_active_value(self.field).into()`\n    Normal(syn::Ident),\n    /// Option<T> with fallback: `Some(v) => Set(v).into(), None => Set(expr).into()`\n    WithDefault { ident: syn::Ident, expr: syn::Expr },\n}\n\nimpl IntoActiveModelField {\n    pub(super) fn ident(&self) -> &syn::Ident {\n        match self {\n            IntoActiveModelField::Normal(ident) => ident,\n            IntoActiveModelField::WithDefault { ident, .. } => ident,\n        }\n    }\n}\n\n/// Contains all the information extracted from the input struct and its attributes\n/// needed to generate the `IntoActiveModel` trait implementation.\npub(super) struct DeriveIntoActiveModel {\n    /// The identifier of the input struct\n    pub ident: syn::Ident,\n    /// Optional explicit ActiveModel type specified via `#[sea_orm(active_model = \"Type\")]`\n    pub active_model: Option<syn::Type>,\n    /// handles provided struct fields\n    pub fields: Vec<IntoActiveModelField>,\n    /// handles fields set by #[sea_orm(set(field = expr))]\n    pub set_fields: Vec<(syn::Ident, syn::Expr)>,\n    /// require all fields specified, no `..default::Default()`\n    pub exhaustive: bool,\n}\n\nimpl DeriveIntoActiveModel {\n    /// This function finds attributes relevant for this macros:\n    /// Container attributes (#[sea_orm(...)]) on the struct for:\n    ///   - active_model: explicit ActiveModel type\n    ///   - exhaustive: require all fields to be set\n    ///   - set(...): provided values for ommited fields\n    ///\n    /// Field attributes (#[sea_orm(...)]) with:\n    ///   - ignore/skip: exclude from conversion\n    ///   - default: fallback value for Option<T> fields\n    fn new(input: syn::DeriveInput) -> Result<Self, Error> {\n        let fields = match input.data {\n            syn::Data::Struct(syn::DataStruct {\n                fields: syn::Fields::Named(syn::FieldsNamed { named, .. }),\n                ..\n            }) => named,\n            _ => return Err(Error::InputNotStruct),\n        };\n\n        let mut active_model = None;\n        let mut set_fields = Vec::new();\n        let mut exhaustive = false;\n\n        for attr in input.attrs.iter() {\n            if !attr.path().is_ident(\"sea_orm\") {\n                continue;\n            }\n\n            // Parse container attributes: #[sea_orm(...)]\n            // Supports:\n            // - active_model = \"Type\": explicitly specify the ActiveModel type\n            // - exhaustive: require all ActiveModel fields to be explicitly set\n            // - set(field = expr, ...): provide default values for fields not in the input struct\n            if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated) {\n                for meta in list {\n                    // Parse active_model attribute: #[sea_orm(active_model = \"MyActiveModel\")]\n                    if let Some(s) = meta.get_as_kv(\"active_model\") {\n                        active_model = Some(syn::parse_str::<syn::Type>(&s).map_err(Error::Syn)?);\n                    }\n                    // Parse exhaustive flag: #[sea_orm(exhaustive)]\n                    // When set, prevents using Default::default() for unspecified fields\n                    if meta.exists(\"exhaustive\") {\n                        exhaustive = true;\n                    }\n                    // Parse set attribute: #[sea_orm(set(field1 = expr1, field2 = expr2, ...))]\n                    // Collects field assignments to be included in the generated ActiveModel\n                    if let Meta::List(meta_list) = &meta {\n                        if meta_list.path.is_ident(\"set\") {\n                            let nested = meta_list\n                                .parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)\n                                .map_err(Error::Syn)?;\n                            for nested_meta in nested {\n                                if let Some(val) = nested_meta.get_as_kv_with_ident() {\n                                    let (ident, expr_str) = val;\n                                    let expr = syn::parse_str::<syn::Expr>(&expr_str)\n                                        .map_err(Error::Syn)?;\n                                    set_fields.push((ident, expr));\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // Field attributes\n        let mut field_idents: Vec<IntoActiveModelField> = Vec::new();\n        for field in fields.iter() {\n            if let Some(f) = parse_field(field)? {\n                field_idents.push(f);\n            }\n        }\n\n        Ok(Self {\n            ident: input.ident,\n            active_model,\n            fields: field_idents,\n            set_fields,\n            exhaustive,\n        })\n    }\n\n    fn expand(&self) -> syn::Result<TokenStream> {\n        let expanded_impl_into_active_model = self.impl_into_active_model();\n\n        Ok(expanded_impl_into_active_model)\n    }\n\n    /// Generates the implementation of `IntoActiveModel` trait for the input struct\n    pub(super) fn impl_into_active_model(&self) -> TokenStream {\n        let Self {\n            ident,\n            active_model,\n            fields,\n            set_fields,\n            exhaustive,\n        } = self;\n\n        let mut active_model_ident = active_model\n            .clone()\n            .unwrap_or_else(|| syn::parse_str::<syn::Type>(\"ActiveModel\").unwrap());\n\n        // Create a type alias for qualified types\n        let type_alias_definition = if is_qualified_type(&active_model_ident) {\n            let type_alias = format_ident!(\"ActiveModelFor{ident}\");\n            let type_def = quote!( type #type_alias = #active_model_ident; );\n            active_model_ident = syn::Type::Path(syn::TypePath {\n                qself: None,\n                path: syn::Path {\n                    leading_colon: None,\n                    segments: [PathSegment {\n                        ident: type_alias,\n                        arguments: PathArguments::None,\n                    }]\n                    .into_iter()\n                    .collect(),\n                },\n            });\n            type_def\n        } else {\n            quote!()\n        };\n\n        let field_idents: Vec<_> = fields.iter().map(|f| f.ident()).collect();\n\n        // Generate field conversion code based on field type\n        let expanded_fields = fields.iter().map(|field| match field {\n            IntoActiveModelField::Normal(ident) => quote!(\n                sea_orm::IntoActiveValue::<_>::into_active_value(self.#ident).into()\n            ),\n            IntoActiveModelField::WithDefault { ident, expr } => quote!({\n                match self.#ident.into() {\n                    Some(v) => sea_orm::ActiveValue::Set(v).into(),\n                    None => sea_orm::ActiveValue::Set(#expr).into(),\n                }\n            }),\n        });\n\n        // Add custom field assignments from #[sea_orm(set(field = expr))]\n        let (set_idents, set_exprs): (Vec<_>, Vec<_>) = set_fields.iter().cloned().unzip();\n        let expanded_sets = set_exprs.iter().map(|expr| {\n            quote!(\n                sea_orm::ActiveValue::Set(#expr)\n            )\n        });\n\n        // Add defaults(Unset) unless exhaustive mode is enabled\n        let rest = if *exhaustive {\n            quote!()\n        } else {\n            quote!(..::std::default::Default::default())\n        };\n\n        quote!(\n            #type_alias_definition\n\n            #[automatically_derived]\n            impl sea_orm::IntoActiveModel<#active_model_ident> for #ident {\n                fn into_active_model(self) -> #active_model_ident {\n                    #active_model_ident {\n                        #( #field_idents: #expanded_fields, )*\n                        #( #set_idents: #expanded_sets, )*\n                        #rest\n                    }\n                }\n            }\n        )\n    }\n}\n\n/// Parse field-level attributes on each struct field\n/// Supports:\n/// - ignore or skip: exclude the field from conversion\n/// - default = \"expr\": provide a fallback value for Option<T> fields (Some(v) => Set(v), None => Set(expr))\nfn parse_field(field: &syn::Field) -> Result<Option<IntoActiveModelField>, Error> {\n    let ident = field.ident.as_ref().unwrap().clone();\n    // Default expression for this field\n    let mut default_expr: Option<syn::Expr> = None;\n\n    for attr in field.attrs.iter() {\n        if !attr.path().is_ident(\"sea_orm\") {\n            continue;\n        }\n\n        // Parse the attribute arguments: #[sea_orm(...)]\n        if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated) {\n            for meta in list.iter() {\n                // Check for ignore/skip: #[sea_orm(ignore)] or #[sea_orm(skip)]\n                if meta.exists(\"ignore\") || meta.exists(\"skip\") {\n                    return Ok(None);\n                }\n                // Check for bare default: #[sea_orm(default)]\n                if meta.exists(\"default\") {\n                    if default_expr.is_some() {\n                        return Err(Error::Syn(syn::Error::new_spanned(\n                            meta,\n                            \"duplicate `default` attribute\",\n                        )));\n                    }\n                    let expr: syn::Expr = syn::parse_quote!(::core::default::Default::default());\n                    default_expr = Some(expr);\n                    continue; // Skip next default check\n                }\n                // Check for default value: #[sea_orm(default = \"expr\")]\n                if let Some(expr_str) = meta.get_as_kv(\"default\") {\n                    // Error on duplicate `default`\n                    if default_expr.is_some() {\n                        return Err(Error::Syn(syn::Error::new_spanned(\n                            meta,\n                            \"duplicate `default` attribute\",\n                        )));\n                    }\n                    // Parse the expression string into a syn::Expr\n                    let expr = syn::parse_str::<syn::Expr>(&expr_str).map_err(Error::Syn)?;\n                    default_expr = Some(expr);\n                }\n            }\n        }\n    }\n\n    // Finnaly match and return appropriate field type\n    if let Some(expr) = default_expr {\n        Ok(Some(IntoActiveModelField::WithDefault { ident, expr }))\n    } else {\n        Ok(Some(IntoActiveModelField::Normal(ident)))\n    }\n}\n\n/// Method to derive the ActiveModel from the [ActiveModelTrait](sea_orm::ActiveModelTrait)\npub fn expand_into_active_model(input: syn::DeriveInput) -> syn::Result<TokenStream> {\n    let ident_span = input.ident.span();\n\n    match DeriveIntoActiveModel::new(input) {\n        Ok(model) => model.expand(),\n        Err(Error::InputNotStruct) => Ok(quote_spanned! {\n            ident_span => compile_error!(\"you can only derive IntoActiveModel on structs\");\n        }),\n        Err(Error::Syn(err)) => Err(err),\n    }\n}\n\nfn is_qualified_type(ty: &syn::Type) -> bool {\n    matches!(ty, syn::Type::Path(syn::TypePath { qself: Some(_), .. }))\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/migration.rs",
    "content": "use proc_macro2::TokenStream;\nuse quote::quote;\n\nstruct DeriveMigrationName {\n    ident: syn::Ident,\n}\n\nimpl DeriveMigrationName {\n    fn new(input: syn::DeriveInput) -> Self {\n        let ident = input.ident;\n\n        DeriveMigrationName { ident }\n    }\n\n    fn expand(&self) -> TokenStream {\n        let ident = &self.ident;\n\n        quote!(\n            #[automatically_derived]\n            impl sea_orm_migration::MigrationName for #ident {\n                fn name(&self) -> &str {\n                    sea_orm_migration::util::get_file_stem(file!())\n                }\n            }\n        )\n    }\n}\n\n/// Method to derive a MigrationName\npub fn expand_derive_migration_name(input: syn::DeriveInput) -> syn::Result<TokenStream> {\n    Ok(DeriveMigrationName::new(input).expand())\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/mod.rs",
    "content": "mod active_enum;\nmod active_enum_display;\nmod active_model;\nmod active_model_behavior;\nmod active_model_ex;\nmod arrow_schema;\nmod attributes;\nmod case_style;\nmod column;\nmod derive_iden;\nmod entity;\nmod entity_loader;\nmod entity_model;\nmod from_query_result;\nmod into_active_model;\nmod migration;\nmod model;\nmod model_ex;\nmod partial_model;\nmod primary_key;\nmod related_entity;\nmod relation;\nmod try_getable_from_json;\nmod typed_column;\nmod util;\nmod value_type;\nmod value_type_match;\n\npub use active_enum::*;\npub use active_enum_display::*;\npub use active_model::*;\npub use active_model_behavior::*;\npub use active_model_ex::*;\npub use arrow_schema::*;\npub use column::*;\npub use derive_iden::*;\npub use entity::*;\npub use entity_model::*;\npub use from_query_result::*;\npub use into_active_model::*;\npub use migration::*;\npub use model::*;\npub use model_ex::*;\npub use partial_model::*;\npub use primary_key::*;\npub use related_entity::*;\npub use relation::*;\npub use try_getable_from_json::*;\npub use typed_column::*;\npub use value_type::*;\n"
  },
  {
    "path": "sea-orm-macros/src/derives/model.rs",
    "content": "use super::{\n    attributes::derive_attr,\n    util::{escape_rust_keyword, field_not_ignored, trim_starting_raw_identifier},\n};\nuse heck::ToUpperCamelCase;\nuse itertools::izip;\nuse proc_macro2::TokenStream;\nuse quote::{format_ident, quote};\nuse std::iter::FromIterator;\nuse syn::{Attribute, Data, Expr, Ident, LitStr};\n\npub(crate) struct DeriveModel {\n    column_idents: Vec<Ident>,\n    entity_ident: Ident,\n    field_idents: Vec<Ident>,\n    field_types: Vec<syn::Type>,\n    ident: Ident,\n    ignore_attrs: Vec<bool>,\n}\n\nimpl DeriveModel {\n    pub fn new(ident: &Ident, data: &Data, attrs: &[Attribute]) -> syn::Result<Self> {\n        let fields = match data {\n            syn::Data::Struct(syn::DataStruct {\n                fields: syn::Fields::Named(syn::FieldsNamed { named, .. }),\n                ..\n            }) => named,\n            _ => {\n                return Err(syn::Error::new_spanned(\n                    ident,\n                    \"You can only derive DeriveModel on structs\",\n                ));\n            }\n        };\n\n        let sea_attr = derive_attr::SeaOrm::try_from_attributes(attrs)?.unwrap_or_default();\n\n        let entity_ident = sea_attr.entity.unwrap_or_else(|| format_ident!(\"Entity\"));\n\n        let field_idents = fields\n            .iter()\n            .map(|field| field.ident.as_ref().unwrap().clone())\n            .collect();\n\n        let field_types = fields.iter().map(|field| field.ty.clone()).collect();\n\n        let column_idents = fields\n            .iter()\n            .map(|field| {\n                let ident = field.ident.as_ref().unwrap().to_string();\n                let ident = trim_starting_raw_identifier(ident).to_upper_camel_case();\n                let ident = escape_rust_keyword(ident);\n                let mut ident = format_ident!(\"{}\", &ident);\n                field\n                    .attrs\n                    .iter()\n                    .filter(|attr| attr.path().is_ident(\"sea_orm\"))\n                    .try_for_each(|attr| {\n                        attr.parse_nested_meta(|meta| {\n                            if meta.path.is_ident(\"enum_name\") {\n                                ident = syn::parse_str(&meta.value()?.parse::<LitStr>()?.value())\n                                    .unwrap();\n                            } else {\n                                // Reads the value expression to advance the parse stream.\n                                // Some parameters, such as `primary_key`, do not have any value,\n                                // so ignoring an error occurred here.\n                                let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();\n                            }\n\n                            Ok(())\n                        })\n                    })?;\n\n                Ok(ident)\n            })\n            .collect::<Result<_, syn::Error>>()?;\n\n        let ignore_attrs = fields\n            .iter()\n            .map(|field| !field_not_ignored(field))\n            .collect();\n\n        Ok(DeriveModel {\n            column_idents,\n            entity_ident,\n            field_idents,\n            field_types,\n            ident: ident.clone(),\n            ignore_attrs,\n        })\n    }\n\n    fn expand(&self) -> syn::Result<TokenStream> {\n        let expanded_impl_from_query_result = self.impl_from_query_result();\n        let expanded_impl_model_trait = self.impl_model_trait();\n\n        Ok(TokenStream::from_iter([\n            expanded_impl_from_query_result,\n            expanded_impl_model_trait,\n        ]))\n    }\n\n    fn impl_from_query_result(&self) -> TokenStream {\n        let ident = &self.ident;\n        let field_idents = &self.field_idents;\n        let column_idents = &self.column_idents;\n        let field_types = &self.field_types;\n        let ignore_attrs = &self.ignore_attrs;\n\n        let (field_readers, field_values): (Vec<TokenStream>, Vec<TokenStream>) = izip!(\n            field_idents.iter(),\n            column_idents,\n            field_types,\n            ignore_attrs,\n        )\n        .map(|(field_ident, column_ident, field_type, &ignore)| {\n            if ignore {\n                let reader = quote! {\n                    let #field_ident: Option<()> = None;\n                };\n                let unwrapper = quote! {\n                    #field_ident: Default::default()\n                };\n                (reader, unwrapper)\n            } else {\n                let reader = quote! {\n                    let #field_ident =\n                        row.try_get_nullable::<Option<#field_type>>(\n                            pre,\n                            sea_orm::IdenStatic::as_str(\n                                &<<Self as sea_orm::ModelTrait>::Entity\n                                    as sea_orm::entity::EntityTrait>::Column::#column_ident\n                            ).into()\n                        )?;\n                };\n                let unwrapper = quote! {\n                    #field_ident: #field_ident.ok_or_else(|| sea_orm::DbErr::Type(\n                        format!(\n                            \"Missing value for column '{}'\",\n                            sea_orm::IdenStatic::as_str(\n                                &<<Self as sea_orm::ModelTrait>::Entity\n                                    as sea_orm::entity::EntityTrait>::Column::#column_ident\n                            )\n                        )\n                    ))?\n                };\n                (reader, unwrapper)\n            }\n        })\n        .unzip();\n\n        // When a nested model is loaded via LEFT JOIN, all its fields may be NULL.\n        // In that case we interpret it as \"no nested row\" (i.e., Option::None).\n        // This check detects that condition by testing if all non-ignored fields are NULL.\n        let all_null_check = {\n            let checks: Vec<_> = izip!(field_idents, ignore_attrs)\n                .filter_map(|(field_ident, &ignore)| {\n                    if ignore {\n                        None\n                    } else {\n                        Some(quote! { #field_ident.is_none() })\n                    }\n                })\n                .collect();\n\n            quote! { true #( && #checks )* }\n        };\n\n        quote!(\n            #[automatically_derived]\n            impl sea_orm::FromQueryResult for #ident {\n                fn from_query_result(row: &sea_orm::QueryResult, pre: &str) -> std::result::Result<Self, sea_orm::DbErr> {\n                    Self::from_query_result_nullable(row, pre).map_err(Into::into)\n                }\n\n                fn from_query_result_nullable(row: &sea_orm::QueryResult, pre: &str) -> std::result::Result<Self, sea_orm::TryGetError> {\n                    #(#field_readers)*\n\n                    if #all_null_check {\n                        return Err(sea_orm::TryGetError::Null(\"All fields of nested model are null\".into()));\n                    }\n\n                    Ok(Self {\n                        #(#field_values),*\n                    })\n                }\n            }\n        )\n    }\n\n    pub fn impl_model_trait<'a>(&'a self) -> TokenStream {\n        let ident = &self.ident;\n        let entity_ident = &self.entity_ident;\n        let ignore_attrs = &self.ignore_attrs;\n        let ignore = |(ident, ignore): (&'a Ident, &bool)| -> Option<&'a Ident> {\n            if *ignore { None } else { Some(ident) }\n        };\n        let field_idents: Vec<&Ident> = self\n            .field_idents\n            .iter()\n            .zip(ignore_attrs)\n            .filter_map(ignore)\n            .collect();\n        let column_idents: Vec<&Ident> = self\n            .column_idents\n            .iter()\n            .zip(ignore_attrs)\n            .filter_map(ignore)\n            .collect();\n        let get_field_type: Vec<TokenStream> = self\n            .field_types\n            .iter()\n            .zip(ignore_attrs)\n            .filter_map(|(ty, ignore)| {\n                if *ignore {\n                    None\n                } else {\n                    Some(quote!(<#ty as sea_orm::sea_query::ValueType>::array_type()))\n                }\n            })\n            .collect();\n\n        let missing_field_msg = format!(\"field does not exist on {ident}\");\n\n        quote!(\n            #[automatically_derived]\n            impl sea_orm::ModelTrait for #ident {\n                type Entity = #entity_ident;\n\n                fn get(&self, c: <Self::Entity as sea_orm::entity::EntityTrait>::Column) -> sea_orm::Value {\n                    match c {\n                        #(<Self::Entity as sea_orm::entity::EntityTrait>::Column::#column_idents => self.#field_idents.clone().into(),)*\n                    }\n                }\n\n                fn get_value_type(c: <Self::Entity as EntityTrait>::Column) -> sea_orm::sea_query::ArrayType {\n                    match c {\n                        #(<Self::Entity as sea_orm::entity::EntityTrait>::Column::#column_idents => #get_field_type,)*\n                    }\n                }\n\n                fn try_set(&mut self, c: <Self::Entity as sea_orm::EntityTrait>::Column, v: sea_orm::Value) -> Result<(), sea_orm::DbErr> {\n                    match c {\n                        #(<Self::Entity as sea_orm::EntityTrait>::Column::#column_idents => self.#field_idents = sea_orm::sea_query::ValueType::try_from(v).map_err(|e| sea_orm::DbErr::Type(e.to_string()))?,)*\n                        _ => return Err(sea_orm::DbErr::Type(#missing_field_msg.to_owned())),\n                    }\n                    Ok(())\n                }\n            }\n        )\n    }\n}\n\npub fn expand_derive_model(\n    ident: &Ident,\n    data: &Data,\n    attrs: &[Attribute],\n) -> syn::Result<TokenStream> {\n    DeriveModel::new(ident, data, attrs)?.expand()\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/model_ex.rs",
    "content": "use super::attributes::compound_attr;\nuse super::entity_loader::{EntityLoaderField, EntityLoaderSchema, expand_entity_loader};\nuse super::util::{extract_compound_entity, format_field_ident, is_compound_field};\nuse super::{expand_typed_column, model::DeriveModel};\nuse heck::ToUpperCamelCase;\nuse proc_macro2::{Ident, Span, TokenStream};\nuse quote::{format_ident, quote};\nuse std::collections::{BTreeMap, HashMap};\nuse syn::{\n    Attribute, Data, Expr, Fields, ItemStruct, Lit, Meta, Type, parse_quote,\n    punctuated::Punctuated, token::Comma,\n};\n\npub fn expand_sea_orm_model(input: ItemStruct, compact: bool) -> syn::Result<TokenStream> {\n    let model = input.ident;\n    let vis = input.vis;\n    let mut all_fields = input.fields;\n\n    let mut model_attrs: Vec<Attribute> = Vec::new();\n    let mut model_ex_attrs: Vec<Attribute> = Vec::new();\n    let mut has_arrow_schema = false;\n\n    for attr in input.attrs {\n        if !attr.path().is_ident(\"sea_orm\") {\n            model_attrs.push(attr.clone());\n            model_ex_attrs.push(attr);\n            continue;\n        }\n\n        let mut other_attrs = Punctuated::<Meta, Comma>::new();\n\n        attr.parse_nested_meta(|meta| {\n            let is_model = meta.path.is_ident(\"model_attrs\");\n            let is_model_ex = meta.path.is_ident(\"model_ex_attrs\");\n\n            if is_model || is_model_ex {\n                let content;\n                syn::parenthesized!(content in meta.input);\n                use syn::parse::Parse;\n                let nested_metas = content.parse_terminated(Meta::parse, Comma)?;\n                for m in nested_metas {\n                    let new_attr: Attribute = parse_quote!( #[#m] );\n                    if is_model {\n                        model_attrs.push(new_attr);\n                    } else {\n                        model_ex_attrs.push(new_attr);\n                    }\n                }\n            } else if meta.path.is_ident(\"arrow_schema\") {\n                has_arrow_schema = true;\n            } else {\n                let path = &meta.path;\n                if meta.input.peek(syn::Token![=]) {\n                    let value: Expr = meta.value()?.parse()?;\n                    other_attrs.push(parse_quote!( #path = #value ));\n                } else if meta.input.is_empty() || meta.input.peek(Comma) {\n                    other_attrs.push(parse_quote!( #path ));\n                } else {\n                    let content;\n                    syn::parenthesized!(content in meta.input);\n                    let tokens: TokenStream = content.parse()?;\n                    other_attrs.push(parse_quote!( #path(#tokens) ));\n                }\n            }\n            Ok(())\n        })?;\n\n        if !other_attrs.is_empty() {\n            let attr: Attribute = parse_quote!( #[sea_orm(#other_attrs)] );\n            model_attrs.push(attr.clone());\n            model_ex_attrs.push(attr);\n        }\n    }\n\n    if has_arrow_schema {\n        model_attrs.push(parse_quote!(#[derive(DeriveArrowSchema)]));\n    }\n\n    let model_ex = Ident::new(&format!(\"{model}Ex\"), model.span());\n    for attr in &mut model_ex_attrs {\n        if attr.path().is_ident(\"derive\") {\n            if let Meta::List(list) = &mut attr.meta {\n                let mut new_list: Punctuated<_, Comma> = Punctuated::new();\n\n                list.parse_nested_meta(|meta| {\n                    if meta.path.is_ident(\"Eq\") {\n                        // skip\n                    } else if meta.path.is_ident(\"DeriveEntityModel\") {\n                        // replace macro\n                        new_list.push(parse_quote!(DeriveModelEx));\n                        new_list.push(parse_quote!(DeriveActiveModelEx));\n                    } else {\n                        new_list.push(meta.path);\n                    }\n\n                    Ok(())\n                })?;\n\n                *attr = parse_quote!(#[derive( #new_list )]);\n            }\n        }\n    }\n\n    let compact_model = if compact {\n        quote!(#[sea_orm(compact_model)])\n    } else {\n        quote!()\n    };\n\n    let mut model_fields = Vec::new();\n\n    for field in all_fields.iter_mut() {\n        let field_type = &field.ty;\n        let field_type = quote! { #field_type }\n            .to_string() // e.g.: \"Option < String >\"\n            .replace(' ', \"\"); // Remove spaces\n\n        if is_compound_field(&field_type) {\n            let entity_path = extract_compound_entity(&field_type);\n            if field_type.starts_with(\"Option<\") || field_type.starts_with(\"HasOne<\") {\n                field.ty = syn::parse_str(&format!(\"HasOne < {entity_path} >\"))?;\n            } else {\n                field.ty = syn::parse_str(&format!(\"HasMany < {entity_path} >\"))?;\n            }\n        } else {\n            model_fields.push(field);\n        }\n    }\n\n    Ok(quote! {\n        #(#model_attrs)*\n        #[sea_orm(model_ex)]\n        #vis struct #model {\n            #(#model_fields),*\n        }\n\n        #(#model_ex_attrs)*\n        #compact_model\n        #vis struct #model_ex #all_fields\n    })\n}\n\npub fn expand_derive_model_ex(\n    ident: Ident,\n    data: Data,\n    attrs: Vec<Attribute>,\n) -> syn::Result<TokenStream> {\n    let mut compact = false;\n    let mut model_fields: Vec<Ident> = Vec::new();\n    let mut compound_fields: Vec<Ident> = Vec::new();\n    let mut impl_related = Vec::new();\n    let mut entity_loader_schema = EntityLoaderSchema::default();\n    let mut unique_keys = BTreeMap::new();\n\n    attrs\n        .iter()\n        .filter(|attr| attr.path().is_ident(\"sea_orm\"))\n        .try_for_each(|attr| {\n            attr.parse_nested_meta(|meta| {\n                if meta.path.is_ident(\"compact_model\") {\n                    compact = true;\n                } else {\n                    // Reads the value expression to advance the parse stream.\n                    let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();\n                }\n                Ok(())\n            })\n        })?;\n\n    if let Data::Struct(item_struct) = &data {\n        if let Fields::Named(fields) = &item_struct.fields {\n            for field in &fields.named {\n                if let Some(ident) = &field.ident {\n                    let field_type = &field.ty;\n                    let field_type = quote! { #field_type }\n                        .to_string() // e.g.: \"Option < String >\"\n                        .replace(' ', \"\"); // Remove spaces\n\n                    if is_compound_field(&field_type) {\n                        let compound_attrs =\n                            compound_attr::SeaOrm::from_attributes(&field.attrs).ok();\n                        let is_reverse = compound_attrs\n                            .as_ref()\n                            .map(|r| r.reverse.is_some())\n                            .unwrap_or_default();\n                        let relation_enum = compound_attrs\n                            .as_ref()\n                            .and_then(|r| r.relation_enum.clone());\n                        if field_type.starts_with(\"HasOne<\") {\n                            entity_loader_schema.fields.push(EntityLoaderField {\n                                is_one: true,\n                                is_self: field_type == \"HasOne<Entity>\",\n                                is_reverse,\n                                field: ident.clone(),\n                                entity: extract_compound_entity(&field_type).to_owned(),\n                                relation_enum,\n                                via: None,\n                            });\n                        } else if field_type.starts_with(\"HasMany<\") {\n                            entity_loader_schema.fields.push(EntityLoaderField {\n                                is_one: false,\n                                is_self: field_type == \"HasMany<Entity>\",\n                                is_reverse,\n                                field: ident.clone(),\n                                entity: extract_compound_entity(&field_type).to_owned(),\n                                relation_enum,\n                                via: compound_attrs.as_ref().and_then(|r| r.via.clone()),\n                            });\n                        }\n                        if let Some(attrs) = compound_attrs {\n                            if compact\n                                && (attrs.has_one.is_some()\n                                    || attrs.has_many.is_some()\n                                    || attrs.belongs_to.is_some())\n                            {\n                                return Err(syn::Error::new_spanned(\n                                    ident,\n                                    \"You cannot use #[has_one / has_many / belongs_to] on #[sea_orm::compact_model], please use #[sea_orm::model] instead.\",\n                                ));\n                            } else if attrs.belongs_to.is_some()\n                                && !field_type.starts_with(\"HasOne<\")\n                            {\n                                return Err(syn::Error::new_spanned(\n                                    ident,\n                                    \"belongs_to must be paired with HasOne\",\n                                ));\n                            } else if attrs.has_one.is_some() && !field_type.starts_with(\"HasOne<\")\n                            {\n                                return Err(syn::Error::new_spanned(\n                                    ident,\n                                    \"has_one must be paired with HasOne\",\n                                ));\n                            } else if attrs.has_many.is_some()\n                                && !field_type.starts_with(\"HasMany<\")\n                            {\n                                return Err(syn::Error::new_spanned(\n                                    ident,\n                                    \"has_many must be paired with HasMany\",\n                                ));\n                            }\n                            impl_related.push((attrs, field_type));\n                        }\n                        compound_fields.push(format_field_ident(field));\n                    } else {\n                        // scalar field\n                        for attr in field.attrs.iter() {\n                            // still have to parse column attributes to extract unique keys\n                            if attr.path().is_ident(\"sea_orm\") {\n                                attr.parse_nested_meta(|meta| {\n                                    if meta.path.is_ident(\"unique\") {\n                                        unique_keys.insert(\n                                            ident.clone(),\n                                            vec![(ident.clone(), field.ty.clone())],\n                                        );\n                                    } else if meta.path.is_ident(\"unique_key\") {\n                                        let lit = meta.value()?.parse()?;\n                                        if let Lit::Str(litstr) = lit {\n                                            unique_keys\n                                                .entry(litstr.parse()?)\n                                                .or_default()\n                                                .push((ident.clone(), field.ty.clone()));\n                                        } else {\n                                            return Err(\n                                                meta.error(format!(\"Invalid unique_key {lit:?}\"))\n                                            );\n                                        }\n                                    } else {\n                                        // Reads the value expression to advance the parse stream.\n                                        let _: Option<Expr> =\n                                            meta.value().and_then(|v| v.parse()).ok();\n                                    }\n\n                                    Ok(())\n                                })?;\n                            }\n                        }\n                        model_fields.push(format_field_ident(field));\n                    }\n                }\n            }\n        }\n    }\n\n    let impl_model_trait = DeriveModel::new(&ident, &data, &attrs)?.impl_model_trait();\n\n    let impl_from_model = quote! {\n        impl Model {\n            #[doc = \" Generated by sea-orm-macros\"]\n            pub fn into_ex(self) -> ModelEx {\n                self.into()\n            }\n        }\n\n        #[automatically_derived]\n        impl std::convert::From<Model> for ModelEx {\n            fn from(m: Model) -> Self {\n                Self {\n                    #(#model_fields: m.#model_fields,)*\n                    #(#compound_fields: Default::default(),)*\n                }\n            }\n        }\n\n        #[automatically_derived]\n        impl std::convert::From<ModelEx> for Model {\n            fn from(m: ModelEx) -> Self {\n                Self {\n                    #(#model_fields: m.#model_fields,)*\n                }\n            }\n        }\n\n        #[automatically_derived]\n        impl PartialEq<ModelEx> for Model {\n            fn eq(&self, other: &ModelEx) -> bool {\n                true #(&& self.#model_fields == other.#model_fields)*\n            }\n        }\n\n        #[automatically_derived]\n        impl PartialEq<Model> for ModelEx {\n            fn eq(&self, other: &Model) -> bool {\n                true #(&& self.#model_fields == other.#model_fields)*\n            }\n        }\n    };\n\n    let mut relation_enum_variants: Punctuated<_, Comma> = Punctuated::new();\n    let mut related_entity_enum_variants: Punctuated<_, Comma> = Punctuated::new();\n\n    let impl_related_trait = {\n        let mut ts = TokenStream::new();\n        let mut seen_entity = HashMap::new();\n        for (_, field_type) in impl_related.iter() {\n            let entity_path = extract_compound_entity(field_type);\n            *seen_entity.entry(entity_path).or_insert(0) += 1;\n        }\n\n        for (attrs, field_type) in impl_related.iter() {\n            if attrs.self_ref.is_some() && attrs.via.is_some() {\n                ts.extend(expand_impl_related_self_via(attrs, field_type)?);\n            } else {\n                if attrs.self_ref.is_some() && attrs.relation_enum.is_none() {\n                    return Err(syn::Error::new_spanned(\n                        ident,\n                        \"Please specify `relation_enum` for `self_ref`\",\n                    ));\n                }\n                if let Some(var) = relation_enum_variant(attrs, field_type) {\n                    relation_enum_variants.push(var);\n                }\n                if attrs.self_ref.is_some() && field_type.starts_with(\"HasMany<\") {\n                    // related entity is already provided by the HasOne item\n                    // so self_ref HasMany has to be skipped\n                    continue;\n                }\n                let (first, second) = related_entity_enum_variant(attrs, field_type);\n                related_entity_enum_variants.push(first);\n                if let Some(second) = second {\n                    related_entity_enum_variants.push(second);\n                }\n                let entity_path = extract_compound_entity(field_type);\n                if *seen_entity.get(entity_path).unwrap() == 1 {\n                    // prevent impl trait for same entity twice\n                    ts.extend(expand_impl_related_trait(attrs, field_type)?);\n                }\n            }\n        }\n\n        ts\n    };\n\n    let relation_enum = if !compact {\n        quote! {\n            #[doc = \" Generated by sea-orm-macros\"]\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {\n                #relation_enum_variants\n            }\n        }\n    } else {\n        // for backwards compatibility with compact models\n        quote!()\n    };\n\n    let related_entity_enum = if !compact {\n        quote! {\n            #[doc = \" Generated by sea-orm-macros\"]\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]\n            pub enum RelatedEntity {\n                #related_entity_enum_variants\n            }\n        }\n    } else {\n        // for backwards compatibility with compact models\n        quote!()\n    };\n\n    let (typed_column, typed_column_const) = expand_typed_column(&data)?;\n\n    let (entity_find_by_key, loader_filter_by_key) = expand_find_by_unique_key(unique_keys);\n\n    let entity_loader = expand_entity_loader(entity_loader_schema);\n\n    Ok(quote! {\n        #typed_column\n\n        #typed_column_const\n\n        #impl_from_model\n\n        #impl_model_trait\n\n        #relation_enum\n\n        #impl_related_trait\n\n        #related_entity_enum\n\n        #entity_loader\n\n        impl Entity {\n            #[doc = \" Generated by sea-orm-macros\"]\n            pub const COLUMN: TypedColumn = COLUMN;\n\n            #entity_find_by_key\n        }\n\n        impl EntityLoader {\n            #loader_filter_by_key\n        }\n    })\n}\n\nfn relation_enum_variant(attr: &compound_attr::SeaOrm, ty: &str) -> Option<TokenStream> {\n    let (related_entity, relation_enum) = get_related(attr, ty);\n    if attr.belongs_to.is_some() {\n        let belongs_to = Ident::new(\"belongs_to\", Span::call_site());\n\n        let from = format_tuple(\n            \"\",\n            \"Column\",\n            &attr\n                .from\n                .as_ref()\n                .expect(\"Must specify `from` and `to` on belongs_to relation\")\n                .value(),\n        );\n        let to = format_tuple(\n            related_entity.trim_end_matches(\"::Entity\"),\n            \"Column\",\n            &attr\n                .to\n                .as_ref()\n                .expect(\"Must specify `from` and `to` on belongs_to relation\")\n                .value(),\n        );\n        let mut extra: Punctuated<_, Comma> = Punctuated::new();\n        if let Some(on_update) = &attr.on_update {\n            let tag = Ident::new(\"on_update\", on_update.span());\n            extra.push(quote!(#tag = #on_update))\n        }\n        if let Some(on_delete) = &attr.on_delete {\n            let tag = Ident::new(\"on_delete\", on_delete.span());\n            extra.push(quote!(#tag = #on_delete))\n        }\n        if let Some(()) = &attr.skip_fk {\n            extra.push(quote!(skip_fk))\n        }\n\n        Some(quote! {\n            #[doc = \" Generated by sea-orm-macros\"]\n            #[sea_orm(#belongs_to = #related_entity, from = #from, to = #to, #extra)]\n            #relation_enum\n        })\n    } else if attr.self_ref.is_some()\n        && attr.via.is_none()\n        && attr.from.is_some()\n        && attr.to.is_some()\n    {\n        let belongs_to = Ident::new(\"belongs_to\", Span::call_site());\n\n        let from = format_tuple(\"\", \"Column\", &attr.from.as_ref().unwrap().value());\n        let to = format_tuple(\"\", \"Column\", &attr.to.as_ref().unwrap().value());\n        let mut extra: Punctuated<_, Comma> = Punctuated::new();\n        if let Some(on_update) = &attr.on_update {\n            let tag = Ident::new(\"on_update\", on_update.span());\n            extra.push(quote!(#tag = #on_update))\n        }\n        if let Some(on_delete) = &attr.on_delete {\n            let tag = Ident::new(\"on_delete\", on_delete.span());\n            extra.push(quote!(#tag = #on_delete))\n        }\n        if let Some(()) = &attr.skip_fk {\n            extra.push(quote!(skip_fk))\n        }\n\n        Some(quote! {\n            #[doc = \" Generated by sea-orm-macros\"]\n            #[sea_orm(#belongs_to = \"Entity\", from = #from, to = #to, #extra)]\n            #relation_enum\n        })\n    } else if attr.self_ref.is_some()\n        && attr.via.is_none()\n        && attr.relation_reverse.is_some()\n        && ty.starts_with(\"HasMany<\")\n    {\n        let has_many = Ident::new(\"has_many\", Span::call_site());\n\n        #[allow(clippy::unnecessary_unwrap)]\n        let via_rel = format!(\n            \"Relation::{}\",\n            attr.relation_reverse.as_ref().unwrap().value()\n        );\n\n        Some(quote! {\n            #[doc = \" Generated by sea-orm-macros\"]\n            #[sea_orm(#has_many = \"Entity\", via_rel = #via_rel)]\n            #relation_enum\n        })\n    } else if attr.has_many.is_some() && attr.via.is_none() {\n        // skip junction relation\n\n        let has_many = Ident::new(\"has_many\", Span::call_site());\n        let mut extra: Punctuated<_, Comma> = Punctuated::new();\n        if let Some(via_rel) = &attr.via_rel {\n            let tag = Ident::new(\"via_rel\", via_rel.span());\n            let via_rel = format!(\"Relation::{}\", via_rel.value());\n            extra.push(quote!(#tag = #via_rel))\n        }\n\n        Some(quote! {\n            #[doc = \" Generated by sea-orm-macros\"]\n            #[sea_orm(#has_many = #related_entity, #extra)]\n            #relation_enum\n        })\n    } else if attr.has_one.is_some() {\n        let has_one = Ident::new(\"has_one\", Span::call_site());\n        let mut extra: Punctuated<_, Comma> = Punctuated::new();\n        if let Some(via_rel) = &attr.via_rel {\n            let tag = Ident::new(\"via_rel\", via_rel.span());\n            let via_rel = format!(\"Relation::{}\", via_rel.value());\n            extra.push(quote!(#tag = #via_rel))\n        }\n\n        Some(quote! {\n            #[doc = \" Generated by sea-orm-macros\"]\n            #[sea_orm(#has_one = #related_entity, #extra)]\n            #relation_enum\n        })\n    } else {\n        None\n    }\n}\n\nfn related_entity_enum_variant(\n    attr: &compound_attr::SeaOrm,\n    ty: &str,\n) -> (TokenStream, Option<TokenStream>) {\n    let (related_entity, relation_enum) = get_related(attr, ty);\n\n    let extra = if attr.relation_enum.is_some() {\n        let relation_def = format!(\"Relation::{relation_enum}.def()\");\n        quote!(, def = #relation_def)\n    } else {\n        quote!()\n    };\n\n    let first = quote! {\n        #[doc = \" Generated by sea-orm-macros\"]\n        #[sea_orm(entity = #related_entity #extra)]\n        #relation_enum\n    };\n    let second = if attr.self_ref.is_some() {\n        let relation_def = format!(\"Relation::{relation_enum}.def().rev()\");\n        let relation_enum_ref = if let Some(relation_reverse) = &attr.relation_reverse {\n            Ident::new(&relation_reverse.value(), relation_reverse.span())\n        } else {\n            Ident::new(&format!(\"{relation_enum}Reverse\"), relation_enum.span())\n        };\n        Some(quote! {\n            #[doc = \" Generated by sea-orm-macros\"]\n            #[sea_orm(entity = #related_entity def = #relation_def)]\n            #relation_enum_ref\n        })\n    } else {\n        None\n    };\n\n    (first, second)\n}\n\nfn expand_impl_related_trait(attr: &compound_attr::SeaOrm, ty: &str) -> syn::Result<TokenStream> {\n    if attr.has_one.is_some() || attr.has_many.is_some() || attr.belongs_to.is_some() {\n        let (related_entity, relation_enum) = get_related(attr, ty);\n        let related_entity: TokenStream = related_entity.parse().unwrap();\n\n        if let Some(via_lit) = &attr.via {\n            let via = via_lit.value();\n            let mut junction = via.as_str();\n            let mut via_related = \"\";\n            if let Some((prefix, suffix)) = via.split_once(\"::\") {\n                junction = prefix;\n                via_related = suffix;\n            }\n            let junction = Ident::new(junction, via_lit.span());\n            let relation_def = quote!(super::#junction::Relation::#relation_enum.def());\n            let via_relation_def: TokenStream = if !via_related.is_empty() {\n                let via_related = Ident::new(via_related, via_lit.span());\n                quote!(super::#junction::Relation::#via_related.def().rev())\n            } else {\n                quote!(<super::#junction::Entity as Related<Entity>>::to().rev())\n            };\n\n            Ok(quote! {\n                #[doc = \" Generated by sea-orm-macros\"]\n                impl Related<#related_entity> for Entity {\n                    fn to() -> RelationDef {\n                        #relation_def\n                    }\n                    fn via() -> Option<RelationDef> {\n                        Some(#via_relation_def)\n                    }\n                }\n            })\n\n            // #[sea_orm(relation, via = \"cakes_bakers::Cake\")]\n            // impl Related<super::baker::Entity> for Entity {\n            //     fn to() -> RelationDef {\n            //         super::cakes_bakers::Relation::Baker.def()\n            //     }\n            //     fn via() -> Option<RelationDef> {\n            //         Some(super::cakes_bakers::Relation::Cake.def().rev())\n            //     }\n            // }\n        } else {\n            let relation_def = quote!(Relation::#relation_enum.def());\n\n            Ok(quote! {\n                #[doc = \" Generated by sea-orm-macros\"]\n                impl Related<#related_entity> for Entity {\n                    fn to() -> RelationDef {\n                        #relation_def\n                    }\n                }\n            })\n\n            // #[sea_orm(relation)]\n            // impl Related<super::bakery::Entity> for Entity {\n            //     fn to() -> RelationDef {\n            //         Relation::Bakery.def()\n            //     }\n            // }\n        }\n    } else {\n        Ok(quote!())\n    }\n}\n\nfn expand_impl_related_self_via(\n    attr: &compound_attr::SeaOrm,\n    ty: &str,\n) -> syn::Result<TokenStream> {\n    let Some(via) = &attr.via else {\n        return Err(syn::Error::new(\n            Span::call_site(),\n            \"Please specify the junction Entity `via` for `self_ref`.\",\n        ));\n    };\n\n    if ty != \"HasMany<Entity>\" {\n        return Err(syn::Error::new_spanned(\n            via,\n            \"self_ref + via field type must be `HasMany<Entity>`\",\n        ));\n    }\n\n    if attr.reverse.is_some() {\n        return Ok(quote!());\n    }\n\n    if let (Some(from), Some(to)) = (&attr.from, &attr.to) {\n        let junction = Ident::new(&via.value(), via.span());\n        let from = Ident::new(&from.value(), from.span());\n        let to = Ident::new(&to.value(), to.span());\n\n        Ok(quote! {\n            #[doc = \" Generated by sea-orm-macros\"]\n            impl RelatedSelfVia<super::#junction::Entity> for Entity {\n                fn to() -> RelationDef {\n                    super::#junction::Relation::#to.def()\n                }\n                fn via() -> RelationDef {\n                    super::#junction::Relation::#from.def().rev()\n                }\n            }\n        })\n\n        // #[sea_orm(self_ref, via = \"user_follower\", from = \"User\", to = \"Follower\")]\n        // impl RelatedSelfVia<super::user_follower::Entity> for Entity {\n        //     fn to() -> RelationDef {\n        //         super::user_follower::Relation::Follower.def()\n        //     }\n\n        //     fn via() -> RelationDef {\n        //         super::user_follower::Relation::User.def().rev()\n        //     }\n        // }\n    } else {\n        Ok(quote!())\n    }\n}\n\nfn get_related<'a>(attr: &compound_attr::SeaOrm, ty: &'a str) -> (&'a str, Ident) {\n    let related_entity = extract_compound_entity(ty);\n    let relation_enum = if let Some(relation_enum) = &attr.relation_enum {\n        Ident::new(\n            &relation_enum.value().to_upper_camel_case(),\n            relation_enum.span(),\n        )\n    } else {\n        Ident::new(\n            &infer_relation_name_from_entity(related_entity).to_upper_camel_case(),\n            Span::call_site(),\n        )\n    };\n    (related_entity, relation_enum)\n}\n\nfn infer_relation_name_from_entity(s: &str) -> &str {\n    let s = s.trim_end_matches(\"::Entity\");\n    if let Some((_, suffix)) = s.rsplit_once(\"::\") {\n        return suffix;\n    }\n    s\n}\n\nfn expand_find_by_unique_key(\n    unique_keys: BTreeMap<Ident, Vec<(Ident, Type)>>,\n) -> (TokenStream, TokenStream) {\n    let mut entity_find_by_key = TokenStream::new();\n    let mut loader_filter_by_key = TokenStream::new();\n\n    for (name, columns) in unique_keys {\n        let find_method = format_ident!(\"find_by_{}\", name);\n        let filter_method = format_ident!(\"filter_by_{}\", name);\n        let delete_method = format_ident!(\"delete_by_{}\", name);\n        if columns.len() > 1 {\n            let key_type = columns.iter().map(|(_, ty)| ty).collect::<Vec<_>>();\n\n            let filters = columns\n                .iter()\n                .enumerate()\n                .map(|(i, (col, _))| {\n                    let i = syn::Index::from(i);\n                    let col = to_upper_camel_case(col);\n                    quote!(Column::#col.eq(v.#i))\n                })\n                .collect::<Vec<_>>();\n\n            entity_find_by_key.extend(quote! {\n                #[doc = \" Generated by sea-orm-macros\"]\n                pub fn #find_method(v: (#(#key_type),*)) -> Select<Entity> {\n                    Self::find()\n                        #(.filter(#filters))*\n                }\n\n                #[doc = \" Generated by sea-orm-macros\"]\n                pub fn #delete_method(v: (#(#key_type),*)) -> sea_orm::ValidatedDeleteOne<Entity> {\n                    sea_orm::Delete::_one_only_for_use_by_model_ex(Entity)\n                        #(.filter(#filters))*\n                }\n            });\n            loader_filter_by_key.extend(quote! {\n                #[doc = \" Generated by sea-orm-macros\"]\n                pub fn #filter_method(mut self, v: (#(#key_type),*)) -> Self {\n                    #(self.filter_mut(#filters);)*\n                    self\n                }\n            });\n        } else {\n            let col = to_upper_camel_case(&columns[0].0);\n            let key_type = &columns[0].1;\n            entity_find_by_key.extend(quote! {\n                #[doc = \" Generated by sea-orm-macros\"]\n                pub fn #find_method(v: impl Into<#key_type>) -> Select<Entity> {\n                    Self::find().filter(Column::#col.eq(v.into()))\n                }\n            });\n            loader_filter_by_key.extend(quote! {\n                #[doc = \" Generated by sea-orm-macros\"]\n                pub fn #filter_method(mut self, v: impl Into<#key_type>) -> Self {\n                    self.filter_mut(Column::#col.eq(v.into()));\n                    self\n                }\n            });\n        }\n    }\n\n    (entity_find_by_key, loader_filter_by_key)\n}\n\nfn format_tuple(prefix: &str, middle: &str, suffix: &str) -> String {\n    use std::fmt::Write;\n\n    let parts = if suffix.starts_with('(') && suffix.ends_with(')') {\n        suffix[1..suffix.len() - 1]\n            .split(',')\n            .map(|s| s.trim())\n            .collect()\n    } else {\n        vec![suffix]\n    };\n\n    let mut output = String::new();\n    if parts.len() > 1 {\n        output.write_char('(').unwrap();\n    }\n    for (i, suffix) in parts.iter().enumerate() {\n        let mut part = String::new();\n        part.write_str(prefix).unwrap();\n        if !part.is_empty() {\n            part.write_str(\"::\").unwrap();\n        }\n        part.write_str(middle).unwrap();\n        part.write_str(\"::\").unwrap();\n        part.write_str(&suffix.to_upper_camel_case()).unwrap();\n\n        if i > 0 {\n            output.write_str(\", \").unwrap();\n        }\n        output.write_str(&part).unwrap();\n    }\n    if parts.len() > 1 {\n        output.write_char(')').unwrap();\n    }\n\n    output\n}\n\nfn to_upper_camel_case(i: &Ident) -> Ident {\n    Ident::new(&i.to_string().to_upper_camel_case(), Span::call_site())\n}\n\n#[cfg(test)]\nmod test {\n    use super::format_tuple;\n\n    #[test]\n    fn test_format_tuple() {\n        assert_eq!(format_tuple(\"\", \"Column\", \"Id\"), \"Column::Id\");\n        assert_eq!(format_tuple(\"super\", \"Column\", \"Id\"), \"super::Column::Id\");\n        assert_eq!(\n            format_tuple(\"\", \"Column\", \"(A, B)\"),\n            \"(Column::A, Column::B)\"\n        );\n        assert_eq!(\n            format_tuple(\"super\", \"Column\", \"(A, B)\"),\n            \"(super::Column::A, super::Column::B)\"\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/partial_model.rs",
    "content": "use heck::ToUpperCamelCase;\nuse proc_macro2::{Span, TokenStream};\nuse quote::{format_ident, quote, quote_spanned};\nuse syn::{\n    Expr, Meta, Type, ext::IdentExt, punctuated::Punctuated, spanned::Spanned, token::Comma,\n};\n\nuse super::from_query_result::{\n    DeriveFromQueryResult, FromQueryResultItem, ItemType as FqrItemType,\n};\nuse super::into_active_model::{DeriveIntoActiveModel, IntoActiveModelField};\nuse super::util::GetMeta;\n\n#[derive(Debug)]\nenum Error {\n    InputNotStruct,\n    EntityNotSpecified,\n    NotSupportGeneric(Span),\n    OverlappingAttributes(Span),\n    Syn(syn::Error),\n}\n\n#[derive(Debug, PartialEq, Eq)]\nenum ColumnAs {\n    /// alias from a column in model\n    Col {\n        col: Option<syn::Ident>,\n        field: syn::Ident,\n    },\n    /// from an expr\n    Expr {\n        expr: syn::Expr,\n        field: syn::Ident,\n    },\n    /// nesting another struct\n    Nested {\n        typ: Type,\n        field: syn::Ident,\n        alias: Option<String>,\n    },\n    Skip(syn::Ident),\n}\n\nstruct DerivePartialModel {\n    entity: Option<syn::Type>,\n    active_model: Option<syn::Type>,\n    model_alias: Option<String>,\n    ident: syn::Ident,\n    fields: Vec<ColumnAs>,\n    from_query_result: bool,\n    into_active_model: bool,\n}\n\nimpl DerivePartialModel {\n    fn new(input: syn::DeriveInput) -> Result<Self, Error> {\n        if !input.generics.params.is_empty() {\n            return Err(Error::NotSupportGeneric(input.generics.params.span()));\n        }\n\n        let fields = match input.data {\n            syn::Data::Struct(syn::DataStruct {\n                fields: syn::Fields::Named(syn::FieldsNamed { named, .. }),\n                ..\n            }) => named,\n            _ => return Err(Error::InputNotStruct),\n        };\n\n        let mut entity = None;\n        let mut entity_string = String::new();\n        let mut active_model = None;\n        let mut model_alias = None;\n        let mut from_query_result = true;\n        let mut into_active_model = false;\n\n        for attr in input.attrs.iter() {\n            if !attr.path().is_ident(\"sea_orm\") {\n                continue;\n            }\n\n            if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated) {\n                for meta in list {\n                    if let Some(s) = meta.get_as_kv(\"entity\") {\n                        entity = Some(syn::parse_str::<syn::Type>(&s).map_err(Error::Syn)?);\n                        entity_string = s;\n                    } else if let Some(s) = meta.get_as_kv(\"alias\") {\n                        model_alias = Some(s);\n                    } else if let Some(s) = meta.get_as_kv(\"from_query_result\") {\n                        if s == \"false\" {\n                            from_query_result = false;\n                        }\n                    } else if meta.exists(\"into_active_model\") {\n                        into_active_model = true;\n                    }\n                }\n            }\n        }\n\n        if into_active_model {\n            active_model = Some(\n                syn::parse_str::<syn::Type>(&format!(\n                    \"<{entity_string} as EntityTrait>::ActiveModel\"\n                ))\n                .map_err(Error::Syn)?,\n            );\n        }\n\n        let mut column_as_list = Vec::with_capacity(fields.len());\n\n        for field in fields {\n            let field_span = field.span();\n\n            let mut from_col = None;\n            let mut from_expr = None;\n            let mut nested = false;\n            let mut nested_alias = None;\n            let mut skip = false;\n\n            for attr in field.attrs.iter() {\n                if !attr.path().is_ident(\"sea_orm\") {\n                    continue;\n                }\n\n                if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)\n                {\n                    for meta in list.iter() {\n                        if meta.exists(\"skip\") {\n                            skip = true;\n                        } else if meta.exists(\"nested\") {\n                            nested = true;\n                        } else if let Some(s) = meta.get_as_kv(\"from_col\") {\n                            from_col = Some(format_ident!(\"{}\", s.to_upper_camel_case()));\n                        } else if let Some(s) = meta.get_as_kv(\"from_expr\") {\n                            from_expr = Some(syn::parse_str::<Expr>(&s).map_err(Error::Syn)?);\n                        } else if let Some(s) = meta.get_as_kv(\"alias\") {\n                            nested_alias = Some(s);\n                        }\n                    }\n                }\n            }\n\n            let field_name = field.ident.unwrap();\n\n            let col_as = match (from_col, from_expr, nested) {\n                (Some(col), None, false) => {\n                    if entity.is_none() {\n                        return Err(Error::EntityNotSpecified);\n                    }\n\n                    ColumnAs::Col {\n                        col: Some(col),\n                        field: field_name,\n                    }\n                }\n                (None, Some(expr), false) => ColumnAs::Expr {\n                    expr,\n                    field: field_name,\n                },\n                (None, None, true) => ColumnAs::Nested {\n                    typ: field.ty,\n                    field: field_name,\n                    alias: nested_alias,\n                },\n                (None, None, false) => {\n                    if entity.is_none() {\n                        return Err(Error::EntityNotSpecified);\n                    }\n                    if skip {\n                        ColumnAs::Skip(field_name)\n                    } else {\n                        ColumnAs::Col {\n                            col: None,\n                            field: field_name,\n                        }\n                    }\n                }\n                (_, _, _) => return Err(Error::OverlappingAttributes(field_span)),\n            };\n            column_as_list.push(col_as);\n        }\n\n        Ok(Self {\n            entity,\n            active_model,\n            model_alias,\n            ident: input.ident,\n            fields: column_as_list,\n            from_query_result,\n            into_active_model,\n        })\n    }\n\n    fn expand(&self) -> syn::Result<TokenStream> {\n        let impl_partial_model = self.impl_partial_model();\n\n        let impl_from_query_result = if self.from_query_result {\n            DeriveFromQueryResult {\n                ident: self.ident.clone(),\n                generics: Default::default(),\n                fields: self\n                    .fields\n                    .iter()\n                    .map(|col_as| FromQueryResultItem {\n                        typ: match col_as {\n                            ColumnAs::Nested { .. } => FqrItemType::Nested,\n                            ColumnAs::Skip(_) => FqrItemType::Skip,\n                            _ => FqrItemType::Flat,\n                        },\n                        ident: match col_as {\n                            ColumnAs::Col { field, .. } => field,\n                            ColumnAs::Expr { field, .. } => field,\n                            ColumnAs::Nested { field, .. } => field,\n                            ColumnAs::Skip(field) => field,\n                        }\n                        .to_owned(),\n                        alias: None,\n                    })\n                    .collect(),\n            }\n            .impl_from_query_result(true)\n        } else {\n            quote!()\n        };\n\n        let impl_into_active_model = if self.into_active_model {\n            DeriveIntoActiveModel {\n                ident: self.ident.clone(),\n                active_model: self.active_model.clone(),\n                fields: self\n                    .fields\n                    .iter()\n                    .filter_map(|col_as| {\n                        match col_as {\n                            ColumnAs::Col { field, .. } => Some(field),\n                            ColumnAs::Expr { field, .. } => Some(field),\n                            ColumnAs::Nested { .. } => None,\n                            ColumnAs::Skip(_) => None,\n                        }\n                        .map(|f| IntoActiveModelField::Normal(f.clone()))\n                    })\n                    .collect(),\n                set_fields: Vec::new(),\n                exhaustive: false,\n            }\n            .impl_into_active_model()\n        } else {\n            quote!()\n        };\n\n        Ok(quote! {\n            #impl_partial_model\n            #impl_from_query_result\n            #impl_into_active_model\n        })\n    }\n\n    fn impl_partial_model(&self) -> TokenStream {\n        let select_ident = format_ident!(\"select\");\n        let DerivePartialModel {\n            entity,\n            model_alias,\n            ident,\n            fields,\n            ..\n        } = self;\n        let select_col_code_gen = fields.iter().map(|col_as| match col_as {\n            ColumnAs::Col { col, field } => {\n                let field = field.unraw().to_string();\n                let entity = entity.as_ref().unwrap();\n\n                let variant_name = if let Some(col) = col {\n                    col\n                } else {\n                    &format_ident!(\"{}\", field.to_upper_camel_case())\n                };\n\n                // variant of the entity column\n                let column = quote! {\n                    <#entity as sea_orm::EntityTrait>::Column::#variant_name\n                };\n\n                // We cast enum as text in select_as if the backend is postgres\n\n                let non_nested = match model_alias {\n                    Some(model_alias) => quote! {\n                        let col_expr = sea_orm::sea_query::Expr::col((#model_alias, #column));\n                        let casted = sea_orm::ColumnTrait::select_as(&#column, col_expr);\n                        sea_orm::QuerySelect::column_as(#select_ident, casted, col_alias)\n                    },\n                    None => quote! {\n                        sea_orm::QuerySelect::column_as(#select_ident, #column, col_alias)\n                    },\n                };\n\n                quote! {\n                    let #select_ident = {\n                        let col_alias = pre.map_or(#field.to_string(), |pre| format!(\"{pre}{}\", #field));\n                        if let Some(nested_alias) = nested_alias {\n                            let alias = sea_orm::sea_query::SeaRc::new(nested_alias);\n                            let col_expr = sea_orm::sea_query::Expr::col(\n                                (alias, #column)\n                            );\n\n                            let casted = sea_orm::ColumnTrait::select_as(&#column, col_expr);\n                            sea_orm::QuerySelect::column_as(#select_ident, casted, col_alias)\n                        } else {\n                            #non_nested\n                        }\n                    };\n                }\n            }\n\n            ColumnAs::Expr { expr, field } => {\n                let field = field.unraw().to_string();\n                quote!(let #select_ident =\n                    if let Some(prefix) = pre {\n                        let ident = format!(\"{prefix}{}\", #field);\n                        sea_orm::QuerySelect::column_as(#select_ident, #expr, ident)\n                    } else {\n                        sea_orm::QuerySelect::column_as(#select_ident, #expr, #field)\n                    };\n                )\n            }\n            ColumnAs::Nested { typ, field, alias } => {\n                let field = field.unraw().to_string();\n                let alias_ref: Option<&str> = alias.as_deref();\n                let alias_arg = match alias_ref {\n                    Some(s) => quote! { Some(#s) },\n                    None => quote! { None },\n                };\n                quote!(let #select_ident =\n                    <#typ as sea_orm::PartialModelTrait>::select_cols_nested(#select_ident,\n                        Some(&if let Some(prefix) = pre {\n                                format!(\"{prefix}{}_\", #field)\n                            } else {\n                                format!(\"{}_\", #field)\n                            }\n                        ),\n                        #alias_arg\n                    );\n                )\n            }\n            ColumnAs::Skip(_) => quote!(),\n        });\n\n        quote! {\n            #[automatically_derived]\n            impl sea_orm::PartialModelTrait for #ident {\n                fn select_cols_nested<S: sea_orm::QuerySelect>(#select_ident: S, pre: Option<&str>, nested_alias: Option<&'static str>) -> S {\n                    #(#select_col_code_gen)*\n                    #select_ident\n                }\n            }\n        }\n    }\n}\n\npub fn expand_derive_partial_model(input: syn::DeriveInput) -> syn::Result<TokenStream> {\n    let ident_span = input.ident.span();\n\n    match DerivePartialModel::new(input) {\n        Ok(partial_model) => partial_model.expand(),\n        Err(Error::NotSupportGeneric(span)) => Ok(quote_spanned! {\n            span => compile_error!(\"you can only derive `DerivePartialModel` on concrete struct\");\n        }),\n        Err(Error::OverlappingAttributes(span)) => Ok(quote_spanned! {\n            span => compile_error!(\"you can only use one of `from_col`, `from_expr`, `nested`\");\n        }),\n        Err(Error::EntityNotSpecified) => Ok(quote_spanned! {\n            ident_span => compile_error!(\"you need specific which entity you are using\")\n        }),\n        Err(Error::InputNotStruct) => Ok(quote_spanned! {\n            ident_span => compile_error!(\"you can only derive `DerivePartialModel` on named struct\");\n        }),\n        Err(Error::Syn(err)) => Err(err),\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use quote::format_ident;\n    use syn::{DeriveInput, Type, parse_str};\n\n    use crate::derives::partial_model::ColumnAs;\n\n    use super::DerivePartialModel;\n\n    type StdResult<T> = Result<T, Box<dyn std::error::Error>>;\n\n    const CODE_SNIPPET_1: &str = r#\"\n        #[sea_orm(entity = \"Entity\")]\n        struct PartialModel {\n            default_field: i32,\n            #[sea_orm(from_col = \"bar\")]\n            alias_field: i32,\n            #[sea_orm(from_expr = \"Expr::val(1).add(1)\")]\n            expr_field : i32\n        }\n        \"#;\n\n    #[test]\n    fn test_load_macro_input_1() -> StdResult<()> {\n        let input = parse_str::<DeriveInput>(CODE_SNIPPET_1)?;\n\n        let middle = DerivePartialModel::new(input).unwrap();\n        assert_eq!(middle.entity, Some(parse_str::<Type>(\"Entity\").unwrap()));\n        assert_eq!(middle.ident, format_ident!(\"PartialModel\"));\n        assert_eq!(middle.fields.len(), 3);\n        assert_eq!(\n            middle.fields[0],\n            ColumnAs::Col {\n                col: None,\n                field: format_ident!(\"default_field\")\n            }\n        );\n        assert_eq!(\n            middle.fields[1],\n            ColumnAs::Col {\n                col: Some(format_ident!(\"Bar\")),\n                field: format_ident!(\"alias_field\"),\n            },\n        );\n        assert_eq!(\n            middle.fields[2],\n            ColumnAs::Expr {\n                expr: syn::parse_str(\"Expr::val(1).add(1)\").unwrap(),\n                field: format_ident!(\"expr_field\"),\n            }\n        );\n        assert_eq!(middle.from_query_result, true);\n\n        Ok(())\n    }\n\n    const CODE_SNIPPET_2: &str = r#\"\n        #[sea_orm(entity = \"MyEntity\", from_query_result = \"false\")]\n        struct PartialModel {\n            default_field: i32,\n        }\n        \"#;\n\n    #[test]\n    fn test_load_macro_input_2() -> StdResult<()> {\n        let input = parse_str::<DeriveInput>(CODE_SNIPPET_2)?;\n\n        let middle = DerivePartialModel::new(input).unwrap();\n        assert_eq!(middle.entity, Some(parse_str::<Type>(\"MyEntity\").unwrap()));\n        assert_eq!(middle.ident, format_ident!(\"PartialModel\"));\n        assert_eq!(middle.fields.len(), 1);\n        assert_eq!(\n            middle.fields[0],\n            ColumnAs::Col {\n                col: None,\n                field: format_ident!(\"default_field\")\n            }\n        );\n        assert_eq!(middle.from_query_result, false);\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/primary_key.rs",
    "content": "use super::impl_iden;\nuse proc_macro2::{Ident, TokenStream};\nuse quote::{quote, quote_spanned};\nuse syn::{Data, DataEnum, Fields, Variant};\n\nfn impl_primary_key_to_column(ident: &Ident, data: &Data) -> syn::Result<TokenStream> {\n    let variants = match data {\n        syn::Data::Enum(DataEnum { variants, .. }) => variants,\n        _ => {\n            return Ok(quote_spanned! {\n                ident.span() => compile_error!(\"you can only derive DerivePrimaryKey on enums\");\n            });\n        }\n    };\n\n    if variants.is_empty() {\n        return Ok(quote_spanned! {\n            ident.span() => compile_error!(\"Entity must have a primary key column. See <https://github.com/SeaQL/sea-orm/issues/485> for details.\");\n        });\n    }\n\n    let variant: Vec<TokenStream> = variants\n        .iter()\n        .map(|Variant { ident, fields, .. }| match fields {\n            Fields::Named(_) => quote! { #ident{..} },\n            Fields::Unnamed(_) => quote! { #ident(..) },\n            Fields::Unit => quote! { #ident },\n        })\n        .collect();\n\n    Ok(quote!(\n        #[automatically_derived]\n        impl sea_orm::PrimaryKeyToColumn for #ident {\n            type Column = Column;\n\n            fn into_column(self) -> Self::Column {\n                match self {\n                    #(Self::#variant => Self::Column::#variant,)*\n                }\n            }\n\n            fn from_column(col: Self::Column) -> Option<Self> {\n                match col {\n                    #(Self::Column::#variant => Some(Self::#variant),)*\n                    _ => None,\n                }\n            }\n        }\n    ))\n}\n\n/// Method to derive a Primary Key for a Model using the [PrimaryKeyTrait](sea_orm::PrimaryKeyTrait)\npub fn expand_derive_primary_key(ident: &Ident, data: &Data) -> syn::Result<TokenStream> {\n    let impl_primary_key_to_column = impl_primary_key_to_column(ident, data)?;\n    let impl_iden = impl_iden(ident, data)?;\n\n    Ok(quote!(\n        #impl_primary_key_to_column\n\n        #impl_iden\n    ))\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/related_entity.rs",
    "content": "#[cfg(feature = \"seaography\")]\nmod private {\n    use heck::ToLowerCamelCase;\n    use proc_macro_crate::{FoundCrate, crate_name};\n    use proc_macro2::{Ident, Span, TokenStream};\n    use quote::{quote, quote_spanned};\n\n    use crate::derives::attributes::related_attr;\n\n    enum Error {\n        InputNotEnum,\n        InvalidEntityPath,\n        Syn(syn::Error),\n    }\n\n    struct DeriveRelatedEntity {\n        entity_ident: TokenStream,\n        ident: syn::Ident,\n        variants: syn::punctuated::Punctuated<syn::Variant, syn::token::Comma>,\n    }\n\n    impl DeriveRelatedEntity {\n        fn new(input: syn::DeriveInput) -> Result<Self, Error> {\n            let sea_attr = related_attr::SeaOrm::try_from_attributes(&input.attrs)\n                .map_err(Error::Syn)?\n                .unwrap_or_default();\n\n            let ident = input.ident;\n            let entity_ident = match sea_attr.entity.as_ref().map(Self::parse_lit_string) {\n                Some(entity_ident) => entity_ident.map_err(|_| Error::InvalidEntityPath)?,\n                None => quote! { Entity },\n            };\n\n            let variants = match input.data {\n                syn::Data::Enum(syn::DataEnum { variants, .. }) => variants,\n                _ => return Err(Error::InputNotEnum),\n            };\n\n            Ok(DeriveRelatedEntity {\n                entity_ident,\n                ident,\n                variants,\n            })\n        }\n\n        fn expand(&self) -> syn::Result<TokenStream> {\n            let ident = &self.ident;\n            let entity_ident = &self.entity_ident;\n\n            let mut get_relation_impl = Vec::new();\n            let mut get_relation_name_impl = Vec::new();\n            let mut get_related_entity_filter_impl = Vec::new();\n\n            for variant in &self.variants {\n                let attr = related_attr::SeaOrm::from_attributes(&variant.attrs)?;\n\n                let enum_name = &variant.ident;\n\n                let target_entity = attr\n                    .entity\n                    .as_ref()\n                    .map(Self::parse_lit_string)\n                    .ok_or_else(|| {\n                        syn::Error::new_spanned(variant, \"Missing value for 'entity'\")\n                    })??;\n\n                let def = match attr.def {\n                    Some(def) => Some(Self::parse_lit_string(&def).map_err(|_| {\n                        syn::Error::new_spanned(variant, \"Missing value for 'def'\")\n                    })?),\n                    None => None,\n                };\n\n                let name = enum_name.to_string().to_lower_camel_case();\n\n                get_relation_impl.push(if let Some(def) = &def {\n                    quote! { Self::#enum_name => builder.get_relation::<#entity_ident, #target_entity>(#name, #def) }\n                } else {\n                    quote! { Self::#enum_name => via_builder.get_relation::<#entity_ident, #target_entity>(#name) }\n                });\n                get_relation_name_impl.push(if let Some(def) = &def {\n                    quote! { Self::#enum_name => builder.get_relation_name::<#entity_ident, #target_entity>(#name, #def) }\n                } else {\n                    quote! { Self::#enum_name => via_builder.get_relation_name::<#entity_ident, #target_entity>(#name) }\n                });\n                get_related_entity_filter_impl.push(if let Some(def) = &def {\n                    quote! { Self::#enum_name => builder.get_relation::<#entity_ident, #target_entity>(#name, #def) }\n                } else {\n                    quote! { Self::#enum_name => builder.get_relation_via::<#entity_ident, #target_entity>(#name) }\n                });\n            }\n\n            // Get the path of the `async-graphql` on the application's Cargo.toml\n            let async_graphql_crate = match crate_name(\"async-graphql\") {\n                // if found, use application's `async-graphql`\n                Ok(FoundCrate::Name(name)) => {\n                    let ident = Ident::new(&name, Span::call_site());\n                    quote! { #ident }\n                }\n                Ok(FoundCrate::Itself) => quote! { async_graphql },\n                // if not, then use the `async-graphql` re-exported by `seaography`\n                Err(_) => quote! { seaography::async_graphql },\n            };\n\n            Ok(quote! {\n                impl seaography::RelationBuilder for #ident {\n                    fn get_relation(&self, context: & 'static seaography::BuilderContext) -> #async_graphql_crate::dynamic::Field {\n                        let builder = seaography::EntityObjectRelationBuilder { context };\n                        let via_builder = seaography::EntityObjectViaRelationBuilder { context };\n                        match self {\n                            #(#get_relation_impl,)*\n                            _ => panic!(\"No relations for this entity\"),\n                        }\n                    }\n                    fn get_relation_name(&self, context: & 'static seaography::BuilderContext) -> String {\n                        let builder = seaography::EntityObjectRelationBuilder { context };\n                        let via_builder = seaography::EntityObjectViaRelationBuilder { context };\n                        match self {\n                            #(#get_relation_name_impl,)*\n                            _ => panic!(\"No relations for this entity\"),\n                        }\n                    }\n                    fn get_related_entity_filter(&self, context: & 'static seaography::BuilderContext) -> seaography::RelatedEntityFilterField {\n                        let builder = seaography::RelatedEntityFilterBuilder { context };\n                        match self {\n                            #(#get_related_entity_filter_impl,)*\n                            _ => panic!(\"No relations for this entity\"),\n                        }\n                    }\n                }\n            })\n        }\n\n        fn parse_lit_string(lit: &syn::Lit) -> syn::Result<TokenStream> {\n            match lit {\n                syn::Lit::Str(lit_str) => lit_str\n                    .value()\n                    .parse()\n                    .map_err(|_| syn::Error::new_spanned(lit, \"attribute not valid\")),\n                _ => Err(syn::Error::new_spanned(lit, \"attribute must be a string\")),\n            }\n        }\n    }\n\n    /// Method to derive a Related enumeration\n    pub fn expand_derive_related_entity(input: syn::DeriveInput) -> syn::Result<TokenStream> {\n        let ident_span = input.ident.span();\n\n        match DeriveRelatedEntity::new(input) {\n            Ok(model) => model.expand(),\n            Err(Error::InputNotEnum) => Ok(quote_spanned! {\n                ident_span => compile_error!(\"you can only derive DeriveRelation on enums\");\n            }),\n            Err(Error::InvalidEntityPath) => Ok(quote_spanned! {\n                ident_span => compile_error!(\"invalid attribute value for 'entity'\");\n            }),\n            Err(Error::Syn(err)) => Err(err),\n        }\n    }\n}\n\n#[cfg(not(feature = \"seaography\"))]\nmod private {\n    use proc_macro2::TokenStream;\n\n    pub fn expand_derive_related_entity(_: syn::DeriveInput) -> syn::Result<TokenStream> {\n        Ok(TokenStream::new())\n    }\n}\n\npub use private::*;\n"
  },
  {
    "path": "sea-orm-macros/src/derives/relation.rs",
    "content": "use proc_macro2::TokenStream;\nuse quote::{format_ident, quote, quote_spanned};\n\nuse super::attributes::{derive_attr, relation_attr};\n\nenum Error {\n    InputNotEnum,\n    Syn(syn::Error),\n}\n\nstruct DeriveRelation {\n    entity_ident: syn::Ident,\n    ident: syn::Ident,\n    variants: syn::punctuated::Punctuated<syn::Variant, syn::token::Comma>,\n}\n\nimpl DeriveRelation {\n    fn new(input: syn::DeriveInput) -> Result<Self, Error> {\n        let variants = match input.data {\n            syn::Data::Enum(syn::DataEnum { variants, .. }) => variants,\n            _ => return Err(Error::InputNotEnum),\n        };\n\n        let sea_attr = derive_attr::SeaOrm::try_from_attributes(&input.attrs)\n            .map_err(Error::Syn)?\n            .unwrap_or_default();\n\n        let ident = input.ident;\n        let entity_ident = sea_attr.entity.unwrap_or_else(|| format_ident!(\"Entity\"));\n\n        Ok(DeriveRelation {\n            entity_ident,\n            ident,\n            variants,\n        })\n    }\n\n    fn expand(&self) -> syn::Result<TokenStream> {\n        let expanded_impl_relation_trait = self.impl_relation_trait()?;\n\n        Ok(expanded_impl_relation_trait)\n    }\n\n    fn impl_relation_trait(&self) -> syn::Result<TokenStream> {\n        let ident = &self.ident;\n        let entity_ident = &self.entity_ident;\n        let no_relation_def_msg = format!(\"No RelationDef for {ident}\");\n\n        fn lit_str(lit: &syn::Lit) -> syn::Result<String> {\n            match lit {\n                syn::Lit::Str(lit_str) => Ok(lit_str.value()),\n                _ => Err(syn::Error::new_spanned(lit, \"attribute must be a string\")),\n            }\n        }\n\n        fn parse_lit_str(lit: &syn::Lit) -> syn::Result<TokenStream> {\n            lit_str(lit)?\n                .parse()\n                .map_err(|_| syn::Error::new_spanned(lit, \"attribute not valid\"))\n        }\n\n        let variant_relation_defs: Vec<TokenStream> = self\n            .variants\n            .iter()\n            .map(|variant| {\n                let variant_ident = &variant.ident;\n                let attr = relation_attr::SeaOrm::from_attributes(&variant.attrs)?;\n                let mut relation_type = quote! { error };\n                let related_to = if attr.belongs_to.is_some() {\n                    relation_type = quote! { belongs_to };\n                    attr.belongs_to\n                        .as_ref()\n                        .map(parse_lit_str)\n                        .ok_or_else(|| {\n                            syn::Error::new_spanned(variant, \"Missing value for 'belongs_to'\")\n                        })\n                } else if attr.has_one.is_some() {\n                    relation_type = quote! { has_one };\n                    attr.has_one\n                        .as_ref()\n                        .map(parse_lit_str)\n                        .ok_or_else(|| {\n                            syn::Error::new_spanned(variant, \"Missing value for 'has_one'\")\n                        })\n                } else if attr.has_many.is_some() {\n                    relation_type = quote! { has_many };\n                    attr.has_many\n                        .as_ref()\n                        .map(parse_lit_str)\n                        .ok_or_else(|| {\n                            syn::Error::new_spanned(variant, \"Missing value for 'has_many'\")\n                        })\n                } else {\n                    Err(syn::Error::new_spanned(\n                        variant,\n                        \"Missing one of 'has_one', 'has_many' or 'belongs_to'\",\n                    ))\n                }??;\n\n                let mut result = if let (Some(has_many), Some(via)) = (&attr.has_many, &attr.via_rel) {\n                    let has_many = lit_str(has_many)?;\n                    let via: TokenStream = if has_many == \"Entity\" {\n                        lit_str(via)?\n                    } else {\n                        format!(\"{}::{}\", has_many.trim_end_matches(\"::Entity\"), lit_str(via)?)\n                    }.parse().unwrap();\n                    quote!(\n                        Self::#variant_ident => #entity_ident::has_many_via(#related_to, #via)\n                    )\n                } else {\n                    quote!(\n                        Self::#variant_ident => #entity_ident::#relation_type(#related_to)\n                    )\n                };\n\n                if attr.from.is_some() {\n                    let from =\n                        attr.from\n                            .as_ref()\n                            .map(parse_lit_str)\n                            .ok_or_else(|| {\n                                syn::Error::new_spanned(variant, \"Missing value for 'from'\")\n                            })??;\n                    result = quote! { #result.from(#from) };\n                } else if attr.belongs_to.is_some() {\n                    return Err(syn::Error::new_spanned(variant, \"Missing attribute 'from'\"));\n                }\n\n                if attr.to.is_some() {\n                    let to = attr\n                        .to\n                        .as_ref()\n                        .map(parse_lit_str)\n                        .ok_or_else(|| {\n                            syn::Error::new_spanned(variant, \"Missing value for 'to'\")\n                        })??;\n                    result = quote! { #result.to(#to) };\n                } else if attr.belongs_to.is_some() {\n                    return Err(syn::Error::new_spanned(variant, \"Missing attribute 'to'\"));\n                }\n\n                if attr.on_update.is_some() {\n                    let on_update = attr\n                        .on_update\n                        .as_ref()\n                        .map(parse_lit_str)\n                        .ok_or_else(|| {\n                            syn::Error::new_spanned(variant, \"Missing value for 'on_update'\")\n                        })??;\n                    result = quote! { #result.on_update(sea_orm::prelude::ForeignKeyAction::#on_update) };\n                }\n\n                if attr.on_delete.is_some() {\n                    let on_delete = attr\n                        .on_delete\n                        .as_ref()\n                        .map(parse_lit_str)\n                        .ok_or_else(|| {\n                            syn::Error::new_spanned(variant, \"Missing value for 'on_delete'\")\n                        })??;\n                    result = quote! { #result.on_delete(sea_orm::prelude::ForeignKeyAction::#on_delete) };\n                }\n\n                if attr.on_condition.is_some() {\n                    let on_condition = attr\n                        .on_condition\n                        .as_ref()\n                        .map(parse_lit_str)\n                        .ok_or_else(|| {\n                            syn::Error::new_spanned(variant, \"Missing value for 'on_condition'\")\n                        })??;\n                    result = quote! { #result.on_condition(|_, _| sea_orm::sea_query::IntoCondition::into_condition(#on_condition)) };\n                }\n\n                if attr.fk_name.is_some() {\n                    let fk_name = attr\n                        .fk_name\n                        .as_ref()\n                        .map(|lit| {\n                            match lit {\n                                syn::Lit::Str(lit_str) => Ok(lit_str.value()),\n                                _ => Err(syn::Error::new_spanned(lit, \"attribute must be a string\")),\n                            }\n                        })\n                        .ok_or_else(|| {\n                            syn::Error::new_spanned(variant, \"Missing value for 'fk_name'\")\n                        })??;\n                    result = quote! { #result.fk_name(#fk_name) };\n                }\n\n                if attr.skip_fk.is_some() {\n                    result = quote! { #result.skip_fk() };\n                }\n\n                if attr.condition_type.is_some() {\n                    let condition_type = attr\n                        .condition_type\n                        .as_ref()\n                        .map(|lit| {\n                            match lit {\n                                syn::Lit::Str(lit_str) => {\n                                    match lit_str.value().to_ascii_lowercase().as_str() {\n                                        \"all\" => Ok(quote!( sea_orm::sea_query::ConditionType::All )),\n                                        \"any\" => Ok(quote!( sea_orm::sea_query::ConditionType::Any )),\n                                        _ => Err(syn::Error::new_spanned(lit, \"Condition type must be one of `all` or `any`\")),\n                                    }\n                                },\n                                _ => Err(syn::Error::new_spanned(lit, \"attribute must be a string\")),\n                            }\n                        })\n                        .ok_or_else(|| {\n                            syn::Error::new_spanned(variant, \"Missing value for 'condition_type'\")\n                        })??;\n                    result = quote! { #result.condition_type(#condition_type) };\n                }\n\n                result = quote! { #result.into() };\n\n                Result::<_, syn::Error>::Ok(result)\n            })\n            .collect::<Result<Vec<_>, _>>()?;\n\n        Ok(quote!(\n            #[automatically_derived]\n            impl sea_orm::entity::RelationTrait for #ident {\n                fn def(&self) -> sea_orm::entity::RelationDef {\n                    match self {\n                        #( #variant_relation_defs, )*\n                        _ => panic!(#no_relation_def_msg)\n                    }\n                }\n            }\n        ))\n    }\n}\n\n/// Method to derive a Relation\npub fn expand_derive_relation(input: syn::DeriveInput) -> syn::Result<TokenStream> {\n    let ident_span = input.ident.span();\n\n    match DeriveRelation::new(input) {\n        Ok(model) => model.expand(),\n        Err(Error::InputNotEnum) => Ok(quote_spanned! {\n            ident_span => compile_error!(\"you can only derive DeriveRelation on enums\");\n        }),\n        Err(Error::Syn(err)) => Err(err),\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/try_getable_from_json.rs",
    "content": "use proc_macro2::{Ident, TokenStream};\nuse quote::quote;\n\npub fn expand_derive_from_json_query_result(ident: Ident) -> syn::Result<TokenStream> {\n    let impl_not_u8 = if cfg!(feature = \"postgres-array\") {\n        quote!(\n            #[automatically_derived]\n            impl sea_orm::sea_query::postgres_array::NotU8 for #ident {}\n        )\n    } else {\n        quote!()\n    };\n\n    Ok(quote!(\n        #[automatically_derived]\n        impl sea_orm::TryGetableFromJson for #ident {}\n\n        #[automatically_derived]\n        impl std::convert::From<#ident> for sea_orm::Value {\n            fn from(source: #ident) -> Self {\n                sea_orm::Value::Json(\n                    Some(std::boxed::Box::new(\n                        serde_json::to_value(&source)\n                            .expect(concat!(\"Failed to serialize '\", stringify!(#ident), \"'\"))\n                    ))\n                )\n            }\n        }\n\n        #[automatically_derived]\n        impl sea_orm::sea_query::ValueType for #ident {\n            fn try_from(v: sea_orm::Value) -> Result<Self, sea_orm::sea_query::ValueTypeErr> {\n                match v {\n                    sea_orm::Value::Json(Some(json)) => Ok(\n                        serde_json::from_value(*json).map_err(|_| sea_orm::sea_query::ValueTypeErr)?,\n                    ),\n                    _ => Err(sea_orm::sea_query::ValueTypeErr),\n                }\n            }\n\n            fn type_name() -> String {\n                stringify!(#ident).to_owned()\n            }\n\n            fn array_type() -> sea_orm::sea_query::ArrayType {\n                sea_orm::sea_query::ArrayType::Json\n            }\n\n            fn column_type() -> sea_orm::sea_query::ColumnType {\n                sea_orm::sea_query::ColumnType::Json\n            }\n        }\n\n        #[automatically_derived]\n        impl sea_orm::sea_query::Nullable for #ident {\n            fn null() -> sea_orm::Value {\n                sea_orm::Value::Json(None)\n            }\n        }\n\n        #[automatically_derived]\n        impl sea_orm::IntoActiveValue<#ident> for #ident {\n            fn into_active_value(self) -> sea_orm::ActiveValue<#ident> {\n                sea_orm::ActiveValue::set(self)\n            }\n        }\n\n        #impl_not_u8\n    ))\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/typed_column.rs",
    "content": "use super::util::{\n    escape_rust_keyword, format_field_ident, is_compound_field, trim_starting_raw_identifier,\n};\nuse heck::ToUpperCamelCase;\nuse proc_macro2::{Ident, TokenStream};\nuse quote::quote;\nuse syn::{Data, Expr, Fields, Lit, spanned::Spanned};\n\n/// First is `struct TypedColumn`, second is the `const COLUMN`\npub fn expand_typed_column(data: &Data) -> syn::Result<(TokenStream, TokenStream)> {\n    let mut column_fields = Vec::new();\n    let mut column_types = Vec::new();\n    let mut column_values = Vec::new();\n\n    if let Data::Struct(item_struct) = &data {\n        if let Fields::Named(fields) = &item_struct.fields {\n            for field in &fields.named {\n                if let Some(ident) = &field.ident {\n                    let field_name = trim_starting_raw_identifier(ident);\n                    let mut field_name =\n                        Ident::new(&field_name.to_upper_camel_case(), ident.span());\n\n                    let field_type = &field.ty;\n                    let field_type = quote! { #field_type }\n                        .to_string() // e.g.: \"Option < String >\"\n                        .replace(' ', \"\"); // Remove spaces\n\n                    let mut ignore = false;\n                    let mut column_type = None;\n\n                    for attr in field.attrs.iter() {\n                        if attr.path().is_ident(\"sea_orm\") {\n                            attr.parse_nested_meta(|meta| {\n                                if meta.path.is_ident(\"column_type\") {\n                                    let lit = meta.value()?.parse()?;\n                                    if let Lit::Str(litstr) = lit {\n                                        column_type = Some(litstr.value());\n                                    } else {\n                                        return Err(\n                                            meta.error(format!(\"Invalid column_type {lit:?}\"))\n                                        );\n                                    }\n                                } else if meta.path.is_ident(\"enum_name\") {\n                                    let lit = meta.value()?.parse()?;\n                                    if let Lit::Str(litstr) = lit {\n                                        let ty: Ident = syn::parse_str(&litstr.value())?;\n                                        field_name = ty;\n                                    } else {\n                                        return Err(\n                                            meta.error(format!(\"Invalid enum_name {lit:?}\"))\n                                        );\n                                    }\n                                } else if meta.path.is_ident(\"ignore\") {\n                                    ignore = true;\n                                } else {\n                                    // Reads the value expression to advance the parse stream.\n                                    let _: Option<Expr> = meta.value().and_then(|v| v.parse()).ok();\n                                }\n\n                                Ok(())\n                            })?;\n                        }\n                    }\n\n                    if ignore {\n                        continue;\n                    }\n\n                    if is_compound_field(&field_type) {\n                        continue;\n                    }\n\n                    field_name = Ident::new(&escape_rust_keyword(field_name), ident.span());\n\n                    column_fields.push(format_field_ident(field));\n                    let wrapper = super::value_type_match::column_type_wrapper(\n                        &column_type,\n                        &field_type,\n                        field.span(),\n                    );\n                    column_types.push(if let Some(wrapper) = &wrapper {\n                        quote!(sea_orm::#wrapper<Entity>)\n                    } else {\n                        quote!(Column)\n                    });\n                    column_values.push(if let Some(wrapper) = &wrapper {\n                        quote!(sea_orm::#wrapper(Column::#field_name))\n                    } else {\n                        quote!(Column::#field_name)\n                    });\n                }\n            }\n        }\n    }\n\n    Ok((\n        quote! {\n            #[doc = \" Generated by sea-orm-macros\"]\n            pub struct TypedColumn {\n                #(\n                    #[doc = \" Generated by sea-orm-macros\"]\n                    pub #column_fields: #column_types\n                ),*\n            }\n        },\n        quote! {\n            #[doc = \" Generated by sea-orm-macros\"]\n            pub const COLUMN: TypedColumn = TypedColumn {\n                #(#column_fields: #column_values),*\n            };\n        },\n    ))\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/util.rs",
    "content": "use heck::ToUpperCamelCase;\nuse syn::{Field, Ident, Meta, MetaNameValue, punctuated::Punctuated, token::Comma};\n\n/// Remove ignored fields and compound fields\npub(crate) fn field_not_ignored(field: &Field) -> bool {\n    let field_type = &field.ty;\n    let field_type = quote::quote! { #field_type }\n        .to_string() // e.g.: \"Option < String >\"\n        .replace(' ', \"\"); // Remove spaces\n\n    if is_compound_field(&field_type) {\n        return false;\n    }\n\n    field_not_ignored_compound(field)\n}\n\n/// Remove ignored fields, compound fields okay\npub(crate) fn field_not_ignored_compound(field: &Field) -> bool {\n    for attr in field.attrs.iter() {\n        if let Some(ident) = attr.path().get_ident() {\n            if ident != \"sea_orm\" {\n                continue;\n            }\n        } else {\n            continue;\n        }\n\n        if let Ok(list) = attr.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated) {\n            for meta in list.iter() {\n                if let Meta::Path(path) = meta {\n                    if let Some(name) = path.get_ident() {\n                        if name == \"ignore\" {\n                            return false;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    true\n}\n\npub(crate) fn is_compound_field(field_type: &str) -> bool {\n    // for #[sea_orm::model]\n    ((field_type.starts_with(\"Option<\") || field_type.starts_with(\"Vec<\")) && field_type.ends_with(\"::Entity>\"))\n    // for DeriveModelEx\n    || field_type.starts_with(\"HasOne<\") || field_type.starts_with(\"HasMany<\")\n}\n\npub(crate) fn extract_compound_entity(ty: &str) -> &str {\n    if ty.starts_with(\"HasMany<\") {\n        &ty[\"HasMany<\".len()..(ty.len() - 1)]\n    } else if ty.starts_with(\"HasOne<\") {\n        &ty[\"HasOne<\".len()..(ty.len() - 1)]\n    } else if ty.starts_with(\"Option<\") {\n        &ty[\"Option<\".len()..(ty.len() - 1)]\n    } else if ty.starts_with(\"Vec<\") {\n        &ty[\"Vec<\".len()..(ty.len() - 1)]\n    } else {\n        panic!(\"Relation applied to non compound type: {ty}\")\n    }\n}\n\npub(crate) fn format_field_ident(field: &Field) -> Ident {\n    field.ident.clone().unwrap()\n}\n\npub(crate) fn trim_starting_raw_identifier<T>(string: T) -> String\nwhere\n    T: ToString,\n{\n    string\n        .to_string()\n        .trim_start_matches(RAW_IDENTIFIER)\n        .to_string()\n}\n\npub(crate) fn escape_rust_keyword<T>(string: T) -> String\nwhere\n    T: ToString,\n{\n    let string = string.to_string();\n    if RUST_KEYWORDS.iter().any(|s| s.eq(&string)) {\n        format!(\"r#{string}\")\n    } else if RUST_SPECIAL_KEYWORDS.iter().any(|s| s.eq(&string)) {\n        format!(\"{string}_\")\n    } else {\n        string\n    }\n}\n\n/// Turn a string to PascalCase while escaping all special characters in ASCII words.\n///\n/// (camel_case is used here to match naming of heck.)\n///\n/// In ActiveEnum, string_value will be PascalCased and made\n/// an identifier in {Enum}Variant.\n///\n/// However Rust only allows for XID_Start char followed by\n/// XID_Continue characters as identifiers; this causes a few\n/// problems:\n///\n/// - `string_value = \"\"` will cause a panic;\n/// - `string_value` containing only non-alphanumerics will become `\"\"`\n///   and cause the above panic;\n/// - `string_values`:\n///      - `\"A B\"`\n///      - `\"A  B\"`\n///      - `\"A_B\"`\n///      - `\"A_ B\"`\n///\n/// All shares the same identifier of `\"AB\"`;\n///\n/// This function does the PascelCase conversion with a few special escapes:\n/// - Non-Unicode Standard Annex #31 compliant characters will converted to their hex notation;\n/// - `\"_\"` into `\"0x5F\"`;\n/// - `\" \"` into `\"0x20\"`;\n/// - Empty strings will become special keyword of `\"__Empty\"`\n///\n/// Note that this does NOT address:\n///\n/// - case-sensitivity. String value \"ABC\" and \"abc\" remains\n///   conflicted after .camel_case().\n///\n/// Example Conversions:\n///\n/// ```ignore\n/// assert_eq!(camel_case_with_escaped_non_uax31(\"\"), \"__Empty\");\n/// assert_eq!(camel_case_with_escaped_non_uax31(\" \"), \"_0x20\");\n/// assert_eq!(camel_case_with_escaped_non_uax31(\"  \"), \"_0x200x20\");\n/// assert_eq!(camel_case_with_escaped_non_uax31(\"_\"), \"_0x5F\");\n/// assert_eq!(camel_case_with_escaped_non_uax31(\"foobar\"), \"Foobar\");\n/// assert_eq!(camel_case_with_escaped_non_uax31(\"foo bar\"), \"Foo0x20bar\");\n/// ```\npub(crate) fn camel_case_with_escaped_non_uax31<T>(string: T) -> String\nwhere\n    T: ToString,\n{\n    let additional_chars_to_replace: [char; 2] = ['_', ' '];\n\n    let mut rebuilt = string\n        .to_string()\n        .chars()\n        .enumerate()\n        .map(|(pos, char_)| {\n            if !additional_chars_to_replace.contains(&char_)\n                && match pos {\n                    0 => unicode_ident::is_xid_start(char_),\n                    _ => unicode_ident::is_xid_continue(char_),\n                }\n            {\n                char_.to_string()\n            } else {\n                format!(\"{:#X}\", char_ as u32)\n            }\n        })\n        .reduce(\n            // Join the \"characters\" (now strings)\n            // back together\n            |lhs, rhs| lhs + rhs.as_str(),\n        )\n        .map_or(\n            // if string_value is \"\"\n            // Make sure the default does NOT go through camel_case,\n            // as the __ will be removed! The underscores are\n            // what guarantees this being special case avoiding\n            // all potential conflicts.\n            String::from(\"__Empty\"),\n            |s| s.to_upper_camel_case(),\n        );\n\n    if rebuilt\n        .chars()\n        .next()\n        .map(char::is_numeric)\n        .unwrap_or(false)\n    {\n        rebuilt = String::from(\"_\") + &rebuilt;\n    }\n\n    rebuilt\n}\n\npub(crate) const RAW_IDENTIFIER: &str = \"r#\";\n\npub(crate) const RUST_KEYWORDS: [&str; 49] = [\n    \"as\", \"async\", \"await\", \"break\", \"const\", \"continue\", \"dyn\", \"else\", \"enum\", \"extern\", \"false\",\n    \"fn\", \"for\", \"if\", \"impl\", \"in\", \"let\", \"loop\", \"match\", \"mod\", \"move\", \"mut\", \"pub\", \"ref\",\n    \"return\", \"static\", \"struct\", \"super\", \"trait\", \"true\", \"type\", \"union\", \"unsafe\", \"use\",\n    \"where\", \"while\", \"abstract\", \"become\", \"box\", \"do\", \"final\", \"macro\", \"override\", \"priv\",\n    \"try\", \"typeof\", \"unsized\", \"virtual\", \"yield\",\n];\n\npub(crate) const RUST_SPECIAL_KEYWORDS: [&str; 3] = [\"crate\", \"Self\", \"self\"];\n\npub(crate) trait GetMeta {\n    fn exists(&self, k: &str) -> bool;\n    fn get_as_kv(&self, k: &str) -> Option<String>;\n    fn get_as_kv_with_ident(&self) -> Option<(Ident, String)>;\n}\n\nimpl GetMeta for Meta {\n    fn exists(&self, key: &str) -> bool {\n        let Meta::Path(path) = self else {\n            return false;\n        };\n        path.is_ident(key)\n    }\n\n    fn get_as_kv(&self, key: &str) -> Option<String> {\n        let Meta::NameValue(MetaNameValue {\n            path,\n            value: syn::Expr::Lit(exprlit),\n            ..\n        }) = self\n        else {\n            return None;\n        };\n\n        let syn::Lit::Str(litstr) = &exprlit.lit else {\n            return None;\n        };\n\n        if path.is_ident(key) {\n            Some(litstr.value())\n        } else {\n            None\n        }\n    }\n\n    fn get_as_kv_with_ident(&self) -> Option<(Ident, String)> {\n        let Meta::NameValue(MetaNameValue {\n            path,\n            value: syn::Expr::Lit(exprlit),\n            ..\n        }) = self\n        else {\n            return None;\n        };\n\n        let syn::Lit::Str(litstr) = &exprlit.lit else {\n            return None;\n        };\n\n        path.get_ident()\n            .map(|ident| (ident.clone(), litstr.value()))\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_non_uax31_escape() {\n        // Test empty string\n        assert_eq!(camel_case_with_escaped_non_uax31(\"\"), \"__Empty\");\n\n        // Test additional_chars_to_replace (to_camel_case related characters)\n        assert_eq!(camel_case_with_escaped_non_uax31(\" \"), \"_0x20\");\n\n        // Test additional_chars_to_replace (multiples. ensure distinct from single)\n        assert_eq!(camel_case_with_escaped_non_uax31(\"  \"), \"_0x200x20\");\n\n        // Test additional_chars_to_replace (udnerscores)\n        assert_eq!(camel_case_with_escaped_non_uax31(\"_\"), \"_0x5F\");\n\n        // Test typical use case\n        assert_eq!(camel_case_with_escaped_non_uax31(\"foobar\"), \"Foobar\");\n\n        // Test spaced words distinct from non-spaced\n        assert_eq!(camel_case_with_escaped_non_uax31(\"foo bar\"), \"Foo0x20bar\");\n\n        // Test underscored words distinct from non-spaced and spaced\n        assert_eq!(camel_case_with_escaped_non_uax31(\"foo_bar\"), \"Foo0x5Fbar\");\n\n        // Test leading numeric characters\n        assert_eq!(camel_case_with_escaped_non_uax31(\"1\"), \"_0x31\");\n\n        // Test escaping also works on full string following lead numeric character\n        // This was previously a fail condition.\n        assert_eq!(\n            camel_case_with_escaped_non_uax31(\"1 2 3\"),\n            \"_0x310x2020x203\"\n        );\n\n        assert_eq!(camel_case_with_escaped_non_uax31(\"씨오알엠\"), \"씨오알엠\");\n\n        assert_eq!(camel_case_with_escaped_non_uax31(\"A_B\"), \"A0x5Fb\");\n\n        assert_eq!(camel_case_with_escaped_non_uax31(\"AB\"), \"Ab\");\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/value_type.rs",
    "content": "use super::attributes::value_type_attr;\nuse super::value_type_match::{array_type_expr, can_try_from_u64, column_type_expr};\nuse proc_macro2::TokenStream;\nuse quote::quote;\nuse syn::{Field, Ident, Type, punctuated::Punctuated, spanned::Spanned, token::Comma};\n\n#[allow(clippy::large_enum_variant)]\nenum DeriveValueType {\n    TupleStruct(DeriveValueTypeStruct),\n    StringLike(DeriveValueTypeString),\n}\n\nstruct DeriveValueTypeStruct {\n    name: syn::Ident,\n    ty: Type,\n    column_type: TokenStream,\n    array_type: TokenStream,\n    can_try_from_u64: bool,\n}\n\n#[derive(Default)]\nstruct DeriveValueTypeStructAttrs {\n    column_type: Option<TokenStream>,\n    array_type: Option<TokenStream>,\n    try_from_u64: bool,\n}\n\nimpl TryFrom<value_type_attr::SeaOrm> for DeriveValueTypeStructAttrs {\n    type Error = syn::Error;\n\n    fn try_from(attrs: value_type_attr::SeaOrm) -> syn::Result<Self> {\n        Ok(Self {\n            column_type: attrs.column_type.map(|s| s.parse()).transpose()?,\n            array_type: attrs.array_type.map(|s| s.parse()).transpose()?,\n            try_from_u64: attrs.try_from_u64.is_some(),\n        })\n    }\n}\n\nstruct DeriveValueTypeString {\n    name: syn::Ident,\n    from_str: Option<TokenStream>,\n    to_str: Option<TokenStream>,\n    column_type: Option<TokenStream>,\n}\n\nstruct DeriveValueTypeStringAttrs {\n    from_str: Option<TokenStream>,\n    to_str: Option<TokenStream>,\n    column_type: Option<TokenStream>,\n}\n\nimpl TryFrom<value_type_attr::SeaOrm> for DeriveValueTypeStringAttrs {\n    type Error = syn::Error;\n\n    fn try_from(attrs: value_type_attr::SeaOrm) -> syn::Result<Self> {\n        let value_type = attrs.value_type.map(|s| s.value());\n        assert_eq!(value_type.as_deref(), Some(\"String\"));\n\n        Ok(Self {\n            from_str: attrs.from_str.map(|s| s.parse()).transpose()?,\n            to_str: attrs.to_str.map(|s| s.parse()).transpose()?,\n            column_type: attrs.column_type.map(|s| s.parse()).transpose()?,\n        })\n    }\n}\n\nimpl DeriveValueType {\n    fn new(input: syn::DeriveInput) -> syn::Result<Self> {\n        // Produce an error if the macro attributes are malformed\n        let value_type_attr = value_type_attr::SeaOrm::try_from_attributes(&input.attrs)?;\n\n        // If some attributes were set, inspect the optional `value_type`\n        let value_type = if let Some(ref value_type_attr) = value_type_attr {\n            value_type_attr.value_type.as_ref().map(|s| s.value())\n        } else {\n            None\n        };\n\n        // If either `value_type` is unset, or no attributes were passed, assume\n        // `DeriveValueTypeStruct`. If no attrs were set, use default values.\n        if value_type.is_none() || value_type_attr.is_none() {\n            let value_type_attr = if let Some(value_type_attr) = value_type_attr {\n                value_type_attr.try_into()?\n            } else {\n                DeriveValueTypeStructAttrs::default()\n            };\n\n            match input.data {\n                syn::Data::Struct(syn::DataStruct {\n                    fields: syn::Fields::Unnamed(syn::FieldsUnnamed { unnamed, .. }),\n                    ..\n                }) => {\n                    return DeriveValueTypeStruct::new(input.ident, value_type_attr, unnamed)\n                        .map(Self::TupleStruct);\n                }\n                _ => {\n                    return Err(syn::Error::new_spanned(\n                        input,\n                        \"You can only derive `DeriveValueType` on a struct with a single unnamed field, unless `value_type` is set.\",\n                    ));\n                }\n            }\n        }\n\n        let value_type_attr = value_type_attr.unwrap();\n        let value_type = value_type.unwrap();\n\n        match value_type.as_str() {\n            \"String\" => DeriveValueTypeString::new(input.ident, value_type_attr.try_into()?)\n                .map(Self::StringLike),\n            _ => Err(syn::Error::new_spanned(\n                input.ident,\n                r#\"Please specify value_type = \"String\"\"#,\n            )),\n        }\n    }\n\n    fn expand(&self) -> syn::Result<TokenStream> {\n        Ok(match self {\n            Self::TupleStruct(s) => s.impl_value_type(),\n            Self::StringLike(s) => s.impl_value_type(),\n        })\n    }\n}\n\nimpl DeriveValueTypeStruct {\n    fn new(\n        name: Ident,\n        attrs: DeriveValueTypeStructAttrs,\n        fields: Punctuated<Field, Comma>,\n    ) -> syn::Result<Self> {\n        let Some(field) = fields.into_iter().next() else {\n            return Err(syn::Error::new_spanned(\n                name,\n                \"You can only derive `DeriveValueType` on tuple struct with 1 inner value\",\n            ));\n        };\n\n        let field_span = field.span();\n        let ty = field.ty;\n        let field_type = quote! { #ty }\n            .to_string() //E.g.: \"Option < String >\"\n            .replace(' ', \"\"); // Remove spaces\n        let field_type = if field_type.starts_with(\"Option<\") {\n            &field_type[7..(field_type.len() - 1)] // Extract `T` out of `Option<T>`\n        } else {\n            field_type.as_str()\n        };\n\n        let column_type = column_type_expr(attrs.column_type, field_type, field_span);\n        let array_type = array_type_expr(attrs.array_type, field_type, field_span);\n        let can_try_from_u64 = attrs.try_from_u64 || can_try_from_u64(field_type);\n\n        Ok(Self {\n            name,\n            ty,\n            column_type,\n            array_type,\n            can_try_from_u64,\n        })\n    }\n\n    fn impl_value_type(&self) -> TokenStream {\n        let name = &self.name;\n        let field_type = &self.ty;\n        let column_type = &self.column_type;\n        let array_type = &self.array_type;\n\n        let try_from_u64_impl = if self.can_try_from_u64 {\n            quote!(\n                #[automatically_derived]\n                impl sea_orm::TryFromU64 for #name {\n                    fn try_from_u64(n: u64) -> Result<Self, sea_orm::DbErr> {\n                        use std::convert::TryInto;\n                        Ok(Self(n.try_into().map_err(|e| sea_orm::DbErr::TryIntoErr {\n                            from: stringify!(u64),\n                            into: stringify!(#name),\n                            source: std::sync::Arc::new(e),\n                        })?))\n                    }\n                }\n            )\n        } else {\n            quote!()\n        };\n\n        let impl_not_u8 = if cfg!(feature = \"postgres-array\") {\n            quote!(\n                #[automatically_derived]\n                impl sea_orm::sea_query::postgres_array::NotU8 for #name {}\n            )\n        } else {\n            quote!()\n        };\n\n        quote!(\n            #[automatically_derived]\n            impl std::convert::From<#name> for sea_orm::Value {\n                fn from(source: #name) -> Self {\n                    source.0.into()\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::TryGetable for #name {\n                fn try_get_by<I: sea_orm::ColIdx>(res: &sea_orm::QueryResult, idx: I)\n                    -> std::result::Result<Self, sea_orm::TryGetError> {\n                    <#field_type as sea_orm::TryGetable>::try_get_by(res, idx).map(|v| #name(v))\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::sea_query::ValueType for #name {\n                fn try_from(v: sea_orm::Value) -> std::result::Result<Self, sea_orm::sea_query::ValueTypeErr> {\n                    <#field_type as sea_orm::sea_query::ValueType>::try_from(v).map(|v| #name(v))\n                }\n\n                fn type_name() -> std::string::String {\n                    stringify!(#name).to_owned()\n                }\n\n                fn array_type() -> sea_orm::sea_query::ArrayType {\n                    #array_type\n                }\n\n                fn column_type() -> sea_orm::sea_query::ColumnType {\n                    #column_type\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::sea_query::Nullable for #name {\n                fn null() -> sea_orm::Value {\n                    <#field_type as sea_orm::sea_query::Nullable>::null()\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::IntoActiveValue<#name> for #name {\n                fn into_active_value(self) -> sea_orm::ActiveValue<#name> {\n                    sea_orm::ActiveValue::Set(self)\n                }\n            }\n\n            #try_from_u64_impl\n\n            #impl_not_u8\n        )\n    }\n}\n\nimpl DeriveValueTypeString {\n    fn new(name: Ident, attrs: DeriveValueTypeStringAttrs) -> syn::Result<Self> {\n        Ok(Self {\n            name,\n            from_str: attrs.from_str,\n            to_str: attrs.to_str,\n            column_type: attrs.column_type,\n        })\n    }\n\n    fn impl_value_type(&self) -> TokenStream {\n        let name = &self.name;\n        let from_str = match &self.from_str {\n            Some(from_str) => from_str,\n            None => &quote!(std::str::FromStr::from_str),\n        };\n        let to_str = match &self.to_str {\n            Some(to_str) => to_str,\n            None => &quote!(std::string::ToString::to_string),\n        };\n        let column_type = match &self.column_type {\n            Some(column_type) => column_type,\n            None => &quote!(String(sea_orm::sea_query::StringLen::None)),\n        };\n\n        let impl_not_u8 = if cfg!(feature = \"postgres-array\") {\n            quote!(\n                #[automatically_derived]\n                impl sea_orm::sea_query::postgres_array::NotU8 for #name {}\n            )\n        } else {\n            quote!()\n        };\n\n        quote!(\n            #[automatically_derived]\n            impl std::convert::From<#name> for sea_orm::Value {\n                fn from(source: #name) -> Self {\n                    #to_str(&source).into()\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::TryGetable for #name {\n                fn try_get_by<I: sea_orm::ColIdx>(res: &sea_orm::QueryResult, idx: I)\n                    -> std::result::Result<Self, sea_orm::TryGetError> {\n                    let string = String::try_get_by(res, idx)?;\n                    #from_str(&string).map_err(|err| {\n                        sea_orm::TryGetError::DbErr(sea_orm::DbErr::TryIntoErr {\n                            from: \"String\",\n                            into: stringify!(#name),\n                            source: std::sync::Arc::new(err),\n                        })\n                    })\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::sea_query::ValueType for #name {\n                fn try_from(v: sea_orm::Value) -> std::result::Result<Self, sea_orm::sea_query::ValueTypeErr> {\n                    let string = <String as sea_orm::sea_query::ValueType>::try_from(v)?;\n                    #from_str(&string).map_err(|_| sea_orm::sea_query::ValueTypeErr)\n                }\n\n                fn type_name() -> std::string::String {\n                    stringify!(#name).to_owned()\n                }\n\n                fn array_type() -> sea_orm::sea_query::ArrayType {\n                    sea_orm::sea_query::ArrayType::String\n                }\n\n                fn column_type() -> sea_orm::sea_query::ColumnType {\n                    sea_orm::sea_query::ColumnType::#column_type\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::sea_query::Nullable for #name {\n                fn null() -> sea_orm::Value {\n                    sea_orm::Value::String(None)\n                }\n            }\n\n            #[automatically_derived]\n            impl sea_orm::IntoActiveValue<#name> for #name {\n                fn into_active_value(self) -> sea_orm::ActiveValue<#name> {\n                    sea_orm::ActiveValue::Set(self)\n                }\n            }\n\n            #impl_not_u8\n        )\n    }\n}\n\npub fn expand_derive_value_type(input: syn::DeriveInput) -> syn::Result<TokenStream> {\n    DeriveValueType::new(input)?.expand()\n}\n"
  },
  {
    "path": "sea-orm-macros/src/derives/value_type_match.rs",
    "content": "use proc_macro2::{Span, TokenStream};\nuse quote::quote_spanned;\nuse syn::{Ident, LitStr, Type};\n\npub fn column_type_expr(\n    column_type: Option<TokenStream>,\n    field_type: &str,\n    field_span: Span,\n) -> TokenStream {\n    match column_type {\n        Some(column_type) => {\n            quote_spanned! { field_span => sea_orm::prelude::ColumnType::#column_type }\n        }\n        None => {\n            let ty: Type = LitStr::new(field_type, field_span)\n                .parse()\n                .expect(\"field type error\");\n            quote_spanned! { field_span => <#ty as sea_orm::sea_query::ValueType>::column_type() }\n        }\n    }\n}\n\npub fn column_type_wrapper(\n    column_type: &Option<String>,\n    field_type: &str,\n    field_span: Span,\n) -> Option<Ident> {\n    let nullable = trim_option(field_type).0;\n\n    if let Some(column_type) = column_type {\n        let column_type = if let Some((prefix, _)) = column_type.split_once('(') {\n            prefix\n        } else {\n            column_type\n        };\n        let value_type = match column_type {\n            \"String\" | \"Text\" => {\n                if nullable {\n                    Some(\"StringColumnNullable\")\n                } else {\n                    Some(\"StringColumn\")\n                }\n            }\n            \"Blob\" | \"Binary\" | \"VarBinary\" => Some(\"BytesColumn\"),\n            \"TinyInteger\" | \"SmallInteger\" | \"Integer\" | \"BigInteger\" | \"TinyUnsigned\"\n            | \"SmallUnsigned\" | \"Unsigned\" | \"BigUnsigned\" | \"Float\" | \"Double\" | \"Decimal\"\n            | \"Money\" => {\n                if nullable {\n                    Some(\"NumericColumnNullable\")\n                } else {\n                    Some(\"NumericColumn\")\n                }\n            }\n            \"DateTime\" | \"Timestamp\" | \"TimestampWithTimeZone\" => Some(\"DateTimeLikeColumn\"),\n            \"Time\" => Some(\"TimeLikeColumn\"),\n            \"Date\" => Some(\"DateLikeColumn\"),\n            \"Boolean\" => Some(\"BoolColumn\"),\n            \"Json\" | \"JsonBinary\" => Some(\"JsonColumn\"),\n            \"Uuid\" => Some(\"UuidColumn\"),\n            \"Array\" => Some(\"GenericArrayColumn\"),\n            _ => None,\n        }\n        .map(|ty| Ident::new(ty, field_span));\n\n        if value_type.is_some() {\n            return value_type;\n        }\n    }\n\n    match trim_option(field_type).1 {\n        \"bool\" => Some(\"BoolColumn\"),\n        \"String\" => {\n            if nullable {\n                Some(\"StringColumnNullable\")\n            } else {\n                Some(\"StringColumn\")\n            }\n        }\n        \"Vec<u8>\" => Some(\"BytesColumn\"),\n        \"Uuid\" => Some(\"UuidColumn\"),\n        \"IpNetwork\" => Some(\"IpNetworkColumn\"),\n        \"Json\" | \"serde_json::Value\" => Some(\"JsonColumn\"),\n        \"TextUuid\" => Some(\"TextUuidColumn\"),\n        field_type => {\n            if is_numeric_column(field_type) || field_type.contains(\"UnixTimestamp\") {\n                if nullable {\n                    Some(\"NumericColumnNullable\")\n                } else {\n                    Some(\"NumericColumn\")\n                }\n            } else if field_type.starts_with(\"Vec<\") {\n                let field_type = &field_type[\"Vec<\".len()..field_type.len() - 1];\n                if is_numeric_column(field_type) {\n                    Some(\"NumericArrayColumn\")\n                } else {\n                    Some(\"GenericArrayColumn\")\n                }\n            } else if field_type.contains(\"DateTime\") || field_type.contains(\"Timestamp\") {\n                Some(\"DateTimeLikeColumn\")\n            } else if field_type.contains(\"Date\") {\n                Some(\"DateLikeColumn\")\n            } else if field_type.contains(\"Time\") {\n                Some(\"TimeLikeColumn\")\n            } else {\n                None\n            }\n        }\n    }\n    .map(|ty| Ident::new(ty, field_span))\n}\n\nfn is_numeric_column(ty: &str) -> bool {\n    matches!(\n        ty,\n        \"i8\" | \"i16\"\n            | \"i32\"\n            | \"i64\"\n            | \"u8\"\n            | \"u16\"\n            | \"u32\"\n            | \"u64\"\n            | \"f32\"\n            | \"f64\"\n            | \"Decimal\"\n            | \"BigDecimal\"\n    )\n}\n\npub fn array_type_expr(\n    array_type: Option<TokenStream>,\n    field_type: &str,\n    field_span: Span,\n) -> TokenStream {\n    match array_type {\n        Some(array_type) => {\n            quote_spanned! { field_span => sea_orm::sea_query::ArrayType::#array_type }\n        }\n        None => {\n            let ty: Type = LitStr::new(field_type, field_span)\n                .parse()\n                .expect(\"field type error\");\n            quote_spanned! { field_span => <#ty as sea_orm::sea_query::ValueType>::array_type() }\n        }\n    }\n}\n\npub fn can_try_from_u64(field_type: &str) -> bool {\n    matches!(\n        field_type,\n        \"i8\" | \"i16\" | \"i32\" | \"i64\" | \"u8\" | \"u16\" | \"u32\" | \"u64\"\n    )\n}\n\n/// Return whether it is nullable\nfn trim_option(s: &str) -> (bool, &str) {\n    if s.starts_with(\"Option<\") {\n        (true, &s[\"Option<\".len()..s.len() - 1])\n    } else {\n        (false, s)\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/lib.rs",
    "content": "extern crate proc_macro;\n\nuse proc_macro::TokenStream;\n\nuse syn::{DeriveInput, Error, parse_macro_input};\n\n#[cfg(feature = \"derive\")]\nmod derives;\n\n#[cfg(feature = \"strum\")]\nmod strum;\n\nmod raw_sql;\n\n/// Create an Entity\n///\n/// ### Usage\n///\n/// ```\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n/// pub struct Entity;\n///\n/// # impl EntityName for Entity {\n/// #     fn table_name(&self) -> &'static str {\n/// #         \"cake\"\n/// #     }\n/// # }\n/// #\n/// # #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\n/// # pub struct Model {\n/// #     pub id: i32,\n/// #     pub name: String,\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n/// # pub enum Column {\n/// #     Id,\n/// #     Name,\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n/// # pub enum PrimaryKey {\n/// #     Id,\n/// # }\n/// #\n/// # impl PrimaryKeyTrait for PrimaryKey {\n/// #     type ValueType = i32;\n/// #\n/// #     fn auto_increment() -> bool {\n/// #         true\n/// #     }\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter)]\n/// # pub enum Relation {}\n/// #\n/// # impl ColumnTrait for Column {\n/// #     type EntityName = Entity;\n/// #\n/// #     fn def(&self) -> ColumnDef {\n/// #         match self {\n/// #             Self::Id => ColumnType::Integer.def(),\n/// #             Self::Name => ColumnType::String(StringLen::None).def(),\n/// #         }\n/// #     }\n/// # }\n/// #\n/// # impl RelationTrait for Relation {\n/// #     fn def(&self) -> RelationDef {\n/// #         panic!(\"No Relation\");\n/// #     }\n/// # }\n/// #\n/// # impl ActiveModelBehavior for ActiveModel {}\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveEntity, attributes(sea_orm))]\npub fn derive_entity(input: TokenStream) -> TokenStream {\n    let input = parse_macro_input!(input as DeriveInput);\n    derives::expand_derive_entity(input)\n        .unwrap_or_else(Error::into_compile_error)\n        .into()\n}\n\n/// This derive macro is the 'almighty' macro which automatically generates\n/// Entity, Column, and PrimaryKey from a given Model.\n///\n/// ### Usage\n///\n/// ```\n/// use sea_orm::entity::prelude::*;\n/// use serde::{Deserialize, Serialize};\n///\n/// #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize)]\n/// #[sea_orm(table_name = \"posts\")]\n/// pub struct Model {\n///     #[sea_orm(primary_key)]\n///     pub id: i32,\n///     pub title: String,\n///     #[sea_orm(column_type = \"Text\")]\n///     pub text: String,\n/// }\n///\n/// # #[derive(Copy, Clone, Debug, EnumIter)]\n/// # pub enum Relation {}\n/// #\n/// # impl RelationTrait for Relation {\n/// #     fn def(&self) -> RelationDef {\n/// #         panic!(\"No Relation\");\n/// #     }\n/// # }\n/// #\n/// # impl ActiveModelBehavior for ActiveModel {}\n/// ```\n///\n/// Entity should always have a primary key.\n/// Or, it will result in a compile error.\n/// See <https://github.com/SeaQL/sea-orm/issues/485> for details.\n///\n/// ```compile_fail\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #[sea_orm(table_name = \"posts\")]\n/// pub struct Model {\n///     pub title: String,\n///     #[sea_orm(column_type = \"Text\")]\n///     pub text: String,\n/// }\n///\n/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n/// # pub enum Relation {}\n/// #\n/// # impl ActiveModelBehavior for ActiveModel {}\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveEntityModel, attributes(sea_orm, seaography))]\npub fn derive_entity_model(input: TokenStream) -> TokenStream {\n    let DeriveInput {\n        ident, data, attrs, ..\n    } = parse_macro_input!(input as DeriveInput);\n\n    if ident != \"Model\" {\n        panic!(\"Struct name must be Model\");\n    }\n\n    let mut ts: TokenStream = derives::expand_derive_entity_model(&data, &attrs)\n        .unwrap_or_else(Error::into_compile_error)\n        .into();\n\n    ts.extend::<TokenStream>(\n        derives::expand_derive_model(&ident, &data, &attrs)\n            .unwrap_or_else(Error::into_compile_error)\n            .into(),\n    );\n\n    ts.extend::<TokenStream>(\n        derives::expand_derive_active_model(&ident, &data)\n            .unwrap_or_else(Error::into_compile_error)\n            .into(),\n    );\n\n    ts\n}\n\n/// Derive a complex model with relational fields\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveModelEx, attributes(sea_orm, seaography))]\npub fn derive_model_ex(input: TokenStream) -> TokenStream {\n    let DeriveInput {\n        ident, data, attrs, ..\n    } = parse_macro_input!(input as DeriveInput);\n\n    if ident != \"ModelEx\" {\n        panic!(\"Struct name must be ModelEx\");\n    }\n\n    derives::expand_derive_model_ex(ident, data, attrs)\n        .unwrap_or_else(Error::into_compile_error)\n        .into()\n}\n\n/// Derive a complex active model with relational fields\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveActiveModelEx, attributes(sea_orm, seaography))]\npub fn derive_active_model_ex(input: TokenStream) -> TokenStream {\n    let DeriveInput {\n        ident, data, attrs, ..\n    } = parse_macro_input!(input as DeriveInput);\n\n    if ident != \"ModelEx\" {\n        panic!(\"Struct name must be ModelEx\");\n    }\n\n    derives::expand_derive_active_model_ex(&ident, &data, &attrs)\n        .unwrap_or_else(Error::into_compile_error)\n        .into()\n}\n\n/// The DerivePrimaryKey derive macro will implement [PrimaryKeyToColumn]\n/// for PrimaryKey which defines tedious mappings between primary keys and columns.\n/// The [EnumIter] is also derived, allowing iteration over all enum variants.\n///\n/// ### Usage\n///\n/// ```\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n/// pub enum PrimaryKey {\n///     CakeId,\n///     FillingId,\n/// }\n///\n/// # #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n/// # pub struct Entity;\n/// #\n/// # impl EntityName for Entity {\n/// #     fn table_name(&self) -> &'static str {\n/// #         \"cake\"\n/// #     }\n/// # }\n/// #\n/// # #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\n/// # pub struct Model {\n/// #     pub cake_id: i32,\n/// #     pub filling_id: i32,\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n/// # pub enum Column {\n/// #     CakeId,\n/// #     FillingId,\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter)]\n/// # pub enum Relation {}\n/// #\n/// # impl ColumnTrait for Column {\n/// #     type EntityName = Entity;\n/// #\n/// #     fn def(&self) -> ColumnDef {\n/// #         match self {\n/// #             Self::CakeId => ColumnType::Integer.def(),\n/// #             Self::FillingId => ColumnType::Integer.def(),\n/// #         }\n/// #     }\n/// # }\n/// #\n/// # impl PrimaryKeyTrait for PrimaryKey {\n/// #     type ValueType = (i32, i32);\n/// #\n/// #     fn auto_increment() -> bool {\n/// #         false\n/// #     }\n/// # }\n/// #\n/// # impl RelationTrait for Relation {\n/// #     fn def(&self) -> RelationDef {\n/// #         panic!(\"No Relation\");\n/// #     }\n/// # }\n/// #\n/// # impl ActiveModelBehavior for ActiveModel {}\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DerivePrimaryKey, attributes(sea_orm))]\npub fn derive_primary_key(input: TokenStream) -> TokenStream {\n    let DeriveInput { ident, data, .. } = parse_macro_input!(input);\n\n    match derives::expand_derive_primary_key(&ident, &data) {\n        Ok(ts) => ts.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n/// The DeriveColumn derive macro will implement [ColumnTrait] for Columns.\n/// It defines the identifier of each column by implementing Iden and IdenStatic.\n/// The EnumIter is also derived, allowing iteration over all enum variants.\n///\n/// ### Usage\n///\n/// ```\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n/// pub enum Column {\n///     CakeId,\n///     FillingId,\n/// }\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveColumn, attributes(sea_orm))]\npub fn derive_column(input: TokenStream) -> TokenStream {\n    let DeriveInput { ident, data, .. } = parse_macro_input!(input);\n\n    match derives::expand_derive_column(&ident, &data) {\n        Ok(ts) => ts.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n/// The DeriveModel derive macro will implement ModelTrait for Model,\n/// which provides setters and getters for all attributes in the mod\n/// It also implements FromQueryResult to convert a query result into the corresponding Model.\n///\n/// ### Usage\n///\n/// ```\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\n/// pub struct Model {\n///     pub id: i32,\n///     pub name: String,\n/// }\n///\n/// # #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n/// # pub struct Entity;\n/// #\n/// # impl EntityName for Entity {\n/// #     fn table_name(&self) -> &'static str {\n/// #         \"cake\"\n/// #     }\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n/// # pub enum Column {\n/// #     Id,\n/// #     Name,\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n/// # pub enum PrimaryKey {\n/// #     Id,\n/// # }\n/// #\n/// # impl PrimaryKeyTrait for PrimaryKey {\n/// #     type ValueType = i32;\n/// #\n/// #     fn auto_increment() -> bool {\n/// #         true\n/// #     }\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter)]\n/// # pub enum Relation {}\n/// #\n/// # impl ColumnTrait for Column {\n/// #     type EntityName = Entity;\n/// #\n/// #     fn def(&self) -> ColumnDef {\n/// #         match self {\n/// #             Self::Id => ColumnType::Integer.def(),\n/// #             Self::Name => ColumnType::String(StringLen::None).def(),\n/// #         }\n/// #     }\n/// # }\n/// #\n/// # impl RelationTrait for Relation {\n/// #     fn def(&self) -> RelationDef {\n/// #         panic!(\"No Relation\");\n/// #     }\n/// # }\n/// #\n/// # impl ActiveModelBehavior for ActiveModel {}\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveModel, attributes(sea_orm))]\npub fn derive_model(input: TokenStream) -> TokenStream {\n    let DeriveInput {\n        ident, data, attrs, ..\n    } = parse_macro_input!(input as DeriveInput);\n\n    derives::expand_derive_model(&ident, &data, &attrs)\n        .unwrap_or_else(Error::into_compile_error)\n        .into()\n}\n\n/// The DeriveActiveModel derive macro will implement ActiveModelTrait for ActiveModel\n/// which provides setters and getters for all active values in the active model.\n///\n/// ### Usage\n///\n/// ```\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\n/// pub struct Model {\n///     pub id: i32,\n///     pub name: String,\n/// }\n///\n/// # #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n/// # pub struct Entity;\n/// #\n/// # impl EntityName for Entity {\n/// #     fn table_name(&self) -> &'static str {\n/// #         \"cake\"\n/// #     }\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n/// # pub enum Column {\n/// #     Id,\n/// #     Name,\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n/// # pub enum PrimaryKey {\n/// #     Id,\n/// # }\n/// #\n/// # impl PrimaryKeyTrait for PrimaryKey {\n/// #     type ValueType = i32;\n/// #\n/// #     fn auto_increment() -> bool {\n/// #         true\n/// #     }\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter)]\n/// # pub enum Relation {}\n/// #\n/// # impl ColumnTrait for Column {\n/// #     type EntityName = Entity;\n/// #\n/// #     fn def(&self) -> ColumnDef {\n/// #         match self {\n/// #             Self::Id => ColumnType::Integer.def(),\n/// #             Self::Name => ColumnType::String(StringLen::None).def(),\n/// #         }\n/// #     }\n/// # }\n/// #\n/// # impl RelationTrait for Relation {\n/// #     fn def(&self) -> RelationDef {\n/// #         panic!(\"No Relation\");\n/// #     }\n/// # }\n/// #\n/// # impl ActiveModelBehavior for ActiveModel {}\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveActiveModel, attributes(sea_orm))]\npub fn derive_active_model(input: TokenStream) -> TokenStream {\n    let DeriveInput { ident, data, .. } = parse_macro_input!(input);\n\n    match derives::expand_derive_active_model(&ident, &data) {\n        Ok(ts) => ts.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n/// Will implement [`IntoActiveModel`] for a struct, allowing conversion into an ActiveModel.\n/// This is useful for \"form\" or \"input\" structs (like from API requests) that turn into\n/// an entity's ActiveModel but may omit some fields or provide optional values with defaults.\n///\n/// ## Usage:\n///\n/// ```rust\n/// # mod fruit {\n/// #     use sea_orm::entity::prelude::*;\n/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #     #[sea_orm(table_name = \"fruit\")]\n/// #     pub struct Model {\n/// #         #[sea_orm(primary_key)]\n/// #         pub id: i32,\n/// #         pub name: String,\n/// #         pub cake_id: Option<i32>,\n/// #     }\n/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n/// #     pub enum Relation {}\n/// #     impl ActiveModelBehavior for ActiveModel {}\n/// # }\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(DeriveIntoActiveModel)]\n/// #[sea_orm(active_model = \"fruit::ActiveModel\")]\n/// struct NewFruit {\n///     name: String,\n///     // `id` and `cake_id` are omitted - they become `NotSet`\n/// }\n/// ```\n///\n/// ## `set(...)` - always set absent ActiveModel fields\n///\n/// ```rust\n/// # mod fruit {\n/// #     use sea_orm::entity::prelude::*;\n/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #     #[sea_orm(table_name = \"fruit\")]\n/// #     pub struct Model {\n/// #         #[sea_orm(primary_key)]\n/// #         pub id: i32,\n/// #         pub name: String,\n/// #         pub cake_id: Option<i32>,\n/// #     }\n/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n/// #     pub enum Relation {}\n/// #     impl ActiveModelBehavior for ActiveModel {}\n/// # }\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(DeriveIntoActiveModel)]\n/// #[sea_orm(active_model = \"fruit::ActiveModel\", set(cake_id = \"None\"))]\n/// struct NewFruit {\n///     name: String,\n///     // `cake_id` is not on the struct, but will always be `Set(None)`\n/// }\n/// ```\n///\n/// ## `default = \"expr\"` - fallback for `Option<T>` struct fields\n///\n/// ```rust\n/// # mod fruit {\n/// #     use sea_orm::entity::prelude::*;\n/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #     #[sea_orm(table_name = \"fruit\")]\n/// #     pub struct Model {\n/// #         #[sea_orm(primary_key)]\n/// #         pub id: i32,\n/// #         pub name: String,\n/// #         pub cake_id: Option<i32>,\n/// #     }\n/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n/// #     pub enum Relation {}\n/// #     impl ActiveModelBehavior for ActiveModel {}\n/// # }\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(DeriveIntoActiveModel)]\n/// #[sea_orm(active_model = \"fruit::ActiveModel\")]\n/// struct UpdateFruit {\n///     /// `Some(\"Apple\")` -> `Set(\"Apple\")`, `None` ->`Set(\"Unnamed\")`\n///     #[sea_orm(default = \"String::from(\\\"Unnamed\\\")\")]\n///     name: Option<String>,\n/// }\n/// ```\n///\n/// ## Combining `set(...)`, `default`, `ignore`, and `exhaustive`\n///\n/// ```rust\n/// # mod fruit {\n/// #     use sea_orm::entity::prelude::*;\n/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #     #[sea_orm(table_name = \"fruit\")]\n/// #     pub struct Model {\n/// #         #[sea_orm(primary_key)]\n/// #         pub id: i32,\n/// #         pub name: String,\n/// #         pub cake_id: Option<i32>,\n/// #     }\n/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n/// #     pub enum Relation {}\n/// #     impl ActiveModelBehavior for ActiveModel {}\n/// # }\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(DeriveIntoActiveModel)]\n/// #[sea_orm(active_model = \"fruit::ActiveModel\", exhaustive, set(cake_id = \"None\"))]\n/// struct NewFruit {\n///     id: i32,\n///     #[sea_orm(default = \"String::from(\\\"Unnamed\\\")\")]\n///     name: Option<String>,\n/// }\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveIntoActiveModel, attributes(sea_orm))]\npub fn derive_into_active_model(input: TokenStream) -> TokenStream {\n    let input = parse_macro_input!(input as DeriveInput);\n    derives::expand_into_active_model(input)\n        .unwrap_or_else(Error::into_compile_error)\n        .into()\n}\n\n/// Models that a user can override\n///\n/// ### Usage\n///\n/// ```\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(\n///     Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, DeriveActiveModelBehavior,\n/// )]\n/// pub struct Model {\n///     pub id: i32,\n///     pub name: String,\n/// }\n///\n/// # #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n/// # pub struct Entity;\n/// #\n/// # impl EntityName for Entity {\n/// #     fn table_name(&self) -> &'static str {\n/// #         \"cake\"\n/// #     }\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n/// # pub enum Column {\n/// #     Id,\n/// #     Name,\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n/// # pub enum PrimaryKey {\n/// #     Id,\n/// # }\n/// #\n/// # impl PrimaryKeyTrait for PrimaryKey {\n/// #     type ValueType = i32;\n/// #\n/// #     fn auto_increment() -> bool {\n/// #         true\n/// #     }\n/// # }\n/// #\n/// # #[derive(Copy, Clone, Debug, EnumIter)]\n/// # pub enum Relation {}\n/// #\n/// # impl ColumnTrait for Column {\n/// #     type EntityName = Entity;\n/// #\n/// #     fn def(&self) -> ColumnDef {\n/// #         match self {\n/// #             Self::Id => ColumnType::Integer.def(),\n/// #             Self::Name => ColumnType::String(StringLen::None).def(),\n/// #         }\n/// #     }\n/// # }\n/// #\n/// # impl RelationTrait for Relation {\n/// #     fn def(&self) -> RelationDef {\n/// #         panic!(\"No Relation\");\n/// #     }\n/// # }\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveActiveModelBehavior)]\npub fn derive_active_model_behavior(input: TokenStream) -> TokenStream {\n    let DeriveInput { ident, data, .. } = parse_macro_input!(input);\n\n    match derives::expand_derive_active_model_behavior(ident, data) {\n        Ok(ts) => ts.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n/// A derive macro to implement `sea_orm::ActiveEnum` trait for enums.\n///\n/// # Limitations\n///\n/// This derive macros can only be used on enums.\n///\n/// # Macro Attributes\n///\n/// All macro attributes listed below have to be annotated in the form of `#[sea_orm(attr = value)]`.\n///\n/// - For enum\n///     - `rs_type`: Define `ActiveEnum::Value`\n///         - Possible values: `String`, `i8`, `i16`, `i32`, `i64`, `u8`, `u16`, `u32`, `u64`\n///         - Note that value has to be passed as string, i.e. `rs_type = \"i8\"`\n///     - `db_type`: Define `ColumnType` returned by `ActiveEnum::db_type()`\n///         - Possible values: all available enum variants of `ColumnType`, e.g. `String(StringLen::None)`, `String(StringLen::N(1))`, `Integer`\n///         - Note that value has to be passed as string, i.e. `db_type = \"Integer\"`\n///     - `enum_name`: Define `String` returned by `ActiveEnum::name()`\n///         - This attribute is optional with default value being the name of enum in camel-case\n///         - Note that value has to be passed as string, i.e. `enum_name = \"MyEnum\"`\n///\n/// - For enum variant\n///     - `string_value` or `num_value`:\n///         - For `string_value`, value should be passed as string, i.e. `string_value = \"A\"`\n///             - Due to the way internal Enums are automatically derived, the following restrictions apply:\n///                 - members cannot share identical `string_value`, case-insensitive.\n///                 - in principle, any future Titlecased Rust keywords are not valid `string_value`.\n///         - For `num_value`, value should be passed as integer, i.e. `num_value = 1` or `num_value = 1i32`\n///         - Note that only one of it can be specified, and all variants of an enum have to annotate with the same `*_value` macro attribute\n///\n/// # Usage\n///\n/// ```\n/// use sea_orm::{DeriveActiveEnum, entity::prelude::*};\n///\n/// #[derive(EnumIter, DeriveActiveEnum)]\n/// #[sea_orm(rs_type = \"i32\", db_type = \"Integer\")]\n/// pub enum Color {\n///     Black = 0,\n///     White = 1,\n/// }\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveActiveEnum, attributes(sea_orm))]\npub fn derive_active_enum(input: TokenStream) -> TokenStream {\n    let input = parse_macro_input!(input as DeriveInput);\n\n    match derives::expand_derive_active_enum(input) {\n        Ok(ts) => ts.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n/// Convert a query result into the corresponding Model.\n///\n/// ### Attributes\n///\n/// - `skip`: will not try to pull this field from the query result. And set it to the default value of the type.\n/// - `nested`: allows nesting models. can be any type that implements `FromQueryResult`\n/// - `alias` / `from_alias`: get the value from this column alias\n///\n/// ### Usage\n///\n/// For more complete examples, please refer to https://github.com/SeaQL/sea-orm/blob/master/tests/from_query_result_tests.rs\n///\n/// ```\n/// use sea_orm::{FromQueryResult, entity::prelude::*};\n///\n/// #[derive(FromQueryResult)]\n/// struct Cake {\n///     id: i32,\n///     name: String,\n///     #[sea_orm(nested)]\n///     bakery: Option<CakeBakery>,\n///     #[sea_orm(skip)]\n///     skip_me: i32,\n/// }\n///\n/// #[derive(FromQueryResult)]\n/// struct CakeBakery {\n///     #[sea_orm(alias = \"bakery_id\")]\n///     id: i32,\n///     #[sea_orm(alias = \"bakery_name\")]\n///     title: String,\n/// }\n/// ```\n///\n/// You can compose this with regular Models, if there's no column collision:\n///\n/// ```ignore\n/// #[derive(FromQueryResult)]\n/// struct CakePlain {\n///     id: i32,\n///     name: String,\n///     price: Decimal,\n///     #[sea_orm(nested)]\n///     baker: Option<cakes_bakers::Model>,\n/// }\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(FromQueryResult, attributes(sea_orm))]\npub fn derive_from_query_result(input: TokenStream) -> TokenStream {\n    let derive_input = parse_macro_input!(input);\n\n    match derives::expand_derive_from_query_result(derive_input) {\n        Ok(token_stream) => token_stream.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n/// The DeriveRelation derive macro will implement RelationTrait for Relation.\n///\n/// ### Usage\n///\n/// ```\n/// # use sea_orm::tests_cfg::fruit::Entity;\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n/// pub enum Relation {\n///     #[sea_orm(\n///         belongs_to = \"sea_orm::tests_cfg::cake::Entity\",\n///         from = \"sea_orm::tests_cfg::fruit::Column::CakeId\",\n///         to = \"sea_orm::tests_cfg::cake::Column::Id\"\n///     )]\n///     Cake,\n///     #[sea_orm(\n///         belongs_to = \"sea_orm::tests_cfg::cake_expanded::Entity\",\n///         from = \"sea_orm::tests_cfg::fruit::Column::CakeId\",\n///         to = \"sea_orm::tests_cfg::cake_expanded::Column::Id\"\n///     )]\n///     CakeExpanded,\n/// }\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveRelation, attributes(sea_orm))]\npub fn derive_relation(input: TokenStream) -> TokenStream {\n    let input = parse_macro_input!(input as DeriveInput);\n    derives::expand_derive_relation(input)\n        .unwrap_or_else(Error::into_compile_error)\n        .into()\n}\n\n/// The DeriveRelatedEntity derive macro will implement seaography::RelationBuilder for RelatedEntity enumeration.\n///\n/// ### Usage\n///\n/// ```ignore\n/// use sea_orm::entity::prelude::*;\n///\n/// // ...\n/// // Model, Relation enum, etc.\n/// // ...\n///\n/// #[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]\n/// pub enum RelatedEntity {\n///     #[sea_orm(entity = \"super::address::Entity\")]\n///     Address,\n///     #[sea_orm(entity = \"super::payment::Entity\")]\n///     Payment,\n///     #[sea_orm(entity = \"super::rental::Entity\")]\n///     Rental,\n///     #[sea_orm(entity = \"Entity\", def = \"Relation::SelfRef.def()\")]\n///     SelfRef,\n///     #[sea_orm(entity = \"super::store::Entity\")]\n///     Store,\n///     #[sea_orm(entity = \"Entity\", def = \"Relation::SelfRef.def().rev()\")]\n///     SelfRefRev,\n/// }\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveRelatedEntity, attributes(sea_orm))]\npub fn derive_related_entity(input: TokenStream) -> TokenStream {\n    let input = parse_macro_input!(input as DeriveInput);\n    derives::expand_derive_related_entity(input)\n        .unwrap_or_else(Error::into_compile_error)\n        .into()\n}\n\n/// The DeriveMigrationName derive macro will implement `sea_orm_migration::MigrationName` for a migration.\n///\n/// ### Usage\n///\n/// ```ignore\n/// #[derive(DeriveMigrationName)]\n/// pub struct Migration;\n/// ```\n///\n/// The derive macro above will provide following implementation,\n/// given the file name is `m20220120_000001_create_post_table.rs`.\n///\n/// ```ignore\n/// impl MigrationName for Migration {\n///     fn name(&self) -> &str {\n///         \"m20220120_000001_create_post_table\"\n///     }\n/// }\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveMigrationName)]\npub fn derive_migration_name(input: TokenStream) -> TokenStream {\n    let input = parse_macro_input!(input as DeriveInput);\n    derives::expand_derive_migration_name(input)\n        .unwrap_or_else(Error::into_compile_error)\n        .into()\n}\n\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(FromJsonQueryResult)]\npub fn derive_from_json_query_result(input: TokenStream) -> TokenStream {\n    let DeriveInput { ident, .. } = parse_macro_input!(input);\n\n    match derives::expand_derive_from_json_query_result(ident) {\n        Ok(ts) => ts.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n/// The DerivePartialModel derive macro will implement [`sea_orm::PartialModelTrait`] for simplify partial model queries.\n/// Since 2.0, this macro cannot be used with the `FromQueryResult` macro.\n///\n/// ## Usage\n///\n/// For more complete examples, please refer to https://github.com/SeaQL/sea-orm/blob/master/tests/partial_model_tests.rs\n///\n/// ```rust\n/// use sea_orm::sea_query::ExprTrait;\n/// use sea_orm::{DerivePartialModel, entity::prelude::*};\n///\n/// #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #[sea_orm(table_name = \"posts\")]\n/// pub struct Model {\n///     #[sea_orm(primary_key)]\n///     pub id: i32,\n///     pub title: String,\n///     #[sea_orm(column_type = \"Text\")]\n///     pub text: String,\n/// }\n/// # #[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]\n/// # pub enum Relation {}\n/// # impl ActiveModelBehavior for ActiveModel {}\n///\n/// #[derive(Debug, DerivePartialModel)]\n/// #[sea_orm(entity = \"Entity\")]\n/// struct SelectResult {\n///     title: String,\n///     #[sea_orm(from_col = \"text\")]\n///     content: String,\n///     #[sea_orm(from_expr = \"Expr::val(1).add(1)\")]\n///     sum: i32,\n/// }\n/// ```\n///\n/// If all fields in the partial model is `from_expr`, the specifying the `entity` can be skipped.\n/// ```\n/// use sea_orm::{\n///     DerivePartialModel,\n///     entity::prelude::*,\n///     sea_query::{Expr, ExprTrait},\n/// };\n///\n/// #[derive(Debug, DerivePartialModel)]\n/// struct SelectResult {\n///     #[sea_orm(from_expr = \"Expr::val(1).add(1)\")]\n///     sum: i32,\n/// }\n/// ```\n///\n/// Since SeaORM 1.1.7, `DerivePartialModel` can also derive `FromQueryResult`.\n/// This is necessary to support nested partial models.\n/// Since 2.0, `from_query_result` is implemented by default, unless `from_query_result = \"false\"`.\n///\n/// ```\n/// use sea_orm::DerivePartialModel;\n/// #\n/// # mod cake {\n/// # use sea_orm::entity::prelude::*;\n/// # #[derive(Clone, Debug, DeriveEntityModel)]\n/// # #[sea_orm(table_name = \"cake\")]\n/// # pub struct Model {\n/// #     #[sea_orm(primary_key)]\n/// #     pub id: i32,\n/// #     pub name: String,\n/// # }\n/// # #[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]\n/// # pub enum Relation {}\n/// # impl ActiveModelBehavior for ActiveModel {}\n/// # }\n/// #\n/// # mod bakery {\n/// # use sea_orm::entity::prelude::*;\n/// # #[derive(Clone, Debug, DeriveEntityModel)]\n/// # #[sea_orm(table_name = \"bakery\")]\n/// # pub struct Model {\n/// #     #[sea_orm(primary_key)]\n/// #     pub id: i32,\n/// #     pub name: String,\n/// # }\n/// # #[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)]\n/// # pub enum Relation {}\n/// # impl ActiveModelBehavior for ActiveModel {}\n/// # }\n///\n/// #[derive(DerivePartialModel)]\n/// #[sea_orm(entity = \"cake::Entity\")]\n/// struct Cake {\n///     id: i32,\n///     name: String,\n///     #[sea_orm(nested)]\n///     bakery: Option<Bakery>,\n///     #[sea_orm(skip)]\n///     ignore: String,\n/// }\n///\n/// #[derive(DerivePartialModel)]\n/// #[sea_orm(entity = \"bakery::Entity\")]\n/// struct Bakery {\n///     id: i32,\n///     #[sea_orm(from_col = \"Name\")]\n///     title: String,\n/// }\n///\n/// // In addition, there's an `alias` attribute to select the columns from an alias:\n///\n/// #[derive(DerivePartialModel)]\n/// #[sea_orm(entity = \"bakery::Entity\", alias = \"factory\")]\n/// struct Factory {\n///     id: i32,\n///     #[sea_orm(from_col = \"name\")]\n///     plant: String,\n/// }\n///\n/// #[derive(DerivePartialModel)]\n/// #[sea_orm(entity = \"cake::Entity\")]\n/// struct CakeFactory {\n///     id: i32,\n///     name: String,\n///     #[sea_orm(nested)]\n///     bakery: Option<Factory>,\n/// }\n/// ```\n///\n/// ```ignore\n/// let cake: CakeFactory = cake::Entity::find()\n///     .join_as(\n///         JoinType::LeftJoin,\n///         cake::Relation::Bakery.def(),\n///         \"factory\",\n///     )\n///     .order_by_asc(cake::Column::Id)\n///     .into_partial_model()\n///     .one(&db)\n///     .await\n///     .unwrap()\n///     .unwrap()\n///\n/// SELECT\n///     \"cake\".\"id\" AS \"id\", \"cake\".\"name\" AS \"name\",\n///     \"factory\".\"id\" AS \"bakery_id\", \"factory\".\"name\" AS \"bakery_plant\"\n/// FROM \"cake\"\n/// LEFT JOIN \"bakery\" AS \"factory\" ON \"cake\".\"bakery_id\" = \"factory\".\"id\"\n/// LIMIT 1\n/// ```\n///\n/// A field cannot have attributes `from_col`, `from_expr` or `nested` at the same time.\n/// Or, it will result in a compile error.\n///\n/// ```compile_fail\n/// use sea_orm::{entity::prelude::*, DerivePartialModel, sea_query::Expr};\n///\n/// #[derive(Debug, DerivePartialModel)]\n/// #[sea_orm(entity = \"Entity\")]\n/// struct SelectResult {\n///     #[sea_orm(from_expr = \"Expr::val(1).add(1)\", from_col = \"foo\")]\n///     sum: i32,\n/// }\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DerivePartialModel, attributes(sea_orm))]\npub fn derive_partial_model(input: TokenStream) -> TokenStream {\n    let derive_input = parse_macro_input!(input);\n\n    match derives::expand_derive_partial_model(derive_input) {\n        Ok(token_stream) => token_stream.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n#[doc(hidden)]\n#[cfg(feature = \"derive\")]\n#[proc_macro_attribute]\npub fn test(_: TokenStream, input: TokenStream) -> TokenStream {\n    let input = parse_macro_input!(input as syn::ItemFn);\n\n    let ret = &input.sig.output;\n    let name = &input.sig.ident;\n    let body = &input.block;\n    let attrs = &input.attrs;\n\n    if cfg!(feature = \"async\") {\n        quote::quote! (\n            #[test]\n            #[cfg(any(\n                feature = \"sqlx-mysql\",\n                feature = \"sqlx-sqlite\",\n                feature = \"sqlx-postgres\",\n            ))]\n            #(#attrs)*\n            fn #name() #ret {\n                let _ = ::tracing_subscriber::fmt()\n                    .with_max_level(::tracing::Level::DEBUG)\n                    .with_test_writer()\n                    .try_init();\n                crate::block_on!(async { #body })\n            }\n        )\n        .into()\n    } else {\n        quote::quote! (\n            #[test]\n            #[cfg(any(\n                feature = \"rusqlite\",\n            ))]\n            #(#attrs)*\n            fn #name() #ret {\n                let _ = ::tracing_subscriber::fmt()\n                    .with_max_level(::tracing::Level::DEBUG)\n                    .with_test_writer()\n                    .try_init();\n                #body\n            }\n        )\n        .into()\n    }\n}\n\n/// Creates a new type that iterates of the variants of an enum.\n///\n/// Iterate over the variants of an Enum. Any additional data on your variants will be set to `Default::default()`.\n/// The macro implements `strum::IntoEnumIterator` on your enum and creates a new type called `YourEnumIter` that is the iterator object.\n/// You cannot derive `EnumIter` on any type with a lifetime bound (`<'a>`) because the iterator would surely\n/// create [unbounded lifetimes](https://doc.rust-lang.org/nightly/nomicon/unbounded-lifetimes.html).\n#[cfg(feature = \"strum\")]\n#[proc_macro_derive(EnumIter, attributes(strum))]\npub fn enum_iter(input: TokenStream) -> TokenStream {\n    let ast = parse_macro_input!(input as DeriveInput);\n\n    strum::enum_iter::enum_iter_inner(&ast)\n        .unwrap_or_else(Error::into_compile_error)\n        .into()\n}\n\n/// Implements traits for types that wrap a database value type.\n///\n/// This procedure macro implements `From<T> for Value`, `sea_orm::TryGetTable`, and\n/// `sea_query::ValueType` for the wrapper type `T`.\n///\n/// It also implements `sea_query::postgres_array::NotU8`.\n/// It implements `TryFromU64` if the wrapped types are recognized primitives, i.e.\n/// `\"i8\" | \"i16\" | \"i32\" | \"i64\" | \"u8\" | \"u16\" | \"u32\" | \"u64\"`.\n///\n/// The wrapped type must be `sea_orm::Value` compatible.\n///\n/// ## Usage\n///\n/// ```rust\n/// use sea_orm::DeriveValueType;\n///\n/// #[derive(DeriveValueType)]\n/// struct MyString(String);\n///\n/// #[derive(DeriveValueType)]\n/// struct MyNumber(i32);\n/// ```\n///\n/// It's also possible to derive value type for enum-strings.\n/// Basically the underlying type is String, and the custom must implement methods `to_str` and `from_str`.\n///\n/// ## Example\n///\n/// ```rust\n/// use sea_orm::{DeriveValueType, sea_query::ValueTypeErr};\n///\n/// #[derive(DeriveValueType)]\n/// #[sea_orm(value_type = \"String\")]\n/// pub enum Tag {\n///     Hard,\n///     Soft,\n/// }\n///\n/// impl std::fmt::Display for Tag {\n///     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n///         write!(\n///             f,\n///             \"{}\",\n///             match self {\n///                 Self::Hard => \"hard\",\n///                 Self::Soft => \"soft\",\n///             }\n///         )\n///     }\n/// }\n///\n/// impl std::str::FromStr for Tag {\n///     type Err = ValueTypeErr;\n///\n///     fn from_str(s: &str) -> Result<Self, Self::Err> {\n///         Ok(match s {\n///             \"hard\" => Self::Hard,\n///             \"soft\" => Self::Soft,\n///             _ => return Err(ValueTypeErr),\n///         })\n///     }\n/// }\n/// ```\n///\n/// `from_str` defaults to `std::str::FromStr::from_str`. `to_str` defaults to `std::string::ToString::to_string`.\n/// They can be overridden with custom functions.\n///\n/// ```rust\n/// use sea_orm::{DeriveValueType, sea_query::ValueTypeErr};\n///\n/// #[derive(DeriveValueType)]\n/// #[sea_orm(\n///     value_type = \"String\",\n///     from_str = \"Tag::from_str\",\n///     to_str = \"Tag::to_str\"\n/// )]\n/// pub enum Tag {\n///     Color,\n///     Grey,\n/// }\n///\n/// impl Tag {\n///     fn to_str(&self) -> &'static str {\n///         match self {\n///             Self::Color => \"color\",\n///             Self::Grey => \"grey\",\n///         }\n///     }\n///\n///     fn from_str(s: &str) -> Result<Self, ValueTypeErr> {\n///         Ok(match s {\n///             \"color\" => Self::Color,\n///             \"grey\" => Self::Grey,\n///             _ => return Err(ValueTypeErr),\n///         })\n///     }\n/// }\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveValueType, attributes(sea_orm))]\npub fn derive_value_type(input: TokenStream) -> TokenStream {\n    let derive_input = parse_macro_input!(input as DeriveInput);\n    match derives::expand_derive_value_type(derive_input) {\n        Ok(token_stream) => token_stream.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveDisplay, attributes(sea_orm))]\npub fn derive_active_enum_display(input: TokenStream) -> TokenStream {\n    let input = parse_macro_input!(input as DeriveInput);\n    match derives::expand_derive_active_enum_display(input) {\n        Ok(ts) => ts.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n/// The DeriveIden derive macro will implement `sea_orm::Iden` for simplify Iden implementation.\n///\n/// ## Usage\n///\n/// ```rust\n/// use sea_orm::{DeriveIden, Iden};\n///\n/// #[derive(DeriveIden)]\n/// pub enum MyClass {\n///     Table, // this is a special case, which maps to the enum's name\n///     Id,\n///     #[sea_orm(iden = \"turtle\")]\n///     Title,\n///     Text,\n/// }\n///\n/// #[derive(DeriveIden)]\n/// struct MyOther;\n///\n/// assert_eq!(MyClass::Table.to_string(), \"my_class\");\n/// assert_eq!(MyClass::Id.to_string(), \"id\");\n/// assert_eq!(MyClass::Title.to_string(), \"turtle\"); // renamed!\n/// assert_eq!(MyClass::Text.to_string(), \"text\");\n/// assert_eq!(MyOther.to_string(), \"my_other\");\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveIden, attributes(sea_orm))]\npub fn derive_iden(input: TokenStream) -> TokenStream {\n    let derive_input = parse_macro_input!(input as DeriveInput);\n\n    match derives::expand_derive_iden(derive_input) {\n        Ok(token_stream) => token_stream.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n/// The DeriveArrowSchema derive macro generates an `arrow_schema()` method\n/// that returns an Apache Arrow schema from a SeaORM entity definition.\n///\n/// This macro is automatically applied when `#[sea_orm(arrow_schema)]` is specified\n/// on a model. You typically don't need to use this derive macro directly.\n///\n/// ## Usage\n///\n/// ```rust,ignore\n/// use sea_orm::entity::prelude::*;\n///\n/// #[sea_orm::model]\n/// #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #[sea_orm(table_name = \"user\", arrow_schema)]\n/// pub struct Model {\n///     #[sea_orm(primary_key)]\n///     pub id: i64,\n///     pub name: String,\n///     #[sea_orm(column_type = \"Decimal(Some((20, 4)))\")]\n///     pub amount: Decimal,\n/// }\n/// ```\n#[cfg(feature = \"derive\")]\n#[proc_macro_derive(DeriveArrowSchema, attributes(sea_orm))]\npub fn derive_arrow_schema(input: TokenStream) -> TokenStream {\n    let derive_input = parse_macro_input!(input as DeriveInput);\n\n    match derives::expand_derive_arrow_schema(\n        derive_input.ident,\n        derive_input.data,\n        derive_input.attrs,\n    ) {\n        Ok(token_stream) => token_stream.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n#[proc_macro]\npub fn raw_sql(input: TokenStream) -> TokenStream {\n    match raw_sql::expand(input) {\n        Ok(token_stream) => token_stream.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n#[cfg(feature = \"derive\")]\n#[proc_macro_attribute]\npub fn sea_orm_model(_attr: TokenStream, input: TokenStream) -> TokenStream {\n    let input = parse_macro_input!(input as syn::ItemStruct);\n\n    match derives::expand_sea_orm_model(input, false) {\n        Ok(token_stream) => token_stream.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n\n#[cfg(feature = \"derive\")]\n#[proc_macro_attribute]\npub fn sea_orm_compact_model(_attr: TokenStream, input: TokenStream) -> TokenStream {\n    let input = parse_macro_input!(input as syn::ItemStruct);\n\n    match derives::expand_sea_orm_model(input, true) {\n        Ok(token_stream) => token_stream.into(),\n        Err(e) => e.to_compile_error().into(),\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/raw_sql.rs",
    "content": "use proc_macro2::TokenStream;\nuse quote::quote;\nuse syn::{\n    Ident, LitStr, Token,\n    parse::{Parse, ParseStream},\n};\n\nstruct CallArgs {\n    backend: Ident,\n    _comma: Token![,],\n    sql_string: LitStr,\n}\n\nimpl Parse for CallArgs {\n    fn parse(input: ParseStream) -> syn::Result<Self> {\n        Ok(CallArgs {\n            backend: input.parse()?,\n            _comma: input.parse()?,\n            sql_string: input.parse()?,\n        })\n    }\n}\n\npub fn expand(input: proc_macro::TokenStream) -> syn::Result<TokenStream> {\n    let CallArgs {\n        backend,\n        sql_string,\n        ..\n    } = syn::parse(input)?;\n\n    let builder = match backend.to_string().as_str() {\n        \"MySql\" => quote!(MysqlQueryBuilder),\n        \"Postgres\" => quote!(PostgresQueryBuilder),\n        \"Sqlite\" => quote!(SqliteQueryBuilder),\n        backend => panic!(\"Unsupported backend {backend}\"),\n    };\n\n    Ok(quote! {{\n        use sea_orm::sea_query;\n\n        let query = sea_query::raw_query!(#builder, #sql_string);\n\n        sea_orm::Statement {\n            sql: query.sql,\n            values: Some(query.values),\n            db_backend: sea_orm::DbBackend::#backend,\n        }\n    }})\n}\n"
  },
  {
    "path": "sea-orm-macros/src/strum/LICENSE",
    "content": "> The `strum` module is adapted from https://github.com/Peternator7/strum\n\nMIT License\n\nCopyright (c) 2019 Peter Glotfelty\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "sea-orm-macros/src/strum/enum_iter.rs",
    "content": "use proc_macro2::{Span, TokenStream};\nuse quote::quote;\nuse syn::{Data, DeriveInput, Fields, Ident};\n\nuse super::helpers::{HasStrumVariantProperties, HasTypeProperties, non_enum_error};\n\npub fn enum_iter_inner(ast: &DeriveInput) -> syn::Result<TokenStream> {\n    let name = &ast.ident;\n    let r#gen = &ast.generics;\n    let (impl_generics, ty_generics, where_clause) = r#gen.split_for_impl();\n    let vis = &ast.vis;\n    let type_properties = ast.get_type_properties()?;\n    let strum_module_path = type_properties.crate_module_path();\n    let doc_comment = format!(\"An iterator over the variants of [{name}]\");\n\n    if r#gen.lifetimes().count() > 0 {\n        return Err(syn::Error::new(\n            Span::call_site(),\n            \"This macro doesn't support enums with lifetimes. \\\n             The resulting enums would be unbounded.\",\n        ));\n    }\n\n    let phantom_data = if r#gen.type_params().count() > 0 {\n        let g = r#gen.type_params().map(|param| &param.ident);\n        quote! { < ( #(#g),* ) > }\n    } else {\n        quote! { < () > }\n    };\n\n    let variants = match &ast.data {\n        Data::Enum(v) => &v.variants,\n        _ => return Err(non_enum_error()),\n    };\n\n    let mut arms = Vec::new();\n    let mut idx = 0usize;\n    for variant in variants {\n        if variant.get_variant_properties()?.disabled.is_some() {\n            continue;\n        }\n\n        let ident = &variant.ident;\n        let params = match &variant.fields {\n            Fields::Unit => quote! {},\n            Fields::Unnamed(fields) => {\n                let defaults = ::core::iter::repeat_n(\n                    quote!(::core::default::Default::default()),\n                    fields.unnamed.len(),\n                );\n                quote! { (#(#defaults),*) }\n            }\n            Fields::Named(fields) => {\n                let fields = fields\n                    .named\n                    .iter()\n                    .map(|field| field.ident.as_ref().unwrap());\n                quote! { {#(#fields: ::core::default::Default::default()),*} }\n            }\n        };\n\n        arms.push(quote! {#idx => ::core::option::Option::Some(#name::#ident #params)});\n        idx += 1;\n    }\n\n    let variant_count = arms.len();\n    arms.push(quote! { _ => ::core::option::Option::None });\n    let iter_name = syn::parse_str::<Ident>(&format!(\"{name}Iter\")).unwrap();\n\n    // Create a string literal \"MyEnumIter\" to use in the debug impl.\n    let iter_name_debug_struct =\n        syn::parse_str::<syn::LitStr>(&format!(\"\\\"{iter_name}\\\"\")).unwrap();\n\n    Ok(quote! {\n        #[doc = #doc_comment]\n        #[allow(\n            missing_copy_implementations,\n        )]\n        #vis struct #iter_name #impl_generics {\n            idx: usize,\n            back_idx: usize,\n            marker: ::core::marker::PhantomData #phantom_data,\n        }\n\n        impl #impl_generics ::core::fmt::Debug for #iter_name #ty_generics #where_clause {\n            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {\n                // We don't know if the variants implement debug themselves so the only thing we\n                // can really show is how many elements are left.\n                f.debug_struct(#iter_name_debug_struct)\n                    .field(\"len\", &self.len())\n                    .finish()\n            }\n        }\n\n        impl #impl_generics #iter_name #ty_generics #where_clause {\n            fn get(&self, idx: usize) -> ::core::option::Option<#name #ty_generics> {\n                match idx {\n                    #(#arms),*\n                }\n            }\n        }\n\n        impl #impl_generics #strum_module_path::IntoEnumIterator for #name #ty_generics #where_clause {\n            type Iterator = #iter_name #ty_generics;\n            fn iter() -> #iter_name #ty_generics {\n                #iter_name {\n                    idx: 0,\n                    back_idx: 0,\n                    marker: ::core::marker::PhantomData,\n                }\n            }\n        }\n\n        impl #impl_generics Iterator for #iter_name #ty_generics #where_clause {\n            type Item = #name #ty_generics;\n\n            fn next(&mut self) -> ::core::option::Option<<Self as Iterator>::Item> {\n                self.nth(0)\n            }\n\n            fn size_hint(&self) -> (usize, ::core::option::Option<usize>) {\n                let t = if self.idx + self.back_idx >= #variant_count { 0 } else { #variant_count - self.idx - self.back_idx };\n                (t, Some(t))\n            }\n\n            fn nth(&mut self, n: usize) -> ::core::option::Option<<Self as Iterator>::Item> {\n                let idx = self.idx + n + 1;\n                if idx + self.back_idx > #variant_count {\n                    // We went past the end of the iterator. Freeze idx at #variant_count\n                    // so that it doesn't overflow if the user calls this repeatedly.\n                    // See PR #76 for context.\n                    self.idx = #variant_count;\n                    ::core::option::Option::None\n                } else {\n                    self.idx = idx;\n                    #iter_name::get(self, idx - 1)\n                }\n            }\n        }\n\n        impl #impl_generics ExactSizeIterator for #iter_name #ty_generics #where_clause {\n            fn len(&self) -> usize {\n                self.size_hint().0\n            }\n        }\n\n        impl #impl_generics DoubleEndedIterator for #iter_name #ty_generics #where_clause {\n            fn next_back(&mut self) -> ::core::option::Option<<Self as Iterator>::Item> {\n                let back_idx = self.back_idx + 1;\n\n                if self.idx + back_idx > #variant_count {\n                    // We went past the end of the iterator. Freeze back_idx at #variant_count\n                    // so that it doesn't overflow if the user calls this repeatedly.\n                    // See PR #76 for context.\n                    self.back_idx = #variant_count;\n                    ::core::option::Option::None\n                } else {\n                    self.back_idx = back_idx;\n                    #iter_name::get(self, #variant_count - self.back_idx)\n                }\n            }\n        }\n\n        impl #impl_generics ::core::iter::FusedIterator for #iter_name #ty_generics #where_clause { }\n\n        impl #impl_generics Clone for #iter_name #ty_generics #where_clause {\n            fn clone(&self) -> #iter_name #ty_generics {\n                #iter_name {\n                    idx: self.idx,\n                    back_idx: self.back_idx,\n                    marker: self.marker.clone(),\n                }\n            }\n        }\n    })\n}\n"
  },
  {
    "path": "sea-orm-macros/src/strum/helpers/case_style.rs",
    "content": "use heck::{\n    ToKebabCase, ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToTitleCase, ToUpperCamelCase,\n};\nuse std::str::FromStr;\nuse syn::{\n    Ident, LitStr,\n    parse::{Parse, ParseStream},\n};\n\n#[allow(clippy::enum_variant_names)]\n#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]\npub enum CaseStyle {\n    CamelCase,\n    KebabCase,\n    MixedCase,\n    ShoutySnakeCase,\n    SnakeCase,\n    TitleCase,\n    UpperCase,\n    LowerCase,\n    ScreamingKebabCase,\n    PascalCase,\n}\n\nconst VALID_CASE_STYLES: &[&str] = &[\n    \"camelCase\",\n    \"PascalCase\",\n    \"kebab-case\",\n    \"snake_case\",\n    \"SCREAMING_SNAKE_CASE\",\n    \"SCREAMING-KEBAB-CASE\",\n    \"lowercase\",\n    \"UPPERCASE\",\n    \"title_case\",\n    \"mixed_case\",\n];\n\nimpl Parse for CaseStyle {\n    fn parse(input: ParseStream) -> syn::Result<Self> {\n        let text = input.parse::<LitStr>()?;\n        let val = text.value();\n\n        val.as_str().parse().map_err(|_| {\n            syn::Error::new_spanned(\n                &text,\n                format!(\n                    \"Unexpected case style for serialize_all: `{val}`. Valid values are: `{VALID_CASE_STYLES:?}`\",\n                ),\n            )\n        })\n    }\n}\n\nimpl FromStr for CaseStyle {\n    type Err = ();\n\n    fn from_str(text: &str) -> Result<Self, ()> {\n        Ok(match text {\n            \"camel_case\" | \"PascalCase\" => CaseStyle::PascalCase,\n            \"camelCase\" => CaseStyle::CamelCase,\n            \"snake_case\" | \"snek_case\" => CaseStyle::SnakeCase,\n            \"kebab_case\" | \"kebab-case\" => CaseStyle::KebabCase,\n            \"SCREAMING-KEBAB-CASE\" => CaseStyle::ScreamingKebabCase,\n            \"shouty_snake_case\" | \"shouty_snek_case\" | \"SCREAMING_SNAKE_CASE\" => {\n                CaseStyle::ShoutySnakeCase\n            }\n            \"title_case\" => CaseStyle::TitleCase,\n            \"mixed_case\" => CaseStyle::MixedCase,\n            \"lowercase\" => CaseStyle::LowerCase,\n            \"UPPERCASE\" => CaseStyle::UpperCase,\n            _ => return Err(()),\n        })\n    }\n}\n\npub trait CaseStyleHelpers {\n    fn convert_case(&self, case_style: Option<CaseStyle>) -> String;\n}\n\nimpl CaseStyleHelpers for Ident {\n    fn convert_case(&self, case_style: Option<CaseStyle>) -> String {\n        let ident_string = self.to_string();\n        if let Some(case_style) = case_style {\n            match case_style {\n                CaseStyle::PascalCase => ident_string.to_upper_camel_case(),\n                CaseStyle::KebabCase => ident_string.to_kebab_case(),\n                CaseStyle::MixedCase => ident_string.to_lower_camel_case(),\n                CaseStyle::ShoutySnakeCase => ident_string.to_shouty_snake_case(),\n                CaseStyle::SnakeCase => ident_string.to_snake_case(),\n                CaseStyle::TitleCase => ident_string.to_title_case(),\n                CaseStyle::UpperCase => ident_string.to_uppercase(),\n                CaseStyle::LowerCase => ident_string.to_lowercase(),\n                CaseStyle::ScreamingKebabCase => ident_string.to_kebab_case().to_uppercase(),\n                CaseStyle::CamelCase => {\n                    let camel_case = ident_string.to_upper_camel_case();\n                    let mut pascal = String::with_capacity(camel_case.len());\n                    let mut it = camel_case.chars();\n                    if let Some(ch) = it.next() {\n                        pascal.extend(ch.to_lowercase());\n                    }\n                    pascal.extend(it);\n                    pascal\n                }\n            }\n        } else {\n            ident_string\n        }\n    }\n}\n\n#[test]\nfn test_convert_case() {\n    let id = Ident::new(\"test_me\", proc_macro2::Span::call_site());\n    assert_eq!(\"testMe\", id.convert_case(Some(CaseStyle::CamelCase)));\n    assert_eq!(\"TestMe\", id.convert_case(Some(CaseStyle::PascalCase)));\n}\n"
  },
  {
    "path": "sea-orm-macros/src/strum/helpers/metadata.rs",
    "content": "use proc_macro2::TokenStream;\nuse syn::{\n    Attribute, DeriveInput, Expr, ExprLit, Ident, Lit, LitBool, LitStr, Meta, MetaNameValue, Path,\n    Token, Variant, Visibility, parenthesized,\n    parse::{Parse, ParseStream},\n    parse_str, parse2,\n    punctuated::Punctuated,\n};\n\nuse super::case_style::CaseStyle;\n\npub mod kw {\n    use syn::custom_keyword;\n    pub use syn::token::Crate;\n\n    // enum metadata\n    custom_keyword!(serialize_all);\n    custom_keyword!(use_phf);\n\n    // enum discriminant metadata\n    custom_keyword!(derive);\n    custom_keyword!(name);\n    custom_keyword!(vis);\n\n    // variant metadata\n    custom_keyword!(message);\n    custom_keyword!(detailed_message);\n    custom_keyword!(serialize);\n    custom_keyword!(to_string);\n    custom_keyword!(disabled);\n    custom_keyword!(default);\n    custom_keyword!(props);\n    custom_keyword!(ascii_case_insensitive);\n}\n\npub enum EnumMeta {\n    SerializeAll {\n        kw: kw::serialize_all,\n        case_style: CaseStyle,\n    },\n    AsciiCaseInsensitive(kw::ascii_case_insensitive),\n    Crate {\n        kw: kw::Crate,\n        crate_module_path: Path,\n    },\n    UsePhf(kw::use_phf),\n}\n\nimpl Parse for EnumMeta {\n    fn parse(input: ParseStream) -> syn::Result<Self> {\n        let lookahead = input.lookahead1();\n        if lookahead.peek(kw::serialize_all) {\n            let kw = input.parse::<kw::serialize_all>()?;\n            input.parse::<Token![=]>()?;\n            let case_style = input.parse()?;\n            Ok(EnumMeta::SerializeAll { kw, case_style })\n        } else if lookahead.peek(kw::Crate) {\n            let kw = input.parse::<kw::Crate>()?;\n            input.parse::<Token![=]>()?;\n            let path_str: LitStr = input.parse()?;\n            let path_tokens = parse_str(&path_str.value())?;\n            let crate_module_path = parse2(path_tokens)?;\n            Ok(EnumMeta::Crate {\n                kw,\n                crate_module_path,\n            })\n        } else if lookahead.peek(kw::ascii_case_insensitive) {\n            Ok(EnumMeta::AsciiCaseInsensitive(input.parse()?))\n        } else if lookahead.peek(kw::use_phf) {\n            Ok(EnumMeta::UsePhf(input.parse()?))\n        } else {\n            Err(lookahead.error())\n        }\n    }\n}\n\npub enum EnumDiscriminantsMeta {\n    Derive { kw: kw::derive, paths: Vec<Path> },\n    Name { kw: kw::name, name: Ident },\n    Vis { kw: kw::vis, vis: Visibility },\n    Other { path: Path, nested: TokenStream },\n}\n\nimpl Parse for EnumDiscriminantsMeta {\n    fn parse(input: ParseStream) -> syn::Result<Self> {\n        if input.peek(kw::derive) {\n            let kw = input.parse()?;\n            let content;\n            parenthesized!(content in input);\n            let paths = content.parse_terminated(Path::parse, Token![,])?;\n            Ok(EnumDiscriminantsMeta::Derive {\n                kw,\n                paths: paths.into_iter().collect(),\n            })\n        } else if input.peek(kw::name) {\n            let kw = input.parse()?;\n            let content;\n            parenthesized!(content in input);\n            let name = content.parse()?;\n            Ok(EnumDiscriminantsMeta::Name { kw, name })\n        } else if input.peek(kw::vis) {\n            let kw = input.parse()?;\n            let content;\n            parenthesized!(content in input);\n            let vis = content.parse()?;\n            Ok(EnumDiscriminantsMeta::Vis { kw, vis })\n        } else {\n            let path = input.parse()?;\n            let content;\n            parenthesized!(content in input);\n            let nested = content.parse()?;\n            Ok(EnumDiscriminantsMeta::Other { path, nested })\n        }\n    }\n}\n\npub trait DeriveInputExt {\n    /// Get all the strum metadata associated with an enum.\n    fn get_metadata(&self) -> syn::Result<Vec<EnumMeta>>;\n\n    /// Get all the `strum_discriminants` metadata associated with an enum.\n    fn get_discriminants_metadata(&self) -> syn::Result<Vec<EnumDiscriminantsMeta>>;\n}\n\nimpl DeriveInputExt for DeriveInput {\n    fn get_metadata(&self) -> syn::Result<Vec<EnumMeta>> {\n        get_metadata_inner(\"strum\", &self.attrs)\n    }\n\n    fn get_discriminants_metadata(&self) -> syn::Result<Vec<EnumDiscriminantsMeta>> {\n        get_metadata_inner(\"strum_discriminants\", &self.attrs)\n    }\n}\n\npub enum VariantMeta {\n    Message {\n        kw: kw::message,\n        value: LitStr,\n    },\n    DetailedMessage {\n        kw: kw::detailed_message,\n        value: LitStr,\n    },\n    Serialize {\n        kw: kw::serialize,\n        value: LitStr,\n    },\n    Documentation {\n        value: LitStr,\n    },\n    ToString {\n        kw: kw::to_string,\n        value: LitStr,\n    },\n    Disabled(kw::disabled),\n    Default(kw::default),\n    AsciiCaseInsensitive {\n        kw: kw::ascii_case_insensitive,\n        value: bool,\n    },\n    Props {\n        kw: kw::props,\n        props: Vec<(LitStr, LitStr)>,\n    },\n}\n\nimpl Parse for VariantMeta {\n    fn parse(input: ParseStream) -> syn::Result<Self> {\n        let lookahead = input.lookahead1();\n        if lookahead.peek(kw::message) {\n            let kw = input.parse()?;\n            let _: Token![=] = input.parse()?;\n            let value = input.parse()?;\n            Ok(VariantMeta::Message { kw, value })\n        } else if lookahead.peek(kw::detailed_message) {\n            let kw = input.parse()?;\n            let _: Token![=] = input.parse()?;\n            let value = input.parse()?;\n            Ok(VariantMeta::DetailedMessage { kw, value })\n        } else if lookahead.peek(kw::serialize) {\n            let kw = input.parse()?;\n            let _: Token![=] = input.parse()?;\n            let value = input.parse()?;\n            Ok(VariantMeta::Serialize { kw, value })\n        } else if lookahead.peek(kw::to_string) {\n            let kw = input.parse()?;\n            let _: Token![=] = input.parse()?;\n            let value = input.parse()?;\n            Ok(VariantMeta::ToString { kw, value })\n        } else if lookahead.peek(kw::disabled) {\n            Ok(VariantMeta::Disabled(input.parse()?))\n        } else if lookahead.peek(kw::default) {\n            Ok(VariantMeta::Default(input.parse()?))\n        } else if lookahead.peek(kw::ascii_case_insensitive) {\n            let kw = input.parse()?;\n            let value = if input.peek(Token![=]) {\n                let _: Token![=] = input.parse()?;\n                input.parse::<LitBool>()?.value\n            } else {\n                true\n            };\n            Ok(VariantMeta::AsciiCaseInsensitive { kw, value })\n        } else if lookahead.peek(kw::props) {\n            let kw = input.parse()?;\n            let content;\n            parenthesized!(content in input);\n            let props = content.parse_terminated(Prop::parse, Token![,])?;\n            Ok(VariantMeta::Props {\n                kw,\n                props: props\n                    .into_iter()\n                    .map(|Prop(k, v)| (LitStr::new(&k.to_string(), k.span()), v))\n                    .collect(),\n            })\n        } else {\n            Err(lookahead.error())\n        }\n    }\n}\n\nstruct Prop(Ident, LitStr);\n\nimpl Parse for Prop {\n    fn parse(input: ParseStream) -> syn::Result<Self> {\n        use syn::ext::IdentExt;\n\n        let k = Ident::parse_any(input)?;\n        let _: Token![=] = input.parse()?;\n        let v = input.parse()?;\n\n        Ok(Prop(k, v))\n    }\n}\n\npub trait VariantExt {\n    /// Get all the metadata associated with an enum variant.\n    fn get_metadata(&self) -> syn::Result<Vec<VariantMeta>>;\n}\n\nimpl VariantExt for Variant {\n    fn get_metadata(&self) -> syn::Result<Vec<VariantMeta>> {\n        let result = get_metadata_inner(\"strum\", &self.attrs)?;\n        self.attrs\n            .iter()\n            .filter(|attr| attr.path().is_ident(\"doc\"))\n            .try_fold(result, |mut vec, attr| {\n                if let Meta::NameValue(MetaNameValue {\n                    value:\n                        Expr::Lit(ExprLit {\n                            lit: Lit::Str(value),\n                            ..\n                        }),\n                    ..\n                }) = &attr.meta\n                {\n                    vec.push(VariantMeta::Documentation {\n                        value: value.clone(),\n                    })\n                }\n                Ok(vec)\n            })\n    }\n}\n\nfn get_metadata_inner<'a, T: Parse>(\n    ident: &str,\n    it: impl IntoIterator<Item = &'a Attribute>,\n) -> syn::Result<Vec<T>> {\n    it.into_iter()\n        .filter(|attr| attr.path().is_ident(ident))\n        .try_fold(Vec::new(), |mut vec, attr| {\n            vec.extend(attr.parse_args_with(Punctuated::<T, Token![,]>::parse_terminated)?);\n            Ok(vec)\n        })\n}\n"
  },
  {
    "path": "sea-orm-macros/src/strum/helpers/mod.rs",
    "content": "pub use self::type_props::HasTypeProperties;\npub use self::variant_props::HasStrumVariantProperties;\n\npub mod case_style;\nmod metadata;\npub mod type_props;\npub mod variant_props;\n\nuse proc_macro2::Span;\nuse quote::ToTokens;\n\npub fn non_enum_error() -> syn::Error {\n    syn::Error::new(Span::call_site(), \"This macro only supports enums.\")\n}\n\npub fn occurrence_error<T: ToTokens>(fst: T, snd: T, attr: &str) -> syn::Error {\n    let mut e =\n        syn::Error::new_spanned(snd, format!(\"Found multiple occurrences of strum({attr})\"));\n    e.combine(syn::Error::new_spanned(fst, \"first one here\"));\n    e\n}\n"
  },
  {
    "path": "sea-orm-macros/src/strum/helpers/type_props.rs",
    "content": "use proc_macro2::TokenStream;\nuse quote::quote;\nuse std::default::Default;\nuse syn::{DeriveInput, Ident, Path, Visibility, parse_quote};\n\nuse super::case_style::CaseStyle;\nuse super::metadata::{DeriveInputExt, EnumDiscriminantsMeta, EnumMeta};\nuse super::occurrence_error;\n\npub trait HasTypeProperties {\n    fn get_type_properties(&self) -> syn::Result<StrumTypeProperties>;\n}\n\n#[derive(Debug, Clone, Default)]\npub struct StrumTypeProperties {\n    pub case_style: Option<CaseStyle>,\n    pub ascii_case_insensitive: bool,\n    pub crate_module_path: Option<Path>,\n    pub discriminant_derives: Vec<Path>,\n    pub discriminant_name: Option<Ident>,\n    pub discriminant_others: Vec<TokenStream>,\n    pub discriminant_vis: Option<Visibility>,\n    pub use_phf: bool,\n}\n\nimpl HasTypeProperties for DeriveInput {\n    fn get_type_properties(&self) -> syn::Result<StrumTypeProperties> {\n        let mut output = StrumTypeProperties::default();\n\n        let strum_meta = self.get_metadata()?;\n        let discriminants_meta = self.get_discriminants_metadata()?;\n\n        let mut serialize_all_kw = None;\n        let mut ascii_case_insensitive_kw = None;\n        let mut use_phf_kw = None;\n        let mut crate_module_path_kw = None;\n        for meta in strum_meta {\n            match meta {\n                EnumMeta::SerializeAll { case_style, kw } => {\n                    if let Some(fst_kw) = serialize_all_kw {\n                        return Err(occurrence_error(fst_kw, kw, \"serialize_all\"));\n                    }\n\n                    serialize_all_kw = Some(kw);\n                    output.case_style = Some(case_style);\n                }\n                EnumMeta::AsciiCaseInsensitive(kw) => {\n                    if let Some(fst_kw) = ascii_case_insensitive_kw {\n                        return Err(occurrence_error(fst_kw, kw, \"ascii_case_insensitive\"));\n                    }\n\n                    ascii_case_insensitive_kw = Some(kw);\n                    output.ascii_case_insensitive = true;\n                }\n                EnumMeta::UsePhf(kw) => {\n                    if let Some(fst_kw) = use_phf_kw {\n                        return Err(occurrence_error(fst_kw, kw, \"use_phf\"));\n                    }\n\n                    use_phf_kw = Some(kw);\n                    output.use_phf = true;\n                }\n                EnumMeta::Crate {\n                    crate_module_path,\n                    kw,\n                } => {\n                    if let Some(fst_kw) = crate_module_path_kw {\n                        return Err(occurrence_error(fst_kw, kw, \"Crate\"));\n                    }\n\n                    crate_module_path_kw = Some(kw);\n                    output.crate_module_path = Some(crate_module_path);\n                }\n            }\n        }\n\n        let mut name_kw = None;\n        let mut vis_kw = None;\n        for meta in discriminants_meta {\n            match meta {\n                EnumDiscriminantsMeta::Derive { paths, .. } => {\n                    output.discriminant_derives.extend(paths);\n                }\n                EnumDiscriminantsMeta::Name { name, kw } => {\n                    if let Some(fst_kw) = name_kw {\n                        return Err(occurrence_error(fst_kw, kw, \"name\"));\n                    }\n\n                    name_kw = Some(kw);\n                    output.discriminant_name = Some(name);\n                }\n                EnumDiscriminantsMeta::Vis { vis, kw } => {\n                    if let Some(fst_kw) = vis_kw {\n                        return Err(occurrence_error(fst_kw, kw, \"vis\"));\n                    }\n\n                    vis_kw = Some(kw);\n                    output.discriminant_vis = Some(vis);\n                }\n                EnumDiscriminantsMeta::Other { path, nested } => {\n                    output.discriminant_others.push(quote! { #path(#nested) });\n                }\n            }\n        }\n\n        Ok(output)\n    }\n}\n\nimpl StrumTypeProperties {\n    pub fn crate_module_path(&self) -> Path {\n        self.crate_module_path\n            .as_ref()\n            .map_or_else(|| parse_quote!(sea_orm::strum), |path| parse_quote!(#path))\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/strum/helpers/variant_props.rs",
    "content": "use std::default::Default;\nuse syn::{Ident, LitStr, Variant};\n\nuse super::metadata::{VariantExt, VariantMeta, kw};\nuse super::occurrence_error;\n\npub trait HasStrumVariantProperties {\n    fn get_variant_properties(&self) -> syn::Result<StrumVariantProperties>;\n}\n\n#[derive(Clone, Eq, PartialEq, Debug, Default)]\npub struct StrumVariantProperties {\n    pub disabled: Option<kw::disabled>,\n    pub default: Option<kw::default>,\n    pub ascii_case_insensitive: Option<bool>,\n    pub message: Option<LitStr>,\n    pub detailed_message: Option<LitStr>,\n    pub documentation: Vec<LitStr>,\n    pub string_props: Vec<(LitStr, LitStr)>,\n    serialize: Vec<LitStr>,\n    to_string: Option<LitStr>,\n    ident: Option<Ident>,\n}\n\nimpl HasStrumVariantProperties for Variant {\n    fn get_variant_properties(&self) -> syn::Result<StrumVariantProperties> {\n        let mut output = StrumVariantProperties {\n            ident: Some(self.ident.clone()),\n            ..Default::default()\n        };\n\n        let mut message_kw = None;\n        let mut detailed_message_kw = None;\n        let mut to_string_kw = None;\n        let mut disabled_kw = None;\n        let mut default_kw = None;\n        let mut ascii_case_insensitive_kw = None;\n        for meta in self.get_metadata()? {\n            match meta {\n                VariantMeta::Message { value, kw } => {\n                    if let Some(fst_kw) = message_kw {\n                        return Err(occurrence_error(fst_kw, kw, \"message\"));\n                    }\n\n                    message_kw = Some(kw);\n                    output.message = Some(value);\n                }\n                VariantMeta::DetailedMessage { value, kw } => {\n                    if let Some(fst_kw) = detailed_message_kw {\n                        return Err(occurrence_error(fst_kw, kw, \"detailed_message\"));\n                    }\n\n                    detailed_message_kw = Some(kw);\n                    output.detailed_message = Some(value);\n                }\n                VariantMeta::Documentation { value } => {\n                    output.documentation.push(value);\n                }\n                VariantMeta::Serialize { value, .. } => {\n                    output.serialize.push(value);\n                }\n                VariantMeta::ToString { value, kw } => {\n                    if let Some(fst_kw) = to_string_kw {\n                        return Err(occurrence_error(fst_kw, kw, \"to_string\"));\n                    }\n\n                    to_string_kw = Some(kw);\n                    output.to_string = Some(value);\n                }\n                VariantMeta::Disabled(kw) => {\n                    if let Some(fst_kw) = disabled_kw {\n                        return Err(occurrence_error(fst_kw, kw, \"disabled\"));\n                    }\n\n                    disabled_kw = Some(kw);\n                    output.disabled = Some(kw);\n                }\n                VariantMeta::Default(kw) => {\n                    if let Some(fst_kw) = default_kw {\n                        return Err(occurrence_error(fst_kw, kw, \"default\"));\n                    }\n\n                    default_kw = Some(kw);\n                    output.default = Some(kw);\n                }\n                VariantMeta::AsciiCaseInsensitive { kw, value } => {\n                    if let Some(fst_kw) = ascii_case_insensitive_kw {\n                        return Err(occurrence_error(fst_kw, kw, \"ascii_case_insensitive\"));\n                    }\n\n                    ascii_case_insensitive_kw = Some(kw);\n                    output.ascii_case_insensitive = Some(value);\n                }\n                VariantMeta::Props { props, .. } => {\n                    output.string_props.extend(props);\n                }\n            }\n        }\n\n        Ok(output)\n    }\n}\n"
  },
  {
    "path": "sea-orm-macros/src/strum/mod.rs",
    "content": "//! Source code adapted from https://github.com/Peternator7/strum\n\n#![allow(dead_code)]\n\npub mod enum_iter;\npub mod helpers;\n"
  },
  {
    "path": "sea-orm-macros/tests/derive_active_enum_test.rs",
    "content": "use sea_orm::{ActiveEnum, entity::prelude::StringLen};\nuse sea_orm_macros::{DeriveActiveEnum, EnumIter};\n\n#[derive(Debug, EnumIter, DeriveActiveEnum, Eq, PartialEq)]\n#[sea_orm(\n    rs_type = \"String\",\n    db_type = \"Enum\",\n    enum_name = \"test_enum\",\n    rename_all = \"camelCase\"\n)]\nenum TestEnum {\n    DefaultVariant,\n    #[sea_orm(rename = \"camelCase\")]\n    VariantCamelCase,\n    #[sea_orm(rename = \"kebab-case\")]\n    VariantKebabCase,\n    #[sea_orm(rename = \"mixed_case\")]\n    VariantMixedCase,\n    #[sea_orm(rename = \"SCREAMING_SNAKE_CASE\")]\n    VariantShoutySnakeCase,\n    #[sea_orm(rename = \"snake_case\")]\n    VariantSnakeCase,\n    #[sea_orm(rename = \"title_case\")]\n    VariantTitleCase,\n    #[sea_orm(rename = \"UPPERCASE\")]\n    VariantUpperCase,\n    #[sea_orm(rename = \"lowercase\")]\n    VariantLowerCase,\n    #[sea_orm(rename = \"SCREAMING-KEBAB-CASE\")]\n    VariantScreamingKebabCase,\n    #[sea_orm(rename = \"PascalCase\")]\n    VariantPascalCase,\n    #[sea_orm(string_value = \"CuStOmStRiNgVaLuE\")]\n    CustomStringValue,\n}\n\n#[derive(Debug, EnumIter, DeriveActiveEnum, Eq, PartialEq)]\n#[sea_orm(\n    rs_type = \"String\",\n    db_type = \"Enum\",\n    enum_name = \"test_enum\",\n    rename_all = \"camelCase\"\n)]\nenum TestRenameAllWithoutCasesEnum {\n    HelloWorld,\n}\n\n#[derive(Debug, EnumIter, DeriveActiveEnum, Eq, PartialEq)]\n#[sea_orm(\n    rs_type = \"String\",\n    db_type = \"String(StringLen::None)\",\n    rename_all = \"snake_case\"\n)]\npub enum TestEnum2 {\n    HelloWorld,\n    #[sea_orm(rename = \"camelCase\")]\n    HelloWorldTwo,\n}\n\n#[derive(Debug, EnumIter, DeriveActiveEnum, Eq, PartialEq)]\n#[sea_orm(\n    rs_type = \"String\",\n    db_type = \"String(StringLen::None)\",\n    rename_all = \"snake_case\"\n)]\npub enum TestEnum3 {\n    HelloWorld,\n}\n\n#[test]\nfn derive_active_enum_value() {\n    assert_eq!(TestEnum::DefaultVariant.to_value(), \"defaultVariant\");\n    assert_eq!(TestEnum::VariantCamelCase.to_value(), \"variantCamelCase\");\n    assert_eq!(TestEnum::VariantKebabCase.to_value(), \"variant-kebab-case\");\n    assert_eq!(TestEnum::VariantMixedCase.to_value(), \"variantMixedCase\");\n    assert_eq!(\n        TestEnum::VariantShoutySnakeCase.to_value(),\n        \"VARIANT_SHOUTY_SNAKE_CASE\"\n    );\n    assert_eq!(TestEnum::VariantSnakeCase.to_value(), \"variant_snake_case\");\n    assert_eq!(TestEnum::VariantTitleCase.to_value(), \"Variant Title Case\");\n    assert_eq!(TestEnum::VariantUpperCase.to_value(), \"VARIANTUPPERCASE\");\n    assert_eq!(TestEnum::VariantLowerCase.to_value(), \"variantlowercase\");\n    assert_eq!(\n        TestEnum::VariantScreamingKebabCase.to_value(),\n        \"VARIANT-SCREAMING-KEBAB-CASE\"\n    );\n    assert_eq!(TestEnum::VariantPascalCase.to_value(), \"VariantPascalCase\");\n    assert_eq!(TestEnum::CustomStringValue.to_value(), \"CuStOmStRiNgVaLuE\");\n}\n\n#[test]\nfn derive_active_enum_from_value() {\n    assert_eq!(\n        TestEnum::try_from_value(&\"defaultVariant\".to_string()),\n        Ok(TestEnum::DefaultVariant)\n    );\n    assert_eq!(\n        TestEnum::try_from_value(&\"variantCamelCase\".to_string()),\n        Ok(TestEnum::VariantCamelCase)\n    );\n    assert_eq!(\n        TestEnum::try_from_value(&\"variant-kebab-case\".to_string()),\n        Ok(TestEnum::VariantKebabCase)\n    );\n    assert_eq!(\n        TestEnum::try_from_value(&\"variantMixedCase\".to_string()),\n        Ok(TestEnum::VariantMixedCase)\n    );\n    assert_eq!(\n        TestEnum::try_from_value(&\"VARIANT_SHOUTY_SNAKE_CASE\".to_string()),\n        Ok(TestEnum::VariantShoutySnakeCase),\n    );\n    assert_eq!(\n        TestEnum::try_from_value(&\"variant_snake_case\".to_string()),\n        Ok(TestEnum::VariantSnakeCase)\n    );\n    assert_eq!(\n        TestEnum::try_from_value(&\"Variant Title Case\".to_string()),\n        Ok(TestEnum::VariantTitleCase)\n    );\n    assert_eq!(\n        TestEnum::try_from_value(&\"VARIANTUPPERCASE\".to_string()),\n        Ok(TestEnum::VariantUpperCase)\n    );\n    assert_eq!(\n        TestEnum::try_from_value(&\"variantlowercase\".to_string()),\n        Ok(TestEnum::VariantLowerCase)\n    );\n    assert_eq!(\n        TestEnum::try_from_value(&\"VARIANT-SCREAMING-KEBAB-CASE\".to_string()),\n        Ok(TestEnum::VariantScreamingKebabCase),\n    );\n    assert_eq!(\n        TestEnum::try_from_value(&\"VariantPascalCase\".to_string()),\n        Ok(TestEnum::VariantPascalCase)\n    );\n    assert_eq!(\n        TestEnum::try_from_value(&\"CuStOmStRiNgVaLuE\".to_string()),\n        Ok(TestEnum::CustomStringValue)\n    );\n}\n\n#[test]\nfn derive_active_enum_value_2() {\n    assert_eq!(TestEnum2::HelloWorld.to_value(), \"hello_world\");\n    assert_eq!(TestEnum2::HelloWorldTwo.to_value(), \"helloWorldTwo\");\n\n    assert_eq!(TestEnum3::HelloWorld.to_value(), \"hello_world\");\n    assert_eq!(\n        TestRenameAllWithoutCasesEnum::HelloWorld.to_value(),\n        \"helloWorld\"\n    );\n}\n"
  },
  {
    "path": "sea-orm-macros/tests/derive_entity_model_auto_increment_test.rs",
    "content": "use sea_orm::entity::prelude::*;\nuse sea_orm_macros::DeriveEntityModel;\n\nmod string_pk {\n    use super::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"string_pk\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod string_pk_set_true {\n    use super::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"string_pk\")]\n    pub struct Model {\n        #[sea_orm(primary_key, auto_increment = true)]\n        pub id: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[test]\nfn test_auto_increment_default_by_type() {\n    assert!(!string_pk::PrimaryKey::auto_increment());\n    assert!(string_pk_set_true::PrimaryKey::auto_increment());\n}\n"
  },
  {
    "path": "sea-orm-macros/tests/derive_entity_model_column_name_test.rs",
    "content": "use std::str::FromStr;\n\nuse sea_orm::Iden;\nuse sea_orm::Iterable;\nuse sea_orm::prelude::*;\nuse sea_orm_macros::DeriveEntityModel;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"user\", rename_all = \"camelCase\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    id: i32,\n    username: String,\n    first_name: String,\n    middle_name: String,\n    #[sea_orm(column_name = \"lAsTnAmE\")]\n    last_name: String,\n    orders_count: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[test]\nfn test_column_names() {\n    let columns: Vec<String> = Column::iter().map(|item| item.to_string()).collect();\n\n    assert_eq!(\n        columns,\n        vec![\n            \"id\",\n            \"username\",\n            \"firstName\",\n            \"middleName\",\n            \"lAsTnAmE\",\n            \"ordersCount\",\n        ]\n    );\n\n    let col =\n        Column::from_str(\"firstName\").expect(\"column from str should recognize column_name attr\");\n    assert!(matches!(col, Column::FirstName));\n    let col =\n        Column::from_str(\"first_name\").expect(\"column from str should recognize column_name attr\");\n    assert!(matches!(col, Column::FirstName));\n\n    let col =\n        Column::from_str(\"lastName\").expect(\"column from str should recognize column_name attr\");\n    assert!(matches!(col, Column::LastName));\n    let col =\n        Column::from_str(\"last_name\").expect(\"column from str should recognize column_name attr\");\n    assert!(matches!(col, Column::LastName));\n    let col =\n        Column::from_str(\"lAsTnAmE\").expect(\"column from str should recognize column_name attr\");\n    assert!(matches!(col, Column::LastName));\n}\n"
  },
  {
    "path": "sea-orm-macros/tests/derive_value_type_test.rs",
    "content": "#[test]\nfn when_user_import_nothing_macro_still_works_test() {\n    #[derive(sea_orm::DeriveValueType)]\n    struct MyString(String);\n}\n\n#[test]\nfn when_user_alias_result_macro_still_works_test() {\n    #[allow(dead_code)]\n    type Result<T> = std::result::Result<T, ()>;\n    #[derive(sea_orm::DeriveValueType)]\n    struct MyString(String);\n}\n\n#[test]\nfn when_stringy_newtype_works_test() {\n    #[allow(dead_code)]\n    #[derive(sea_orm::DeriveValueType)]\n    #[sea_orm(value_type = \"String\")]\n    struct Foo {\n        inner: i32,\n    }\n\n    impl std::fmt::Display for Foo {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            self.inner.fmt(f)\n        }\n    }\n\n    impl std::str::FromStr for Foo {\n        type Err = std::num::ParseIntError;\n\n        fn from_str(s: &str) -> Result<Self, Self::Err> {\n            Ok(Self { inner: s.parse()? })\n        }\n    }\n}\n\n#[test]\nfn when_explicit_stringy_newtype_works_test() {\n    #[derive(sea_orm::DeriveValueType)]\n    #[sea_orm(value_type = \"String\")]\n    struct Foo(i32);\n\n    impl std::fmt::Display for Foo {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            self.0.fmt(f)\n        }\n    }\n\n    impl std::str::FromStr for Foo {\n        type Err = std::num::ParseIntError;\n\n        fn from_str(s: &str) -> Result<Self, Self::Err> {\n            Ok(Self(s.parse()?))\n        }\n    }\n}\n\n#[test]\nfn when_custom_from_str_works() {\n    #[derive(sea_orm::DeriveValueType)]\n    #[sea_orm(\n        value_type = \"String\",\n        from_str = \"Foo::from_str\",\n        to_str = \"Foo::to_str\"\n    )]\n    struct Foo(i32);\n\n    impl Foo {\n        fn from_str(_s: &str) -> Result<Self, std::convert::Infallible> {\n            Ok(Self(42))\n        }\n\n        fn to_str(&self) -> String {\n            42.to_string()\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nauthors       = [\"Billy Chan <ccw.billy.123@gmail.com>\"]\ncategories    = [\"database\"]\ndescription   = \"Migration utility for SeaORM\"\ndocumentation = \"https://docs.rs/sea-orm\"\nedition       = \"2024\"\nhomepage      = \"https://www.sea-ql.org/SeaORM\"\nkeywords      = [\"async\", \"orm\", \"mysql\", \"postgres\", \"sqlite\"]\nlicense       = \"MIT OR Apache-2.0\"\nname          = \"sea-orm-migration\"\nrepository    = \"https://github.com/SeaQL/sea-orm\"\nrust-version  = \"1.85.0\"\nversion       = \"2.0.0-rc.37\"\n\n[lib]\nname = \"sea_orm_migration\"\npath = \"src/lib.rs\"\n\n[dependencies]\nasync-trait = { version = \"0.1\", default-features = false }\nclap = { version = \"4.3\", features = [\"env\", \"derive\"], optional = true }\ndotenvy = { version = \"0.15\", default-features = false, optional = true }\nsea-orm = { version = \"~2.0.0-rc.37\", path = \"../\", features = [\n    \"schema-sync\",\n] }\nsea-orm-cli = { version = \"~2.0.0-rc.37\", path = \"../sea-orm-cli\", default-features = false, optional = true }\nsea-schema = { version = \"0.17.0-rc\", default-features = false, features = [\n    \"discovery\",\n    \"writer\",\n    \"probe\",\n] }\ntracing = { version = \"0.1\", default-features = false, features = [\"log\"] }\ntracing-subscriber = { version = \"0.3.17\", default-features = false, features = [\n    \"env-filter\",\n    \"fmt\",\n] }\n\n[dev-dependencies]\ntokio = { version = \"1\", features = [\"rt-multi-thread\", \"macros\"] }\n\n[features]\ncli = [\"clap\", \"dotenvy\", \"sea-orm-cli/cli\"]\ndefault = [\"cli\"]\nentity-registry = [\"sea-orm/entity-registry\"]\nruntime-async-std = [\n    \"sea-orm/runtime-async-std\",\n    \"sea-schema/runtime-async-std\",\n    \"sea-orm-cli?/runtime-async-std\",\n]\nruntime-async-std-native-tls = [\n    \"sea-orm/runtime-async-std-native-tls\",\n    \"sea-schema/runtime-async-std-native-tls\",\n    \"sea-orm-cli?/runtime-async-std-native-tls\",\n]\nruntime-async-std-rustls = [\n    \"sea-orm/runtime-async-std-rustls\",\n    \"sea-schema/runtime-async-std-rustls\",\n    \"sea-orm-cli?/runtime-async-std-rustls\",\n]\nruntime-tokio = [\n    \"sea-orm/runtime-tokio\",\n    \"sea-schema/runtime-tokio\",\n    \"sea-orm-cli?/runtime-tokio\",\n]\nruntime-tokio-native-tls = [\n    \"sea-orm/runtime-tokio-native-tls\",\n    \"sea-schema/runtime-tokio-native-tls\",\n    \"sea-orm-cli?/runtime-tokio-native-tls\",\n]\nruntime-tokio-rustls = [\n    \"sea-orm/runtime-tokio-rustls\",\n    \"sea-schema/runtime-tokio-rustls\",\n    \"sea-orm-cli?/runtime-tokio-rustls\",\n]\nsqlite-use-returning-for-3_35 = [\"sea-orm/sqlite-use-returning-for-3_35\"]\nsqlx-all = [\"sqlx-mysql\", \"sqlx-postgres\", \"sqlx-sqlite\"]\nsqlx-dep = []\nsqlx-mysql = [\"sqlx-dep\", \"sea-orm/sqlx-mysql\", \"sea-orm-cli?/sqlx-mysql\"]\nsqlx-postgres = [\n    \"sqlx-dep\",\n    \"sea-orm/sqlx-postgres\",\n    \"sea-orm-cli?/sqlx-postgres\",\n]\nsqlx-sqlite = [\"sqlx-dep\", \"sea-orm/sqlx-sqlite\", \"sea-orm-cli?/sqlx-sqlite\"]\nwith-bigdecimal = [\"sea-orm/with-bigdecimal\"]\nwith-chrono = [\"sea-orm/with-chrono\"]\nwith-ipnetwork = [\"sea-orm/with-ipnetwork\"]\nwith-json = [\"sea-orm/with-json\"]\nwith-rust_decimal = [\"sea-orm/with-rust_decimal\"]\nwith-time = [\"sea-orm/with-time\"]\nwith-uuid = [\"sea-orm/with-uuid\"]\n\n[patch.crates-io]\n# sea-query = { path = \"../sea-query\" }\n"
  },
  {
    "path": "sea-orm-migration/README.md",
    "content": "# SeaORM CLI\n\nInstall and Usage: \n\n```sh\n> cargo install sea-orm-cli \n> sea-orm-cli help\n```\n\nOr: \n\n```sh\n> cargo install --bin sea\n> sea help\n```\n\nGetting Help:\n\n```sh\ncargo run -- -h\n```\n\n## Running Entity Generator:\n\n```sh\n# MySQL (`--database-schema` option is ignored)\ncargo run -- generate entity -u mysql://sea:sea@localhost/bakery -o out\n\n# SQLite (`--database-schema` option is ignored)\ncargo run -- generate entity -u sqlite://bakery.db -o out\n\n# PostgreSQL\ncargo run -- generate entity -u postgres://sea:sea@localhost/bakery -s public -o out\n```\n\n## Running Migration:\n\n- Initialize migration directory\n    ```sh\n    cargo run -- migrate init\n    ```\n- Apply all pending migrations\n    ```sh\n    cargo run -- migrate\n    ```\n    ```sh\n    cargo run -- migrate up\n    ```\n- Apply first 10 pending migrations\n    ```sh\n    cargo run -- migrate up -n 10\n    ```\n- Rollback last applied migrations\n    ```sh\n    cargo run -- migrate down\n    ```\n- Rollback last 10 applied migrations\n    ```sh\n    cargo run -- migrate down -n 10\n    ```\n- Drop all tables from the database, then reapply all migrations\n    ```sh\n    cargo run -- migrate fresh\n    ```\n- Rollback all applied migrations, then reapply all migrations\n    ```sh\n    cargo run -- migrate refresh\n    ```\n- Rollback all applied migrations\n    ```sh\n    cargo run -- migrate reset\n    ```\n- Check the status of all migrations\n    ```sh\n    cargo run -- migrate status\n    ```\n\n"
  },
  {
    "path": "sea-orm-migration/src/cli.rs",
    "content": "use std::future::Future;\n\nuse clap::Parser;\nuse dotenvy::dotenv;\nuse std::{error::Error, fmt::Display, process::exit};\nuse tracing_subscriber::{EnvFilter, prelude::*};\n\nuse sea_orm::{ConnectOptions, Database, DbConn, DbErr};\nuse sea_orm_cli::{MigrateSubcommands, run_migrate_generate, run_migrate_init};\n\nuse super::MigratorTraitSelf;\n\nconst MIGRATION_DIR: &str = \"./\";\n\npub async fn run_cli<M>(migrator: M)\nwhere\n    M: MigratorTraitSelf,\n{\n    run_cli_with_connection(migrator, Database::connect).await;\n}\n\n/// Same as [`run_cli`] where you provide the function to create the [`DbConn`].\n///\n/// This allows configuring the database connection as you see fit.\n/// E.g. you can change settings in [`ConnectOptions`] or you can load sqlite\n/// extensions.\npub async fn run_cli_with_connection<M, F, Fut>(migrator: M, make_connection: F)\nwhere\n    M: MigratorTraitSelf,\n    F: FnOnce(ConnectOptions) -> Fut,\n    Fut: Future<Output = Result<DbConn, DbErr>>,\n{\n    dotenv().ok();\n    let cli = Cli::parse();\n\n    let url = cli\n        .database_url\n        .expect(\"Environment variable 'DATABASE_URL' not set\");\n    let schema = cli.database_schema.unwrap_or_else(|| \"public\".to_owned());\n\n    let connect_options = ConnectOptions::new(url)\n        .set_schema_search_path(schema)\n        .to_owned();\n\n    let db = make_connection(connect_options)\n        .await\n        .expect(\"Fail to acquire database connection\");\n\n    run_migrate(migrator, &db, cli.command, cli.verbose)\n        .await\n        .unwrap_or_else(handle_error);\n}\n\npub async fn run_migrate<M>(\n    migrator: M,\n    db: &DbConn,\n    command: Option<MigrateSubcommands>,\n    verbose: bool,\n) -> Result<(), Box<dyn Error>>\nwhere\n    M: MigratorTraitSelf,\n{\n    let filter = match verbose {\n        true => \"debug\",\n        false => \"sea_orm_migration=info\",\n    };\n\n    let filter_layer = EnvFilter::try_new(filter).unwrap();\n\n    if verbose {\n        let fmt_layer = tracing_subscriber::fmt::layer();\n        tracing_subscriber::registry()\n            .with(filter_layer)\n            .with(fmt_layer)\n            .init()\n    } else {\n        let fmt_layer = tracing_subscriber::fmt::layer()\n            .with_target(false)\n            .with_level(false)\n            .without_time();\n        tracing_subscriber::registry()\n            .with(filter_layer)\n            .with(fmt_layer)\n            .init()\n    };\n\n    match command {\n        Some(MigrateSubcommands::Fresh) => migrator.fresh(db).await?,\n        Some(MigrateSubcommands::Refresh) => migrator.refresh(db).await?,\n        Some(MigrateSubcommands::Reset) => migrator.reset(db).await?,\n        Some(MigrateSubcommands::Status) => migrator.status(db).await?,\n        Some(MigrateSubcommands::Up { num }) => migrator.up(db, num).await?,\n        Some(MigrateSubcommands::Down { num }) => migrator.down(db, Some(num)).await?,\n        Some(MigrateSubcommands::Init) => run_migrate_init(MIGRATION_DIR)?,\n        Some(MigrateSubcommands::Generate {\n            migration_name,\n            universal_time: _,\n            local_time,\n        }) => run_migrate_generate(MIGRATION_DIR, &migration_name, !local_time)?,\n        _ => migrator.up(db, None).await?,\n    };\n\n    Ok(())\n}\n\n#[derive(Parser)]\n#[command(version)]\npub struct Cli {\n    #[arg(short = 'v', long, global = true, help = \"Show debug messages\")]\n    verbose: bool,\n\n    #[arg(\n        global = true,\n        short = 's',\n        long,\n        env = \"DATABASE_SCHEMA\",\n        long_help = \"Database schema\\n \\\n                    - For MySQL and SQLite, this argument is ignored.\\n \\\n                    - For PostgreSQL, this argument is optional with default value 'public'.\\n\"\n    )]\n    database_schema: Option<String>,\n\n    #[arg(\n        global = true,\n        short = 'u',\n        long,\n        env = \"DATABASE_URL\",\n        help = \"Database URL\"\n    )]\n    database_url: Option<String>,\n\n    #[command(subcommand)]\n    command: Option<MigrateSubcommands>,\n}\n\nfn handle_error<E>(error: E)\nwhere\n    E: Display,\n{\n    eprintln!(\"{error}\");\n    exit(1);\n}\n"
  },
  {
    "path": "sea-orm-migration/src/connection.rs",
    "content": "pub use sea_orm::{\n    DatabaseExecutor as SchemaManagerConnection,\n    IntoDatabaseExecutor as IntoSchemaManagerConnection,\n};\n"
  },
  {
    "path": "sea-orm-migration/src/lib.rs",
    "content": "#[cfg(feature = \"cli\")]\npub mod cli;\npub mod connection;\npub mod manager;\npub mod migrator;\npub mod prelude;\npub mod schema;\npub mod seaql_migrations;\npub mod util;\n\npub use connection::*;\npub use manager::*;\npub use migrator::*;\n\npub use async_trait;\npub use sea_orm;\npub use sea_orm::DbErr;\npub use sea_orm::sea_query;\n\npub trait MigrationName {\n    fn name(&self) -> &str;\n}\n\n/// The migration definition\n#[async_trait::async_trait]\npub trait MigrationTrait: MigrationName + Send + Sync {\n    /// Define actions to perform when applying the migration\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr>;\n\n    /// Define actions to perform when rolling back the migration\n    async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> {\n        Err(DbErr::Migration(\"We Don't Do That Here\".to_owned()))\n    }\n\n    /// Control whether this migration runs inside a transaction.\n    ///\n    /// - `None` (default): follow backend convention (Postgres = transaction, MySQL/SQLite = no transaction)\n    /// - `Some(true)`: force wrapping in a transaction on any backend\n    /// - `Some(false)`: disable automatic transaction wrapping (use `manager.begin()` for manual control)\n    fn use_transaction(&self) -> Option<bool> {\n        None\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/src/manager.rs",
    "content": "use super::{IntoSchemaManagerConnection, SchemaManagerConnection};\nuse sea_orm::sea_query::{\n    ForeignKeyCreateStatement, ForeignKeyDropStatement, IndexCreateStatement, IndexDropStatement,\n    SelectStatement, TableAlterStatement, TableCreateStatement, TableDropStatement,\n    TableRenameStatement, TableTruncateStatement,\n    extension::postgres::{TypeAlterStatement, TypeCreateStatement, TypeDropStatement},\n};\nuse sea_orm::{ConnectionTrait, DbBackend, DbErr, StatementBuilder, TransactionTrait};\n#[allow(unused_imports)]\nuse sea_schema::probe::SchemaProbe;\n\n/// Helper struct for writing migration scripts in migration file\npub struct SchemaManager<'c> {\n    conn: SchemaManagerConnection<'c>,\n}\n\nimpl<'c> SchemaManager<'c> {\n    pub fn new<T>(conn: T) -> Self\n    where\n        T: IntoSchemaManagerConnection<'c>,\n    {\n        Self {\n            conn: conn.into_database_executor(),\n        }\n    }\n\n    pub async fn execute<S>(&self, stmt: S) -> Result<(), DbErr>\n    where\n        S: StatementBuilder,\n    {\n        self.conn.execute(&stmt).await.map(|_| ())\n    }\n\n    #[doc(hidden)]\n    pub async fn exec_stmt<S>(&self, stmt: S) -> Result<(), DbErr>\n    where\n        S: StatementBuilder,\n    {\n        self.conn.execute(&stmt).await.map(|_| ())\n    }\n\n    pub fn get_database_backend(&self) -> DbBackend {\n        self.conn.get_database_backend()\n    }\n\n    pub fn get_connection(&self) -> &SchemaManagerConnection<'c> {\n        &self.conn\n    }\n}\n\n/// Transaction Control\nimpl SchemaManager<'_> {\n    /// Begin a new transaction, returning an owned `SchemaManager` backed by it.\n    ///\n    /// Useful in migrations with `use_transaction() -> Some(false)` for manual\n    /// transaction management (e.g., separating DDL and DML into distinct transactions).\n    pub async fn begin(&self) -> Result<SchemaManager<'static>, DbErr> {\n        let txn = self.conn.begin().await?;\n        Ok(SchemaManager {\n            conn: SchemaManagerConnection::OwnedTransaction(txn),\n        })\n    }\n\n    /// Commit the owned transaction. Only valid on a `SchemaManager` created by [`begin()`](Self::begin).\n    pub async fn commit(self) -> Result<(), DbErr> {\n        match self.conn {\n            SchemaManagerConnection::OwnedTransaction(txn) => txn.commit().await,\n            _ => Err(DbErr::Custom(\n                \"Cannot commit: SchemaManager does not own a transaction\".into(),\n            )),\n        }\n    }\n}\n\n/// Schema Creation\nimpl SchemaManager<'_> {\n    pub async fn create_table(&self, stmt: TableCreateStatement) -> Result<(), DbErr> {\n        self.execute(stmt).await\n    }\n\n    pub async fn create_index(&self, stmt: IndexCreateStatement) -> Result<(), DbErr> {\n        self.execute(stmt).await\n    }\n\n    pub async fn create_foreign_key(&self, stmt: ForeignKeyCreateStatement) -> Result<(), DbErr> {\n        self.execute(stmt).await\n    }\n\n    pub async fn create_type(&self, stmt: TypeCreateStatement) -> Result<(), DbErr> {\n        self.execute(stmt).await\n    }\n}\n\n/// Schema Mutation\nimpl SchemaManager<'_> {\n    pub async fn alter_table(&self, stmt: TableAlterStatement) -> Result<(), DbErr> {\n        self.execute(stmt).await\n    }\n\n    pub async fn drop_table(&self, stmt: TableDropStatement) -> Result<(), DbErr> {\n        self.execute(stmt).await\n    }\n\n    pub async fn rename_table(&self, stmt: TableRenameStatement) -> Result<(), DbErr> {\n        self.execute(stmt).await\n    }\n\n    pub async fn truncate_table(&self, stmt: TableTruncateStatement) -> Result<(), DbErr> {\n        self.execute(stmt).await\n    }\n\n    pub async fn drop_index(&self, stmt: IndexDropStatement) -> Result<(), DbErr> {\n        self.execute(stmt).await\n    }\n\n    pub async fn drop_foreign_key(&self, stmt: ForeignKeyDropStatement) -> Result<(), DbErr> {\n        self.execute(stmt).await\n    }\n\n    pub async fn alter_type(&self, stmt: TypeAlterStatement) -> Result<(), DbErr> {\n        self.execute(stmt).await\n    }\n\n    pub async fn drop_type(&self, stmt: TypeDropStatement) -> Result<(), DbErr> {\n        self.execute(stmt).await\n    }\n}\n\n/// Schema Inspection.\nimpl SchemaManager<'_> {\n    pub async fn has_table<T>(&self, table: T) -> Result<bool, DbErr>\n    where\n        T: AsRef<str>,\n    {\n        has_table(&self.conn, table).await\n    }\n\n    pub async fn has_column<T, C>(&self, _table: T, _column: C) -> Result<bool, DbErr>\n    where\n        T: AsRef<str>,\n        C: AsRef<str>,\n    {\n        let _stmt: SelectStatement = match self.conn.get_database_backend() {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DbBackend::MySql => sea_schema::mysql::MySql.has_column(_table, _column),\n            #[cfg(feature = \"sqlx-postgres\")]\n            DbBackend::Postgres => sea_schema::postgres::Postgres.has_column(_table, _column),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DbBackend::Sqlite => sea_schema::sqlite::Sqlite.has_column(_table, _column),\n            #[allow(unreachable_patterns)]\n            other => {\n                return Err(DbErr::BackendNotSupported {\n                    db: other.as_str(),\n                    ctx: \"has_column\",\n                });\n            }\n        };\n\n        #[allow(unreachable_code)]\n        let res = self\n            .conn\n            .query_one(&_stmt)\n            .await?\n            .ok_or_else(|| DbErr::Custom(\"Failed to check column exists\".to_owned()))?;\n\n        res.try_get(\"\", \"has_column\")\n    }\n\n    pub async fn has_index<T, I>(&self, _table: T, _index: I) -> Result<bool, DbErr>\n    where\n        T: AsRef<str>,\n        I: AsRef<str>,\n    {\n        let _stmt: SelectStatement = match self.conn.get_database_backend() {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DbBackend::MySql => sea_schema::mysql::MySql.has_index(_table, _index),\n            #[cfg(feature = \"sqlx-postgres\")]\n            DbBackend::Postgres => sea_schema::postgres::Postgres.has_index(_table, _index),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DbBackend::Sqlite => sea_schema::sqlite::Sqlite.has_index(_table, _index),\n            #[allow(unreachable_patterns)]\n            other => {\n                return Err(DbErr::BackendNotSupported {\n                    db: other.as_str(),\n                    ctx: \"has_index\",\n                });\n            }\n        };\n\n        #[allow(unreachable_code)]\n        let res = self\n            .conn\n            .query_one(&_stmt)\n            .await?\n            .ok_or_else(|| DbErr::Custom(\"Failed to check index exists\".to_owned()))?;\n\n        res.try_get(\"\", \"has_index\")\n    }\n}\n\npub(crate) async fn has_table<C, T>(conn: &C, _table: T) -> Result<bool, DbErr>\nwhere\n    C: ConnectionTrait,\n    T: AsRef<str>,\n{\n    let _stmt: SelectStatement = match conn.get_database_backend() {\n        #[cfg(feature = \"sqlx-mysql\")]\n        DbBackend::MySql => sea_schema::mysql::MySql.has_table(_table),\n        #[cfg(feature = \"sqlx-postgres\")]\n        DbBackend::Postgres => sea_schema::postgres::Postgres.has_table(_table),\n        #[cfg(feature = \"sqlx-sqlite\")]\n        DbBackend::Sqlite => sea_schema::sqlite::Sqlite.has_table(_table),\n        #[allow(unreachable_patterns)]\n        other => {\n            return Err(DbErr::BackendNotSupported {\n                db: other.as_str(),\n                ctx: \"has_table\",\n            });\n        }\n    };\n\n    #[allow(unreachable_code)]\n    let res = conn\n        .query_one(&_stmt)\n        .await?\n        .ok_or_else(|| DbErr::Custom(\"Failed to check table exists\".to_owned()))?;\n\n    res.try_get(\"\", \"has_table\")\n}\n"
  },
  {
    "path": "sea-orm-migration/src/migrator/exec.rs",
    "content": "use std::collections::HashSet;\n#[cfg(not(feature = \"with-time\"))]\nuse std::time::SystemTime;\nuse tracing::info;\n\nuse super::{Migration, MigrationStatus, queries::*};\nuse crate::{SchemaManager, seaql_migrations};\nuse sea_orm::sea_query::{\n    Alias, Expr, ExprTrait, ForeignKey, IntoIden, Order, Query, Table, extension::postgres::Type,\n};\nuse sea_orm::{\n    ActiveValue, ConnectionTrait, DbBackend, DbErr, DynIden, EntityTrait, FromQueryResult,\n    Iterable, QueryFilter, Schema, Statement, TransactionSession, TransactionTrait,\n};\n\npub async fn get_migration_models<C>(\n    db: &C,\n    migration_table_name: DynIden,\n) -> Result<Vec<seaql_migrations::Model>, DbErr>\nwhere\n    C: ConnectionTrait,\n{\n    let stmt = Query::select()\n        .table_name(migration_table_name)\n        .columns(seaql_migrations::Column::iter().map(IntoIden::into_iden))\n        .order_by(seaql_migrations::Column::Version, Order::Asc)\n        .take();\n\n    db.query_all(&stmt)\n        .await?\n        .into_iter()\n        .map(|row| seaql_migrations::Model::from_query_result(&row, \"\"))\n        .collect()\n}\n\npub fn get_migration_with_status(\n    migration_files: Vec<Migration>,\n    migration_models: Vec<seaql_migrations::Model>,\n) -> Result<Vec<Migration>, DbErr> {\n    let mut migration_files = migration_files;\n\n    let migration_in_db: HashSet<String> = migration_models\n        .into_iter()\n        .map(|model| model.version)\n        .collect();\n    let migration_in_fs: HashSet<String> = migration_files\n        .iter()\n        .map(|file| file.migration.name().to_string())\n        .collect();\n\n    let pending_migrations = &migration_in_fs - &migration_in_db;\n    for migration_file in migration_files.iter_mut() {\n        if !pending_migrations.contains(migration_file.migration.name()) {\n            migration_file.status = MigrationStatus::Applied;\n        }\n    }\n\n    let missing_migrations_in_fs = &migration_in_db - &migration_in_fs;\n    let errors: Vec<String> = missing_migrations_in_fs\n            .iter()\n            .map(|missing_migration| {\n                format!(\"Migration file of version '{missing_migration}' is missing, this migration has been applied but its file is missing\")\n            }).collect();\n\n    if !errors.is_empty() {\n        Err(DbErr::Custom(errors.join(\"\\n\")))\n    } else {\n        Ok(migration_files)\n    }\n}\n\npub async fn install<C>(db: &C, migration_table_name: DynIden) -> Result<(), DbErr>\nwhere\n    C: ConnectionTrait,\n{\n    let builder = db.get_database_backend();\n    let schema = Schema::new(builder);\n    let mut stmt = schema\n        .create_table_from_entity(seaql_migrations::Entity)\n        .table_name(migration_table_name);\n    stmt.if_not_exists();\n    db.execute(&stmt).await?;\n    Ok(())\n}\n\npub async fn uninstall(\n    manager: &SchemaManager<'_>,\n    migration_table_name: DynIden,\n) -> Result<(), DbErr> {\n    let mut stmt = Table::drop();\n    stmt.table(migration_table_name).if_exists().cascade();\n    manager.drop_table(stmt).await?;\n    Ok(())\n}\n\npub async fn drop_everything<C: ConnectionTrait + TransactionTrait>(db: &C) -> Result<(), DbErr> {\n    if db.get_database_backend() == DbBackend::Postgres {\n        let transaction = db.begin().await?;\n        drop_everything_impl(&transaction).await?;\n        transaction.commit().await\n    } else {\n        drop_everything_impl(db).await\n    }\n}\n\nasync fn drop_everything_impl<C: ConnectionTrait>(db: &C) -> Result<(), DbErr> {\n    let db_backend = db.get_database_backend();\n\n    // Temporarily disable the foreign key check\n    if db_backend == DbBackend::Sqlite {\n        info!(\"Disabling foreign key check\");\n        db.execute_raw(Statement::from_string(\n            db_backend,\n            \"PRAGMA foreign_keys = OFF\".to_owned(),\n        ))\n        .await?;\n        info!(\"Foreign key check disabled\");\n    }\n\n    // Drop all foreign keys\n    if db_backend == DbBackend::MySql {\n        info!(\"Dropping all foreign keys\");\n        let stmt = query_mysql_foreign_keys(db);\n        let rows = db.query_all(&stmt).await?;\n        for row in rows.into_iter() {\n            let constraint_name: String = row.try_get(\"\", \"CONSTRAINT_NAME\")?;\n            let table_name: String = row.try_get(\"\", \"TABLE_NAME\")?;\n            info!(\n                \"Dropping foreign key '{}' from table '{}'\",\n                constraint_name, table_name\n            );\n            let mut stmt = ForeignKey::drop();\n            stmt.table(Alias::new(table_name.as_str()))\n                .name(constraint_name.as_str());\n            db.execute(&stmt).await?;\n            info!(\"Foreign key '{}' has been dropped\", constraint_name);\n        }\n        info!(\"All foreign keys dropped\");\n    }\n\n    // Drop all tables\n    let stmt = query_tables(db)?;\n    let rows = db.query_all(&stmt).await?;\n    for row in rows.into_iter() {\n        let table_name: String = row.try_get(\"\", \"table_name\")?;\n        info!(\"Dropping table '{}'\", table_name);\n        let mut stmt = Table::drop();\n        stmt.table(Alias::new(table_name.as_str()))\n            .if_exists()\n            .cascade();\n        db.execute(&stmt).await?;\n        info!(\"Table '{}' has been dropped\", table_name);\n    }\n\n    // Drop all types\n    if db_backend == DbBackend::Postgres {\n        info!(\"Dropping all types\");\n        let stmt = query_pg_types(db);\n        let rows = db.query_all(&stmt).await?;\n        for row in rows {\n            let type_name: String = row.try_get(\"\", \"typname\")?;\n            info!(\"Dropping type '{}'\", type_name);\n            let mut stmt = Type::drop();\n            stmt.name(Alias::new(&type_name));\n            db.execute(&stmt).await?;\n            info!(\"Type '{}' has been dropped\", type_name);\n        }\n    }\n\n    // Restore the foreign key check\n    if db_backend == DbBackend::Sqlite {\n        info!(\"Restoring foreign key check\");\n        db.execute_raw(Statement::from_string(\n            db_backend,\n            \"PRAGMA foreign_keys = ON\".to_owned(),\n        ))\n        .await?;\n        info!(\"Foreign key check restored\");\n    }\n\n    Ok(())\n}\n\nfn should_use_transaction(migration: &dyn crate::MigrationTrait, backend: DbBackend) -> bool {\n    match migration.use_transaction() {\n        Some(v) => v,\n        None => backend == DbBackend::Postgres,\n    }\n}\n\nasync fn insert_migration_record<C: ConnectionTrait>(\n    db: &C,\n    name: &str,\n    migration_table_name: DynIden,\n) -> Result<(), DbErr> {\n    #[cfg(not(feature = \"with-time\"))]\n    let applied_at = SystemTime::now()\n        .duration_since(SystemTime::UNIX_EPOCH)\n        .expect(\"SystemTime before UNIX EPOCH!\")\n        .as_secs() as i64;\n    #[cfg(feature = \"with-time\")]\n    let applied_at = sea_orm::prelude::TimeDateTimeWithTimeZone::now_utc().unix_timestamp();\n    seaql_migrations::Entity::insert(seaql_migrations::ActiveModel {\n        version: ActiveValue::Set(name.to_owned()),\n        applied_at: ActiveValue::Set(applied_at),\n    })\n    .table_name(migration_table_name)\n    .exec(db)\n    .await?;\n    Ok(())\n}\n\nasync fn delete_migration_record<C: ConnectionTrait>(\n    db: &C,\n    name: &str,\n    migration_table_name: DynIden,\n) -> Result<(), DbErr> {\n    seaql_migrations::Entity::delete_many()\n        .filter(Expr::col(seaql_migrations::Column::Version).eq(name))\n        .table_name(migration_table_name)\n        .exec(db)\n        .await?;\n    Ok(())\n}\n\npub async fn exec_up_with(\n    manager: &SchemaManager<'_>,\n    mut steps: Option<u32>,\n    pending_migrations: Vec<Migration>,\n    migration_table_name: DynIden,\n) -> Result<(), DbErr> {\n    let db = manager.get_connection();\n\n    if let Some(steps) = steps {\n        info!(\"Applying {} pending migrations\", steps);\n    } else {\n        info!(\"Applying all pending migrations\");\n    }\n    if pending_migrations.is_empty() {\n        info!(\"No pending migrations\");\n    }\n\n    for Migration { migration, .. } in pending_migrations {\n        if let Some(steps) = steps.as_mut() {\n            if steps == &0 {\n                break;\n            }\n            *steps -= 1;\n        }\n\n        let use_txn = should_use_transaction(migration.as_ref(), db.get_database_backend());\n        info!(\"Applying migration '{}'\", migration.name());\n\n        if use_txn {\n            let transaction = db.begin().await?;\n            let txn_manager = SchemaManager::new(&transaction);\n            migration.up(&txn_manager).await?;\n            info!(\"Migration '{}' has been applied\", migration.name());\n            insert_migration_record(&transaction, migration.name(), migration_table_name.clone())\n                .await?;\n            transaction.commit().await?;\n        } else {\n            migration.up(manager).await?;\n            info!(\"Migration '{}' has been applied\", migration.name());\n            insert_migration_record(db, migration.name(), migration_table_name.clone()).await?;\n        }\n    }\n\n    Ok(())\n}\n\npub async fn exec_down_with(\n    manager: &SchemaManager<'_>,\n    mut steps: Option<u32>,\n    applied_migrations: Vec<Migration>,\n    migration_table_name: DynIden,\n) -> Result<(), DbErr> {\n    let db = manager.get_connection();\n\n    if let Some(steps) = steps {\n        info!(\"Rolling back {} applied migrations\", steps);\n    } else {\n        info!(\"Rolling back all applied migrations\");\n    }\n    if applied_migrations.is_empty() {\n        info!(\"No applied migrations\");\n    }\n\n    for Migration { migration, .. } in applied_migrations.into_iter().rev() {\n        if let Some(steps) = steps.as_mut() {\n            if steps == &0 {\n                break;\n            }\n            *steps -= 1;\n        }\n\n        let use_txn = should_use_transaction(migration.as_ref(), db.get_database_backend());\n        info!(\"Rolling back migration '{}'\", migration.name());\n\n        if use_txn {\n            let transaction = db.begin().await?;\n            let txn_manager = SchemaManager::new(&transaction);\n            migration.down(&txn_manager).await?;\n            info!(\"Migration '{}' has been rolled back\", migration.name());\n            delete_migration_record(&transaction, migration.name(), migration_table_name.clone())\n                .await?;\n            transaction.commit().await?;\n        } else {\n            migration.down(manager).await?;\n            info!(\"Migration '{}' has been rolled back\", migration.name());\n            delete_migration_record(db, migration.name(), migration_table_name.clone()).await?;\n        }\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-migration/src/migrator/queries.rs",
    "content": "use sea_orm::sea_query::{self, Expr, ExprTrait, Query, SelectStatement, SimpleExpr};\nuse sea_orm::{\n    ActiveModelTrait, Condition, ConnectionTrait, DbErr, DeriveIden, DynIden, EntityTrait,\n};\n#[allow(unused_imports)]\nuse sea_schema::probe::SchemaProbe;\n\npub fn query_tables<C>(db: &C) -> Result<SelectStatement, DbErr>\nwhere\n    C: ConnectionTrait,\n{\n    #[allow(unused_imports)]\n    use sea_orm::DbBackend;\n\n    match db.get_database_backend() {\n        #[cfg(feature = \"sqlx-mysql\")]\n        DbBackend::MySql => Ok(sea_schema::mysql::MySql.query_tables()),\n        #[cfg(feature = \"sqlx-postgres\")]\n        DbBackend::Postgres => Ok(sea_schema::postgres::Postgres.query_tables()),\n        #[cfg(feature = \"sqlx-sqlite\")]\n        DbBackend::Sqlite => Ok(sea_schema::sqlite::Sqlite.query_tables()),\n        #[allow(unreachable_patterns)]\n        other => Err(DbErr::BackendNotSupported {\n            db: other.as_str(),\n            ctx: \"query_tables\",\n        }),\n    }\n}\n\n// this function is only called after checking db backend, the panic is unreachable\npub fn get_current_schema<C>(db: &C) -> SimpleExpr\nwhere\n    C: ConnectionTrait,\n{\n    #[allow(unused_imports)]\n    use sea_orm::DbBackend;\n\n    match db.get_database_backend() {\n        #[cfg(feature = \"sqlx-mysql\")]\n        DbBackend::MySql => sea_schema::mysql::MySql::get_current_schema(),\n        #[cfg(feature = \"sqlx-postgres\")]\n        DbBackend::Postgres => sea_schema::postgres::Postgres::get_current_schema(),\n        #[cfg(feature = \"sqlx-sqlite\")]\n        DbBackend::Sqlite => sea_schema::sqlite::Sqlite::get_current_schema(),\n        #[allow(unreachable_patterns)]\n        other => panic!(\"{other:?} feature is off\"),\n    }\n}\n\n#[derive(DeriveIden)]\nenum InformationSchema {\n    #[sea_orm(iden = \"information_schema\")]\n    Schema,\n    #[sea_orm(iden = \"TABLE_NAME\")]\n    TableName,\n    #[sea_orm(iden = \"CONSTRAINT_NAME\")]\n    ConstraintName,\n    TableConstraints,\n    TableSchema,\n    ConstraintType,\n}\n\npub fn query_mysql_foreign_keys<C>(db: &C) -> SelectStatement\nwhere\n    C: ConnectionTrait,\n{\n    let mut stmt = Query::select();\n    stmt.columns([\n        InformationSchema::TableName,\n        InformationSchema::ConstraintName,\n    ])\n    .from((\n        InformationSchema::Schema,\n        InformationSchema::TableConstraints,\n    ))\n    .cond_where(\n        Condition::all()\n            .add(get_current_schema(db).equals((\n                InformationSchema::TableConstraints,\n                InformationSchema::TableSchema,\n            )))\n            .add(\n                Expr::col((\n                    InformationSchema::TableConstraints,\n                    InformationSchema::ConstraintType,\n                ))\n                .eq(\"FOREIGN KEY\"),\n            ),\n    );\n    stmt\n}\n\n#[derive(DeriveIden)]\nenum PgType {\n    Table,\n    Oid,\n    Typname,\n    Typnamespace,\n    Typelem,\n}\n\n#[derive(DeriveIden)]\nenum PgDepend {\n    Table,\n    Objid,\n    Deptype,\n    Refclassid,\n}\n\n#[derive(DeriveIden)]\nenum PgNamespace {\n    Table,\n    Oid,\n    Nspname,\n}\n\npub fn query_pg_types<C>(db: &C) -> SelectStatement\nwhere\n    C: ConnectionTrait,\n{\n    Query::select()\n        .column(PgType::Typname)\n        .from(PgType::Table)\n        .left_join(\n            PgNamespace::Table,\n            Expr::col((PgNamespace::Table, PgNamespace::Oid))\n                .equals((PgType::Table, PgType::Typnamespace)),\n        )\n        .left_join(\n            PgDepend::Table,\n            Expr::col((PgDepend::Table, PgDepend::Objid))\n                .equals((PgType::Table, PgType::Oid))\n                .and(\n                    Expr::col((PgDepend::Table, PgDepend::Refclassid))\n                        .eq(Expr::cust(\"'pg_extension'::regclass::oid\")),\n                )\n                .and(Expr::col((PgDepend::Table, PgDepend::Deptype)).eq(Expr::cust(\"'e'\"))),\n        )\n        .and_where(get_current_schema(db).equals((PgNamespace::Table, PgNamespace::Nspname)))\n        .and_where(Expr::col((PgType::Table, PgType::Typelem)).eq(0))\n        .and_where(Expr::col((PgDepend::Table, PgDepend::Objid)).is_null())\n        .take()\n}\n\npub trait QueryTable {\n    type Statement;\n\n    fn table_name(self, table_name: DynIden) -> Self::Statement;\n}\n\nimpl QueryTable for SelectStatement {\n    type Statement = SelectStatement;\n\n    fn table_name(mut self, table_name: DynIden) -> SelectStatement {\n        self.from(table_name);\n        self\n    }\n}\n\nimpl QueryTable for sea_query::TableCreateStatement {\n    type Statement = sea_query::TableCreateStatement;\n\n    fn table_name(mut self, table_name: DynIden) -> sea_query::TableCreateStatement {\n        self.table(table_name);\n        self\n    }\n}\n\nimpl<A> QueryTable for sea_orm::Insert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    type Statement = sea_orm::Insert<A>;\n\n    fn table_name(mut self, table_name: DynIden) -> sea_orm::Insert<A> {\n        sea_orm::QueryTrait::query(&mut self).into_table(table_name);\n        self\n    }\n}\n\nimpl<E> QueryTable for sea_orm::DeleteMany<E>\nwhere\n    E: EntityTrait,\n{\n    type Statement = sea_orm::DeleteMany<E>;\n\n    fn table_name(mut self, table_name: DynIden) -> sea_orm::DeleteMany<E> {\n        sea_orm::QueryTrait::query(&mut self).from_table(table_name);\n        self\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/src/migrator/with_self.rs",
    "content": "use super::{Migration, MigrationStatus, exec::*};\nuse crate::{IntoSchemaManagerConnection, MigrationTrait, SchemaManager, seaql_migrations};\nuse sea_orm::sea_query::IntoIden;\nuse sea_orm::{ConnectionTrait, DbErr, DynIden};\n\nuse tracing::info;\n\n/// Performing migrations on a database\n#[async_trait::async_trait]\npub trait MigratorTraitSelf: Sized + Send + Sync {\n    /// Vector of migrations in time sequence\n    fn migrations(&self) -> Vec<Box<dyn MigrationTrait>>;\n\n    /// Name of the migration table, it is `seaql_migrations` by default\n    fn migration_table_name(&self) -> DynIden {\n        seaql_migrations::Entity.into_iden()\n    }\n\n    /// Get list of migrations wrapped in `Migration` struct\n    fn get_migration_files(&self) -> Vec<Migration> {\n        self.migrations()\n            .into_iter()\n            .map(|migration| Migration {\n                migration,\n                status: MigrationStatus::Pending,\n            })\n            .collect()\n    }\n\n    /// Get list of applied migrations from database\n    async fn get_migration_models<C>(&self, db: &C) -> Result<Vec<seaql_migrations::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.install(db).await?;\n        get_migration_models(db, self.migration_table_name()).await\n    }\n\n    /// Get list of migrations with status\n    async fn get_migration_with_status<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.install(db).await?;\n        get_migration_with_status(\n            self.get_migration_files(),\n            self.get_migration_models(db).await?,\n        )\n    }\n\n    /// Get list of pending migrations\n    async fn get_pending_migrations<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.install(db).await?;\n        Ok(self\n            .get_migration_with_status(db)\n            .await?\n            .into_iter()\n            .filter(|file| file.status == MigrationStatus::Pending)\n            .collect())\n    }\n\n    /// Get list of applied migrations\n    async fn get_applied_migrations<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.install(db).await?;\n        Ok(self\n            .get_migration_with_status(db)\n            .await?\n            .into_iter()\n            .filter(|file| file.status == MigrationStatus::Applied)\n            .collect())\n    }\n\n    /// Create migration table `seaql_migrations` in the database\n    async fn install<C>(&self, db: &C) -> Result<(), DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        install(db, self.migration_table_name()).await\n    }\n\n    /// Check the status of all migrations\n    async fn status<C>(&self, db: &C) -> Result<(), DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.install(db).await?;\n\n        info!(\"Checking migration status\");\n\n        for Migration { migration, status } in self.get_migration_with_status(db).await? {\n            info!(\"Migration '{}'... {}\", migration.name(), status);\n        }\n\n        Ok(())\n    }\n\n    /// Drop all tables from the database, then reapply all migrations\n    async fn fresh<'c, C>(&self, db: C) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        let db = db.into_database_executor();\n        let manager = SchemaManager::new(db);\n        exec_fresh(self, &manager).await\n    }\n\n    /// Rollback all applied migrations, then reapply all migrations\n    async fn refresh<'c, C>(&self, db: C) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        let db = db.into_database_executor();\n        let manager = SchemaManager::new(db);\n        exec_down(self, &manager, None).await?;\n        exec_up(self, &manager, None).await\n    }\n\n    /// Rollback all applied migrations\n    async fn reset<'c, C>(&self, db: C) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        let db = db.into_database_executor();\n        let manager = SchemaManager::new(db);\n        exec_down(self, &manager, None).await?;\n        uninstall(&manager, self.migration_table_name()).await\n    }\n\n    /// Uninstall migration tracking table only (non-destructive)\n    /// This will drop the `seaql_migrations` table but won't rollback other schema changes.\n    async fn uninstall<'c, C>(&self, db: C) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        let db = db.into_database_executor();\n        let manager = SchemaManager::new(db);\n        uninstall(&manager, self.migration_table_name()).await\n    }\n\n    /// Apply pending migrations\n    async fn up<'c, C>(&self, db: C, steps: Option<u32>) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        let db = db.into_database_executor();\n        let manager = SchemaManager::new(db);\n        exec_up(self, &manager, steps).await\n    }\n\n    /// Rollback applied migrations\n    async fn down<'c, C>(&self, db: C, steps: Option<u32>) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        let db = db.into_database_executor();\n        let manager = SchemaManager::new(db);\n        exec_down(self, &manager, steps).await\n    }\n}\n\n#[async_trait::async_trait]\nimpl<M> MigratorTraitSelf for M\nwhere\n    M: super::MigratorTrait + Sized + Send + Sync,\n{\n    fn migrations(&self) -> Vec<Box<dyn MigrationTrait>> {\n        M::migrations()\n    }\n\n    fn migration_table_name(&self) -> DynIden {\n        M::migration_table_name()\n    }\n\n    fn get_migration_files(&self) -> Vec<Migration> {\n        M::get_migration_files()\n    }\n\n    async fn get_migration_models<C>(&self, db: &C) -> Result<Vec<seaql_migrations::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        M::get_migration_models(db).await\n    }\n\n    async fn get_migration_with_status<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        M::get_migration_with_status(db).await\n    }\n\n    async fn get_pending_migrations<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        M::get_pending_migrations(db).await\n    }\n\n    async fn get_applied_migrations<C>(&self, db: &C) -> Result<Vec<Migration>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        M::get_applied_migrations(db).await\n    }\n\n    async fn install<C>(&self, db: &C) -> Result<(), DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        M::install(db).await\n    }\n\n    /// Check the status of all migrations\n    async fn status<C>(&self, db: &C) -> Result<(), DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        M::status(db).await\n    }\n\n    async fn fresh<'c, C>(&self, db: C) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        M::fresh(db).await\n    }\n\n    async fn refresh<'c, C>(&self, db: C) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        M::refresh(db).await\n    }\n\n    async fn reset<'c, C>(&self, db: C) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        M::reset(db).await\n    }\n\n    async fn uninstall<'c, C>(&self, db: C) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        M::uninstall(db).await\n    }\n\n    async fn up<'c, C>(&self, db: C, steps: Option<u32>) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        M::up(db, steps).await\n    }\n\n    async fn down<'c, C>(&self, db: C, steps: Option<u32>) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        M::down(db, steps).await\n    }\n}\n\nasync fn exec_fresh<M>(migrator: &M, manager: &SchemaManager<'_>) -> Result<(), DbErr>\nwhere\n    M: MigratorTraitSelf,\n{\n    let db = manager.get_connection();\n\n    migrator.install(db).await?;\n\n    drop_everything(db).await?;\n\n    exec_up(migrator, manager, None).await\n}\n\nasync fn exec_up<M>(\n    migrator: &M,\n    manager: &SchemaManager<'_>,\n    steps: Option<u32>,\n) -> Result<(), DbErr>\nwhere\n    M: MigratorTraitSelf,\n{\n    let db = manager.get_connection();\n\n    migrator.install(db).await?;\n\n    exec_up_with(\n        manager,\n        steps,\n        migrator.get_pending_migrations(db).await?,\n        migrator.migration_table_name(),\n    )\n    .await\n}\n\nasync fn exec_down<M>(\n    migrator: &M,\n    manager: &SchemaManager<'_>,\n    steps: Option<u32>,\n) -> Result<(), DbErr>\nwhere\n    M: MigratorTraitSelf,\n{\n    let db = manager.get_connection();\n\n    migrator.install(db).await?;\n\n    exec_down_with(\n        manager,\n        steps,\n        migrator.get_applied_migrations(db).await?,\n        migrator.migration_table_name(),\n    )\n    .await\n}\n"
  },
  {
    "path": "sea-orm-migration/src/migrator.rs",
    "content": "mod queries;\n\nmod exec;\nuse exec::*;\n\nmod with_self;\npub use with_self::*;\n\nuse std::fmt::Display;\nuse tracing::info;\n\nuse super::{IntoSchemaManagerConnection, MigrationTrait, SchemaManager, seaql_migrations};\nuse sea_orm::sea_query::IntoIden;\nuse sea_orm::{ConnectionTrait, DbErr, DynIden};\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\n/// Status of migration\npub enum MigrationStatus {\n    /// Not yet applied\n    Pending,\n    /// Applied\n    Applied,\n}\n\nimpl Display for MigrationStatus {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        let status = match self {\n            MigrationStatus::Pending => \"Pending\",\n            MigrationStatus::Applied => \"Applied\",\n        };\n        write!(f, \"{status}\")\n    }\n}\n\npub struct Migration {\n    migration: Box<dyn MigrationTrait>,\n    status: MigrationStatus,\n}\n\nimpl Migration {\n    /// Get migration name from MigrationName trait implementation\n    pub fn name(&self) -> &str {\n        self.migration.name()\n    }\n\n    /// Get migration status\n    pub fn status(&self) -> MigrationStatus {\n        self.status\n    }\n}\n\n/// Performing migrations on a database\n#[async_trait::async_trait]\npub trait MigratorTrait: Send {\n    /// Vector of migrations in time sequence\n    fn migrations() -> Vec<Box<dyn MigrationTrait>>;\n\n    /// Name of the migration table, it is `seaql_migrations` by default\n    fn migration_table_name() -> DynIden {\n        seaql_migrations::Entity.into_iden()\n    }\n\n    /// Get list of migrations wrapped in `Migration` struct\n    fn get_migration_files() -> Vec<Migration> {\n        Self::migrations()\n            .into_iter()\n            .map(|migration| Migration {\n                migration,\n                status: MigrationStatus::Pending,\n            })\n            .collect()\n    }\n\n    /// Get list of applied migrations from database\n    async fn get_migration_models<C>(db: &C) -> Result<Vec<seaql_migrations::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Self::install(db).await?;\n        get_migration_models(db, Self::migration_table_name()).await\n    }\n\n    /// Get list of migrations with status\n    async fn get_migration_with_status<C>(db: &C) -> Result<Vec<Migration>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Self::install(db).await?;\n        get_migration_with_status(\n            Self::get_migration_files(),\n            Self::get_migration_models(db).await?,\n        )\n    }\n\n    /// Get list of pending migrations\n    async fn get_pending_migrations<C>(db: &C) -> Result<Vec<Migration>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Self::install(db).await?;\n        Ok(Self::get_migration_with_status(db)\n            .await?\n            .into_iter()\n            .filter(|file| file.status == MigrationStatus::Pending)\n            .collect())\n    }\n\n    /// Get list of applied migrations\n    async fn get_applied_migrations<C>(db: &C) -> Result<Vec<Migration>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Self::install(db).await?;\n        Ok(Self::get_migration_with_status(db)\n            .await?\n            .into_iter()\n            .filter(|file| file.status == MigrationStatus::Applied)\n            .collect())\n    }\n\n    /// Create migration table `seaql_migrations` in the database\n    async fn install<C>(db: &C) -> Result<(), DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        install(db, Self::migration_table_name()).await\n    }\n\n    /// Check the status of all migrations\n    async fn status<C>(db: &C) -> Result<(), DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Self::install(db).await?;\n\n        info!(\"Checking migration status\");\n\n        for Migration { migration, status } in Self::get_migration_with_status(db).await? {\n            info!(\"Migration '{}'... {}\", migration.name(), status);\n        }\n\n        Ok(())\n    }\n\n    /// Drop all tables from the database, then reapply all migrations\n    async fn fresh<'c, C>(db: C) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        let db = db.into_database_executor();\n        let manager = SchemaManager::new(db);\n        exec_fresh::<Self>(&manager).await\n    }\n\n    /// Rollback all applied migrations, then reapply all migrations\n    async fn refresh<'c, C>(db: C) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        let db = db.into_database_executor();\n        let manager = SchemaManager::new(db);\n        exec_down::<Self>(&manager, None).await?;\n        exec_up::<Self>(&manager, None).await\n    }\n\n    /// Rollback all applied migrations\n    async fn reset<'c, C>(db: C) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        let db = db.into_database_executor();\n        let manager = SchemaManager::new(db);\n        exec_down::<Self>(&manager, None).await?;\n        uninstall(&manager, Self::migration_table_name()).await\n    }\n\n    /// Uninstall migration tracking table only (non-destructive)\n    /// This will drop the `seaql_migrations` table but won't rollback other schema changes.\n    async fn uninstall<'c, C>(db: C) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        let db = db.into_database_executor();\n        let manager = SchemaManager::new(db);\n        uninstall(&manager, Self::migration_table_name()).await\n    }\n\n    /// Apply pending migrations\n    async fn up<'c, C>(db: C, steps: Option<u32>) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        let db = db.into_database_executor();\n        let manager = SchemaManager::new(db);\n        exec_up::<Self>(&manager, steps).await\n    }\n\n    /// Rollback applied migrations\n    async fn down<'c, C>(db: C, steps: Option<u32>) -> Result<(), DbErr>\n    where\n        C: IntoSchemaManagerConnection<'c>,\n    {\n        let db = db.into_database_executor();\n        let manager = SchemaManager::new(db);\n        exec_down::<Self>(&manager, steps).await\n    }\n}\n\nasync fn exec_fresh<M>(manager: &SchemaManager<'_>) -> Result<(), DbErr>\nwhere\n    M: MigratorTrait + ?Sized,\n{\n    let db = manager.get_connection();\n\n    M::install(db).await?;\n\n    drop_everything(db).await?;\n\n    exec_up::<M>(manager, None).await\n}\n\nasync fn exec_up<M>(manager: &SchemaManager<'_>, steps: Option<u32>) -> Result<(), DbErr>\nwhere\n    M: MigratorTrait + ?Sized,\n{\n    let db = manager.get_connection();\n\n    M::install(db).await?;\n\n    exec_up_with(\n        manager,\n        steps,\n        M::get_pending_migrations(db).await?,\n        M::migration_table_name(),\n    )\n    .await\n}\n\nasync fn exec_down<M>(manager: &SchemaManager<'_>, steps: Option<u32>) -> Result<(), DbErr>\nwhere\n    M: MigratorTrait + ?Sized,\n{\n    let db = manager.get_connection();\n\n    M::install(db).await?;\n\n    exec_down_with(\n        manager,\n        steps,\n        M::get_applied_migrations(db).await?,\n        M::migration_table_name(),\n    )\n    .await\n}\n"
  },
  {
    "path": "sea-orm-migration/src/prelude.rs",
    "content": "#[cfg(feature = \"cli\")]\npub use crate::cli;\n\npub use crate::{\n    IntoSchemaManagerConnection, MigrationName, MigrationTrait, MigratorTrait, SchemaManager,\n    SchemaManagerConnection,\n};\npub use async_trait;\npub use sea_orm::{\n    self, ConnectionTrait, DbErr, DeriveIden, DeriveMigrationName,\n    sea_query::{self, *},\n};\n"
  },
  {
    "path": "sea-orm-migration/src/schema.rs",
    "content": "//! > Adapted from https://github.com/loco-rs/loco/blob/master/src/schema.rs\n//!\n//! # Database Table Schema Helpers\n//!\n//! This module defines functions and helpers for creating database table\n//! schemas using the `sea-orm` and `sea-query` libraries.\n//!\n//! # Example\n//!\n//! The following example shows how the user migration file should be and using\n//! the schema helpers to create the Db fields.\n//!\n//! ```rust\n//! use sea_orm_migration::{prelude::*, schema::*};\n//!\n//! #[derive(DeriveMigrationName)]\n//! pub struct Migration;\n//!\n//! #[async_trait::async_trait]\n//! impl MigrationTrait for Migration {\n//!     async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n//!         let table = table_auto(\"users\")\n//!             .col(pk_auto(\"id\"))\n//!             .col(uuid(\"pid\"))\n//!             .col(string_uniq(\"email\"))\n//!             .col(string(\"password\"))\n//!             .col(string(\"name\"))\n//!             .col(string_null(\"reset_token\"))\n//!             .col(timestamp_null(\"reset_sent_at\"))\n//!             .to_owned();\n//!         manager.create_table(table).await?;\n//!         Ok(())\n//!     }\n//!\n//!     async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n//!         manager\n//!             .drop_table(Table::drop().table(\"users\").to_owned())\n//!             .await\n//!     }\n//! }\n//! ```\n\nuse crate::{prelude::Iden, sea_query};\nuse sea_orm::sea_query::{\n    Alias, ColumnDef, ColumnType, Expr, IntoIden, PgInterval, Table, TableCreateStatement,\n};\n\n#[derive(Iden)]\nenum GeneralIds {\n    CreatedAt,\n    UpdatedAt,\n}\n\n/// Create a table with `created_at` and `updated_at` added by default\npub fn table_auto<T: IntoIden + 'static>(name: T) -> TableCreateStatement {\n    timestamps(Table::create().table(name).if_not_exists().take())\n}\n\n/// Create a primary key column with auto-increment\npub fn pk_auto<T: IntoIden>(name: T) -> ColumnDef {\n    integer(name).auto_increment().primary_key().take()\n}\n\n/// Create a primary key column of big integer with auto-increment\npub fn big_pk_auto<T: IntoIden>(name: T) -> ColumnDef {\n    big_integer(name).auto_increment().primary_key().take()\n}\n\n/// Create a UUID primary key\npub fn pk_uuid<T: IntoIden>(name: T) -> ColumnDef {\n    uuid(name).primary_key().take()\n}\n\npub fn char_len<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    ColumnDef::new(col).char_len(length).not_null().take()\n}\n\npub fn char_len_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    ColumnDef::new(col).char_len(length).null().take()\n}\n\npub fn char_len_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    char_len(col, length).unique_key().take()\n}\n\npub fn char<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).char().not_null().take()\n}\n\npub fn char_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).char().null().take()\n}\n\npub fn char_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    char(col).unique_key().take()\n}\n\npub fn string_len<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    ColumnDef::new(col).string_len(length).not_null().take()\n}\n\npub fn string_len_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    ColumnDef::new(col).string_len(length).null().take()\n}\n\npub fn string_len_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    string_len(col, length).unique_key().take()\n}\n\npub fn string<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).string().not_null().take()\n}\n\npub fn string_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).string().null().take()\n}\n\npub fn string_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    string(col).unique_key().take()\n}\n\npub fn text<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).text().not_null().take()\n}\n\npub fn text_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).text().null().take()\n}\n\npub fn text_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    text(col).unique_key().take()\n}\n\npub fn tiny_integer<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).tiny_integer().not_null().take()\n}\n\npub fn tiny_integer_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).tiny_integer().null().take()\n}\n\npub fn tiny_integer_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    tiny_integer(col).unique_key().take()\n}\n\npub fn small_integer<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).small_integer().not_null().take()\n}\n\npub fn small_integer_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).small_integer().null().take()\n}\n\npub fn small_integer_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    small_integer(col).unique_key().take()\n}\n\npub fn integer<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).integer().not_null().take()\n}\n\npub fn integer_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).integer().null().take()\n}\n\npub fn integer_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    integer(col).unique_key().take()\n}\n\npub fn big_integer<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).big_integer().not_null().take()\n}\n\npub fn big_integer_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).big_integer().null().take()\n}\n\npub fn big_integer_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    big_integer(col).unique_key().take()\n}\n\npub fn tiny_unsigned<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).tiny_unsigned().not_null().take()\n}\n\npub fn tiny_unsigned_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).tiny_unsigned().null().take()\n}\n\npub fn tiny_unsigned_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    tiny_unsigned(col).unique_key().take()\n}\n\npub fn small_unsigned<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).small_unsigned().not_null().take()\n}\n\npub fn small_unsigned_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).small_unsigned().null().take()\n}\n\npub fn small_unsigned_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    small_unsigned(col).unique_key().take()\n}\n\npub fn unsigned<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).unsigned().not_null().take()\n}\n\npub fn unsigned_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).unsigned().null().take()\n}\n\npub fn unsigned_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    unsigned(col).unique_key().take()\n}\n\npub fn big_unsigned<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).big_unsigned().not_null().take()\n}\n\npub fn big_unsigned_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).big_unsigned().null().take()\n}\n\npub fn big_unsigned_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    big_unsigned(col).unique_key().take()\n}\n\npub fn float<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).float().not_null().take()\n}\n\npub fn float_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).float().null().take()\n}\n\npub fn float_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    float(col).unique_key().take()\n}\n\npub fn double<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).double().not_null().take()\n}\n\npub fn double_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).double().null().take()\n}\n\npub fn double_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    double(col).unique_key().take()\n}\n\npub fn decimal_len<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {\n    ColumnDef::new(col)\n        .decimal_len(precision, scale)\n        .not_null()\n        .take()\n}\n\npub fn decimal_len_null<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {\n    ColumnDef::new(col)\n        .decimal_len(precision, scale)\n        .null()\n        .take()\n}\n\npub fn decimal_len_uniq<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {\n    decimal_len(col, precision, scale).unique_key().take()\n}\n\npub fn decimal<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).decimal().not_null().take()\n}\n\npub fn decimal_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).decimal().null().take()\n}\n\npub fn decimal_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    decimal(col).unique_key().take()\n}\n\npub fn date_time<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).date_time().not_null().take()\n}\n\npub fn date_time_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).date_time().null().take()\n}\n\npub fn date_time_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    date_time(col).unique_key().take()\n}\n\npub fn interval<T: IntoIden>(\n    col: T,\n    fields: Option<PgInterval>,\n    precision: Option<u32>,\n) -> ColumnDef {\n    ColumnDef::new(col)\n        .interval(fields, precision)\n        .not_null()\n        .take()\n}\n\npub fn interval_null<T: IntoIden>(\n    col: T,\n    fields: Option<PgInterval>,\n    precision: Option<u32>,\n) -> ColumnDef {\n    ColumnDef::new(col)\n        .interval(fields, precision)\n        .null()\n        .take()\n}\n\npub fn interval_uniq<T: IntoIden>(\n    col: T,\n    fields: Option<PgInterval>,\n    precision: Option<u32>,\n) -> ColumnDef {\n    interval(col, fields, precision).unique_key().take()\n}\n\npub fn timestamp<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).timestamp().not_null().take()\n}\n\npub fn timestamp_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).timestamp().null().take()\n}\n\npub fn timestamp_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    timestamp(col).unique_key().take()\n}\n\npub fn timestamp_with_time_zone<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col)\n        .timestamp_with_time_zone()\n        .not_null()\n        .take()\n}\n\npub fn timestamp_with_time_zone_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).timestamp_with_time_zone().null().take()\n}\n\npub fn timestamp_with_time_zone_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    timestamp_with_time_zone(col).unique_key().take()\n}\n\npub fn time<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).time().not_null().take()\n}\n\npub fn time_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).time().null().take()\n}\n\npub fn time_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    time(col).unique_key().take()\n}\n\npub fn date<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).date().not_null().take()\n}\n\npub fn date_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).date().null().take()\n}\n\npub fn date_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    date(col).unique_key().take()\n}\n\npub fn year<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).year().not_null().take()\n}\n\npub fn year_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).year().null().take()\n}\n\npub fn year_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    year(col).unique_key().take()\n}\n\npub fn binary_len<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    ColumnDef::new(col).binary_len(length).not_null().take()\n}\n\npub fn binary_len_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    ColumnDef::new(col).binary_len(length).null().take()\n}\n\npub fn binary_len_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    binary_len(col, length).unique_key().take()\n}\n\npub fn binary<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).binary().not_null().take()\n}\n\npub fn binary_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).binary().null().take()\n}\n\npub fn binary_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    binary(col).unique_key().take()\n}\n\npub fn var_binary<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    ColumnDef::new(col).var_binary(length).not_null().take()\n}\n\npub fn var_binary_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    ColumnDef::new(col).var_binary(length).null().take()\n}\n\npub fn var_binary_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    var_binary(col, length).unique_key().take()\n}\n\npub fn bit<T: IntoIden>(col: T, length: Option<u32>) -> ColumnDef {\n    ColumnDef::new(col).bit(length).not_null().take()\n}\n\npub fn bit_null<T: IntoIden>(col: T, length: Option<u32>) -> ColumnDef {\n    ColumnDef::new(col).bit(length).null().take()\n}\n\npub fn bit_uniq<T: IntoIden>(col: T, length: Option<u32>) -> ColumnDef {\n    bit(col, length).unique_key().take()\n}\n\npub fn varbit<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    ColumnDef::new(col).varbit(length).not_null().take()\n}\n\npub fn varbit_null<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    ColumnDef::new(col).varbit(length).null().take()\n}\n\npub fn varbit_uniq<T: IntoIden>(col: T, length: u32) -> ColumnDef {\n    varbit(col, length).unique_key().take()\n}\n\npub fn blob<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).blob().not_null().take()\n}\n\npub fn blob_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).blob().null().take()\n}\n\npub fn blob_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    blob(col).unique_key().take()\n}\n\npub fn boolean<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).boolean().not_null().take()\n}\n\npub fn boolean_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).boolean().null().take()\n}\n\npub fn boolean_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    boolean(col).unique_key().take()\n}\n\npub fn money_len<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {\n    ColumnDef::new(col)\n        .money_len(precision, scale)\n        .not_null()\n        .take()\n}\n\npub fn money_len_null<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {\n    ColumnDef::new(col)\n        .money_len(precision, scale)\n        .null()\n        .take()\n}\n\npub fn money_len_uniq<T: IntoIden>(col: T, precision: u32, scale: u32) -> ColumnDef {\n    money_len(col, precision, scale).unique_key().take()\n}\n\npub fn money<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).money().not_null().take()\n}\n\npub fn money_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).money().null().take()\n}\n\npub fn money_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    money(col).unique_key().take()\n}\n\npub fn json<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).json().not_null().take()\n}\n\npub fn json_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).json().null().take()\n}\n\npub fn json_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    json(col).unique_key().take()\n}\n\npub fn json_binary<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).json_binary().not_null().take()\n}\n\npub fn json_binary_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).json_binary().null().take()\n}\n\npub fn json_binary_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    json_binary(col).unique_key().take()\n}\n\npub fn uuid<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).uuid().not_null().take()\n}\n\npub fn uuid_null<T: IntoIden>(col: T) -> ColumnDef {\n    ColumnDef::new(col).uuid().null().take()\n}\n\npub fn uuid_uniq<T: IntoIden>(col: T) -> ColumnDef {\n    uuid(col).unique_key().take()\n}\n\npub fn custom<T: IntoIden, N: IntoIden>(col: T, name: N) -> ColumnDef {\n    ColumnDef::new(col).custom(name).not_null().take()\n}\n\npub fn custom_null<T: IntoIden, N: IntoIden>(col: T, name: N) -> ColumnDef {\n    ColumnDef::new(col).custom(name).null().take()\n}\n\npub fn enumeration<T, N, S, V>(col: T, name: N, variants: V) -> ColumnDef\nwhere\n    T: IntoIden,\n    N: IntoIden,\n    S: IntoIden,\n    V: IntoIterator<Item = S>,\n{\n    ColumnDef::new(col)\n        .enumeration(name, variants)\n        .not_null()\n        .take()\n}\n\npub fn enumeration_null<T, N, S, V>(col: T, name: N, variants: V) -> ColumnDef\nwhere\n    T: IntoIden,\n    N: IntoIden,\n    S: IntoIden,\n    V: IntoIterator<Item = S>,\n{\n    ColumnDef::new(col)\n        .enumeration(name, variants)\n        .null()\n        .take()\n}\n\npub fn enumeration_uniq<T, N, S, V>(col: T, name: N, variants: V) -> ColumnDef\nwhere\n    T: IntoIden,\n    N: IntoIden,\n    S: IntoIden,\n    V: IntoIterator<Item = S>,\n{\n    enumeration(col, name, variants).unique_key().take()\n}\n\npub fn array<T: IntoIden>(col: T, elem_type: ColumnType) -> ColumnDef {\n    ColumnDef::new(col).array(elem_type).not_null().take()\n}\n\npub fn array_null<T: IntoIden>(col: T, elem_type: ColumnType) -> ColumnDef {\n    ColumnDef::new(col).array(elem_type).null().take()\n}\n\npub fn array_uniq<T: IntoIden>(col: T, elem_type: ColumnType) -> ColumnDef {\n    array(col, elem_type).unique_key().take()\n}\n\n/// Add timestamp columns (`CreatedAt` and `UpdatedAt`) to an existing table.\npub fn timestamps(t: TableCreateStatement) -> TableCreateStatement {\n    let mut t = t;\n    t.col(timestamp(GeneralIds::CreatedAt).default(Expr::current_timestamp()))\n        .col(timestamp(GeneralIds::UpdatedAt).default(Expr::current_timestamp()))\n        .take()\n}\n\n/// Create an Alias.\npub fn name<T: Into<String>>(name: T) -> Alias {\n    Alias::new(name)\n}\n"
  },
  {
    "path": "sea-orm-migration/src/seaql_migrations.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n// One should override the name of migration table via `MigratorTrait::migration_table_name` method\n#[sea_orm(table_name = \"seaql_migrations\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub version: String,\n    pub applied_at: i64,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-migration/src/util.rs",
    "content": "pub fn get_file_stem(path: &str) -> &str {\n    std::path::Path::new(path)\n        .file_stem()\n        .map(|f| f.to_str().unwrap())\n        .unwrap()\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_get_file_stem() {\n        let pair = vec![\n            (\n                \"m20220101_000001_create_table.rs\",\n                \"m20220101_000001_create_table\",\n            ),\n            (\n                \"src/m20220101_000001_create_table.rs\",\n                \"m20220101_000001_create_table\",\n            ),\n            (\n                \"migration/src/m20220101_000001_create_table.rs\",\n                \"m20220101_000001_create_table\",\n            ),\n            (\n                \"/migration/src/m20220101_000001_create_table.tmp.rs\",\n                \"m20220101_000001_create_table.tmp\",\n            ),\n        ];\n        for (path, expect) in pair {\n            assert_eq!(get_file_stem(path), expect);\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migration/m20220118_000001_create_cake_table.rs",
    "content": "use sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"cake\")\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"name\"))\n                    .to_owned(),\n            )\n            .await?;\n\n        manager\n            .create_index(\n                Index::create()\n                    .name(\"cake_name_index\")\n                    .table(\"cake\")\n                    .col(\"name\")\n                    .to_owned(),\n            )\n            .await?;\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .drop_table(Table::drop().table(\"cake\").to_owned())\n            .await?;\n\n        if std::env::var_os(\"ABORT_MIGRATION\").eq(&Some(\"YES\".into())) {\n            return Err(DbErr::Migration(\n                \"Abort migration and rollback changes\".into(),\n            ));\n        }\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migration/m20220118_000002_create_fruit_table.rs",
    "content": "use sea_orm_migration::sea_orm::DbBackend;\nuse sea_orm_migration::{prelude::*, schema::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"fruit\")\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"name\"))\n                    .col(integer(\"cake_id\"))\n                    .foreign_key(\n                        ForeignKey::create()\n                            .name(\"fk-fruit-cake_id\")\n                            .from(\"fruit\", \"cake_id\")\n                            .to(\"cake\", \"id\"),\n                    )\n                    .to_owned(),\n            )\n            .await\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        if manager.get_database_backend() != DbBackend::Sqlite {\n            manager\n                .drop_foreign_key(\n                    ForeignKey::drop()\n                        .table(\"fruit\")\n                        .name(\"fk-fruit-cake_id\")\n                        .to_owned(),\n                )\n                .await?;\n        }\n        manager\n            .drop_table(Table::drop().table(\"fruit\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migration/m20220118_000003_seed_cake_table.rs",
    "content": "use sea_orm_migration::prelude::*;\nuse sea_orm_migration::sea_orm::{entity::*, query::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        cake::ActiveModel {\n            name: Set(\"Cheesecake\".to_owned()),\n            ..Default::default()\n        }\n        .insert(db)\n        .await?;\n\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        cake::Entity::delete_many()\n            .filter(cake::Column::Name.eq(\"Cheesecake\"))\n            .exec(db)\n            .await?;\n\n        Ok(())\n    }\n}\n\nmod cake {\n    use sea_orm_migration::sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"cake\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migration/m20220118_000004_create_tea_enum.rs",
    "content": "use sea_orm_migration::prelude::{sea_query::extension::postgres::Type, *};\nuse sea_orm_migration::sea_orm::{ConnectionTrait, DbBackend};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        if db.get_database_backend() == DbBackend::Postgres {\n            manager\n                .create_type(\n                    Type::create()\n                        .as_enum(Tea::Enum)\n                        .values([Tea::EverydayTea, Tea::BreakfastTea])\n                        .to_owned(),\n                )\n                .await?;\n        }\n\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        if db.get_database_backend() == DbBackend::Postgres {\n            manager\n                .drop_type(Type::drop().name(Tea::Enum).to_owned())\n                .await?;\n        }\n\n        Ok(())\n    }\n}\n\n#[derive(DeriveIden)]\npub enum Tea {\n    #[sea_orm(iden = \"tea\")]\n    Enum,\n    #[sea_orm(iden = \"EverydayTea\")]\n    EverydayTea,\n    #[sea_orm(iden = \"BreakfastTea\")]\n    BreakfastTea,\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migration/m20220923_000001_seed_cake_table.rs",
    "content": "use sea_orm_migration::prelude::*;\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let insert = Query::insert()\n            .into_table(\"cake\")\n            .columns([\"name\"])\n            .values_panic([\"Tiramisu\".into()])\n            .to_owned();\n\n        manager.execute(insert).await?;\n\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let delete = Query::delete()\n            .from_table(\"cake\")\n            .and_where(Expr::col(\"name\").eq(\"Tiramisu\"))\n            .to_owned();\n\n        manager.execute(delete).await?;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migration/m20230109_000001_seed_cake_table.rs",
    "content": "use sea_orm_migration::prelude::*;\nuse sea_orm_migration::sea_orm::{entity::*, query::*};\n\n#[derive(DeriveMigrationName)]\npub struct Migration;\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let transaction = db.begin().await?;\n\n        cake::ActiveModel {\n            name: Set(\"Cheesecake\".to_owned()),\n            ..Default::default()\n        }\n        .insert(&transaction)\n        .await?;\n\n        if std::env::var_os(\"ABORT_MIGRATION\").eq(&Some(\"YES\".into())) {\n            return Err(DbErr::Migration(\n                \"Abort migration and rollback changes\".into(),\n            ));\n        }\n\n        transaction.commit().await?;\n\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let db = manager.get_connection();\n\n        let transaction = db.begin().await?;\n\n        cake::Entity::delete_many()\n            .filter(cake::Column::Name.eq(\"Cheesecake\"))\n            .exec(&transaction)\n            .await?;\n\n        transaction.commit().await?;\n\n        Ok(())\n    }\n}\n\nmod cake {\n    use sea_orm_migration::sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"cake\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migration/m20250101_000001_create_test_table.rs",
    "content": "use sea_orm_migration::prelude::*;\nuse sea_orm_migration::schema::*;\nuse sea_orm_migration::sea_orm::DbBackend;\n\npub struct Migration {\n    pub use_transaction: Option<bool>,\n    pub should_fail: bool,\n}\n\nimpl MigrationName for Migration {\n    fn name(&self) -> &str {\n        \"m20250101_000001_create_test_table\"\n    }\n}\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    fn use_transaction(&self) -> Option<bool> {\n        self.use_transaction\n    }\n\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let expect_txn = self\n            .use_transaction\n            .unwrap_or(manager.get_database_backend() == DbBackend::Postgres);\n        assert_eq!(\n            manager.get_connection().is_transaction(),\n            expect_txn,\n            \"up: expected is_transaction() = {expect_txn}\"\n        );\n\n        manager\n            .create_table(\n                Table::create()\n                    .table(\"test_table\")\n                    .col(pk_auto(\"id\"))\n                    .col(string(\"name\"))\n                    .to_owned(),\n            )\n            .await?;\n\n        if self.should_fail {\n            return Err(DbErr::Migration(\"intentional failure\".into()));\n        }\n\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let expect_txn = self\n            .use_transaction\n            .unwrap_or(manager.get_database_backend() == DbBackend::Postgres);\n        assert_eq!(\n            manager.get_connection().is_transaction(),\n            expect_txn,\n            \"down: expected is_transaction() = {expect_txn}\"\n        );\n\n        manager\n            .drop_table(Table::drop().table(\"test_table\").to_owned())\n            .await\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migration/m20250101_000002_manual_transaction.rs",
    "content": "use sea_orm_migration::prelude::*;\nuse sea_orm_migration::schema::*;\n\npub struct Migration;\n\nimpl MigrationName for Migration {\n    fn name(&self) -> &str {\n        \"m20250101_000002_manual_transaction\"\n    }\n}\n\n#[async_trait::async_trait]\nimpl MigrationTrait for Migration {\n    fn use_transaction(&self) -> Option<bool> {\n        Some(false)\n    }\n\n    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        assert!(\n            !manager.get_connection().is_transaction(),\n            \"outer manager should not be in a transaction\"\n        );\n\n        let m = manager.begin().await?;\n        assert!(\n            m.get_connection().is_transaction(),\n            \"inner manager should be in a transaction\"\n        );\n        m.create_table(\n            Table::create()\n                .table(\"manual_txn_table\")\n                .col(pk_auto(\"id\"))\n                .col(string(\"name\"))\n                .to_owned(),\n        )\n        .await?;\n        m.commit().await?;\n\n        Ok(())\n    }\n\n    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {\n        let m = manager.begin().await?;\n        m.drop_table(Table::drop().table(\"manual_txn_table\").to_owned())\n            .await?;\n        m.commit().await?;\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migration/mod.rs",
    "content": "pub mod m20220118_000001_create_cake_table;\npub mod m20220118_000002_create_fruit_table;\npub mod m20220118_000003_seed_cake_table;\npub mod m20220118_000004_create_tea_enum;\npub mod m20220923_000001_seed_cake_table;\npub mod m20230109_000001_seed_cake_table;\npub mod m20250101_000001_create_test_table;\npub mod m20250101_000002_manual_transaction;\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migrator/default.rs",
    "content": "use crate::common::migration::*;\nuse sea_orm_migration::prelude::*;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220118_000001_create_cake_table::Migration),\n            Box::new(m20220118_000002_create_fruit_table::Migration),\n            Box::new(m20220118_000003_seed_cake_table::Migration),\n            Box::new(m20220118_000004_create_tea_enum::Migration),\n            Box::new(m20220923_000001_seed_cake_table::Migration),\n            Box::new(m20230109_000001_seed_cake_table::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migrator/mod.rs",
    "content": "pub mod default;\npub mod override_migration_table_name;\npub mod transaction_test;\npub mod with_self;\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migrator/override_migration_table_name.rs",
    "content": "use crate::common::migration::*;\nuse sea_orm_migration::prelude::*;\n\npub struct Migrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for Migrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220118_000001_create_cake_table::Migration),\n            Box::new(m20220118_000002_create_fruit_table::Migration),\n            Box::new(m20220118_000003_seed_cake_table::Migration),\n            Box::new(m20220118_000004_create_tea_enum::Migration),\n            Box::new(m20220923_000001_seed_cake_table::Migration),\n            Box::new(m20230109_000001_seed_cake_table::Migration),\n        ]\n    }\n\n    fn migration_table_name() -> sea_orm::DynIden {\n        \"override_migration_table_name\".into_iden()\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migrator/transaction_test.rs",
    "content": "use crate::common::migration::*;\nuse sea_orm_migration::{MigratorTraitSelf, prelude::*};\n\npub struct Migrator {\n    pub use_transaction: Option<bool>,\n    pub should_fail: bool,\n}\n\n#[async_trait::async_trait]\nimpl MigratorTraitSelf for Migrator {\n    fn migrations(&self) -> Vec<Box<dyn MigrationTrait>> {\n        vec![Box::new(m20250101_000001_create_test_table::Migration {\n            use_transaction: self.use_transaction,\n            should_fail: self.should_fail,\n        })]\n    }\n}\n\npub struct ManualTxnMigrator;\n\n#[async_trait::async_trait]\nimpl MigratorTrait for ManualTxnMigrator {\n    fn migrations() -> Vec<Box<dyn MigrationTrait>> {\n        vec![Box::new(m20250101_000002_manual_transaction::Migration)]\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/migrator/with_self.rs",
    "content": "use crate::common::migration::*;\nuse sea_orm_migration::{MigratorTraitSelf, prelude::*};\n\npub struct Migrator {\n    pub i: i32,\n}\n\n#[async_trait::async_trait]\nimpl MigratorTraitSelf for Migrator {\n    fn migrations(&self) -> Vec<Box<dyn MigrationTrait>> {\n        vec![\n            Box::new(m20220118_000001_create_cake_table::Migration),\n            Box::new(m20220118_000002_create_fruit_table::Migration),\n            Box::new(m20220118_000003_seed_cake_table::Migration),\n            Box::new(m20220118_000004_create_tea_enum::Migration),\n            Box::new(m20220923_000001_seed_cake_table::Migration),\n            Box::new(m20230109_000001_seed_cake_table::Migration),\n        ]\n    }\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/common/mod.rs",
    "content": "pub mod migration;\npub mod migrator;\n"
  },
  {
    "path": "sea-orm-migration/tests/main.rs",
    "content": "mod common;\n\nuse common::migrator::*;\nuse sea_orm::{ConnectOptions, ConnectionTrait, Database, DbBackend, DbErr, Statement};\nuse sea_orm_migration::{MigratorTraitSelf, migrator::MigrationStatus, prelude::*};\n\n#[tokio::test]\nasync fn main() -> Result<(), DbErr> {\n    tracing_subscriber::fmt()\n        .with_max_level(tracing::Level::DEBUG)\n        .with_test_writer()\n        .init();\n\n    let url = &std::env::var(\"DATABASE_URL\").expect(\"Environment variable 'DATABASE_URL' not set\");\n\n    run_migration(url, default::Migrator, \"sea_orm_migration\", \"public\").await?;\n    run_migration(\n        url,\n        default::Migrator,\n        \"sea_orm_migration_schema\",\n        \"my_schema\",\n    )\n    .await?;\n\n    run_migration(\n        url,\n        with_self::Migrator { i: 12 },\n        \"sea_orm_migration_self\",\n        \"public\",\n    )\n    .await?;\n\n    run_migration(\n        url,\n        override_migration_table_name::Migrator,\n        \"sea_orm_migration_table_name\",\n        \"public\",\n    )\n    .await?;\n    run_migration(\n        url,\n        override_migration_table_name::Migrator,\n        \"sea_orm_migration_table_name_schema\",\n        \"my_schema\",\n    )\n    .await?;\n\n    run_transaction_test(url, \"sea_orm_migration_txn\", \"public\").await?;\n\n    Ok(())\n}\n\nasync fn create_db(\n    url: &str,\n    db_name: &str,\n    schema: &str,\n) -> Result<sea_orm::DatabaseConnection, DbErr> {\n    let db_connect = |url: String| async {\n        let connect_options = ConnectOptions::new(url)\n            .set_schema_search_path(format!(\"{schema},public\"))\n            .to_owned();\n\n        Database::connect(connect_options).await\n    };\n\n    let db = db_connect(url.to_owned()).await?;\n\n    match db.get_database_backend() {\n        DbBackend::MySql => {\n            db.execute_raw(Statement::from_string(\n                db.get_database_backend(),\n                format!(\"CREATE DATABASE IF NOT EXISTS `{db_name}`;\"),\n            ))\n            .await?;\n\n            let url = format!(\"{url}/{db_name}\");\n            db_connect(url).await\n        }\n        DbBackend::Postgres => {\n            db.execute_raw(Statement::from_string(\n                db.get_database_backend(),\n                format!(\"DROP DATABASE IF EXISTS \\\"{db_name}\\\";\"),\n            ))\n            .await?;\n            db.execute_raw(Statement::from_string(\n                db.get_database_backend(),\n                format!(\"CREATE DATABASE \\\"{db_name}\\\";\"),\n            ))\n            .await?;\n\n            let url = format!(\"{url}/{db_name}\");\n            let db = db_connect(url).await?;\n\n            db.execute_raw(Statement::from_string(\n                db.get_database_backend(),\n                format!(\"CREATE SCHEMA IF NOT EXISTS \\\"{schema}\\\";\"),\n            ))\n            .await?;\n\n            Ok(db)\n        }\n        DbBackend::Sqlite => Ok(db),\n        db => Err(DbErr::BackendNotSupported {\n            db: db.as_str(),\n            ctx: \"create_db\",\n        }),\n    }\n}\n\nasync fn run_migration<M>(url: &str, migrator: M, db_name: &str, schema: &str) -> Result<(), DbErr>\nwhere\n    M: MigratorTraitSelf,\n{\n    let db = &create_db(url, db_name, schema).await?;\n    let manager = SchemaManager::new(db);\n\n    println!(\"\\nMigrator::status\");\n    migrator.status(db).await?;\n\n    println!(\"\\nMigrator::install\");\n    migrator.install(db).await?;\n\n    let migration_table_name = migrator.migration_table_name().to_string();\n    let migration_table_name = migration_table_name.as_str();\n    assert!(manager.has_table(migration_table_name).await?);\n    if migration_table_name != \"seaql_migrations\" {\n        assert!(!manager.has_table(\"seaql_migrations\").await?);\n    }\n\n    println!(\"\\nMigrator::reset\");\n    migrator.reset(db).await?;\n\n    assert!(!manager.has_table(\"cake\").await?);\n    assert!(!manager.has_table(\"fruit\").await?);\n\n    println!(\"\\nMigrator::up\");\n    migrator.up(db, Some(0)).await?;\n\n    assert!(!manager.has_table(\"cake\").await?);\n    assert!(!manager.has_table(\"fruit\").await?);\n\n    println!(\"\\nMigrator::up\");\n    migrator.up(db, Some(1)).await?;\n\n    println!(\"\\nMigrator::get_pending_migrations\");\n    let migrations = migrator.get_pending_migrations(db).await?;\n    assert_eq!(migrations.len(), 5);\n\n    let migration = migrations.get(0).unwrap();\n    assert_eq!(migration.name(), \"m20220118_000002_create_fruit_table\");\n    assert_eq!(migration.status(), MigrationStatus::Pending);\n\n    assert!(manager.has_table(\"cake\").await?);\n    assert!(!manager.has_table(\"fruit\").await?);\n\n    println!(\"\\nMigrator::down\");\n    migrator.down(db, Some(0)).await?;\n\n    assert!(manager.has_table(\"cake\").await?);\n    assert!(!manager.has_table(\"fruit\").await?);\n\n    println!(\"\\nMigrator::down\");\n    migrator.down(db, Some(1)).await?;\n\n    assert!(!manager.has_table(\"cake\").await?);\n    assert!(!manager.has_table(\"fruit\").await?);\n\n    // Tests rolling back a failing migration on Postgres.\n    // With per-migration transactions, only the failing migration is rolled back;\n    // earlier migrations that committed successfully are preserved.\n    if matches!(db.get_database_backend(), DbBackend::Postgres) {\n        println!(\"\\nRoll back changes when encounter errors\");\n\n        // Set a flag to throw error inside `m20230109_000001_seed_cake_table.rs`\n        unsafe {\n            std::env::set_var(\"ABORT_MIGRATION\", \"YES\");\n        }\n\n        // Should throw an error\n        println!(\"\\nMigrator::up\");\n        assert_eq!(\n            migrator.up(db, None).await,\n            Err(DbErr::Migration(\n                \"Abort migration and rollback changes\".into()\n            ))\n        );\n\n        println!(\"\\nMigrator::status\");\n        migrator.status(db).await?;\n\n        // Only the failing migration (m20230109) is rolled back;\n        // earlier migrations (cake, fruit, etc.) committed successfully\n        assert!(manager.has_table(\"cake\").await?);\n        assert!(manager.has_table(\"fruit\").await?);\n\n        // Unset the flag\n        unsafe {\n            std::env::remove_var(\"ABORT_MIGRATION\");\n        }\n    }\n\n    println!(\"\\nMigrator::up\");\n    migrator.up(db, None).await?;\n\n    println!(\"\\nMigrator::get_applied_migrations\");\n    let migrations = migrator.get_applied_migrations(db).await?;\n    assert_eq!(migrations.len(), 6);\n\n    assert!(!manager.has_index(\"cake\", \"non_existent_index\").await?);\n    assert!(manager.has_index(\"cake\", \"cake_name_index\").await?);\n\n    let migration = migrations.get(0).unwrap();\n    assert_eq!(migration.name(), \"m20220118_000001_create_cake_table\");\n    assert_eq!(migration.status(), MigrationStatus::Applied);\n\n    println!(\"\\nMigrator::status\");\n    migrator.status(db).await?;\n\n    assert!(manager.has_table(\"cake\").await?);\n    assert!(manager.has_table(\"fruit\").await?);\n\n    assert!(manager.has_column(\"cake\", \"name\").await?);\n    assert!(manager.has_column(\"fruit\", \"cake_id\").await?);\n\n    // Tests rolling back a failing migration-down on Postgres.\n    // With per-migration transactions, rollbacks happen one at a time in reverse.\n    // Migrations 6-2 roll back and commit successfully. Migration 1 (drops cake\n    // then ABORTs) fails, so its DROP is restored. But migration 2's DROP of\n    // the fruit table already committed.\n    if matches!(db.get_database_backend(), DbBackend::Postgres) {\n        println!(\"\\nRoll back changes when encounter errors\");\n\n        // Set a flag to throw error inside `m20220118_000001_create_cake_table.rs`\n        unsafe {\n            std::env::set_var(\"ABORT_MIGRATION\", \"YES\");\n        }\n\n        // Should throw an error\n        println!(\"\\nMigrator::down\");\n        assert_eq!(\n            migrator.down(db, None).await,\n            Err(DbErr::Migration(\n                \"Abort migration and rollback changes\".into()\n            ))\n        );\n\n        println!(\"\\nMigrator::status\");\n        migrator.status(db).await?;\n\n        // Only migration 1's down was rolled back (cake table restored).\n        // Migrations 2-6 were rolled back successfully (fruit table dropped).\n        assert!(manager.has_table(\"cake\").await?);\n        assert!(!manager.has_table(\"fruit\").await?);\n\n        // Unset the flag\n        unsafe {\n            std::env::remove_var(\"ABORT_MIGRATION\");\n        }\n    }\n\n    println!(\"\\nMigrator::down\");\n    migrator.down(db, None).await?;\n\n    assert!(manager.has_table(migration_table_name).await?);\n    if migration_table_name != \"seaql_migrations\" {\n        assert!(!manager.has_table(\"seaql_migrations\").await?);\n    }\n\n    assert!(!manager.has_table(\"cake\").await?);\n    assert!(!manager.has_table(\"fruit\").await?);\n\n    println!(\"\\nMigrator::fresh\");\n    migrator.fresh(db).await?;\n\n    assert!(manager.has_table(\"cake\").await?);\n    assert!(manager.has_table(\"fruit\").await?);\n\n    println!(\"\\nMigrator::refresh\");\n    migrator.refresh(db).await?;\n\n    assert!(manager.has_table(\"cake\").await?);\n    assert!(manager.has_table(\"fruit\").await?);\n\n    println!(\"\\nMigrator::reset\");\n    migrator.reset(db).await?;\n\n    assert!(!manager.has_table(\"cake\").await?);\n    assert!(!manager.has_table(\"fruit\").await?);\n\n    println!(\"\\nMigrator::status\");\n    migrator.status(db).await?;\n\n    Ok(())\n}\n\nasync fn run_transaction_test(url: &str, db_name: &str, schema: &str) -> Result<(), DbErr> {\n    let db = &create_db(url, db_name, schema).await?;\n    let backend = db.get_database_backend();\n    let manager = SchemaManager::new(db);\n\n    // use_transaction = None: Postgres wraps by default, others don't.\n    // The assertion happens inside the migration's up()/down() body.\n    println!(\"\\nTransaction test: use_transaction = None\");\n    let m = transaction_test::Migrator {\n        use_transaction: None,\n        should_fail: false,\n    };\n    m.up(db, None).await?;\n    assert!(manager.has_table(\"test_table\").await?);\n    m.down(db, None).await?;\n    assert!(!manager.has_table(\"test_table\").await?);\n    m.reset(db).await.ok();\n\n    // use_transaction = Some(true): forces transaction on every backend.\n    println!(\"\\nTransaction test: use_transaction = Some(true)\");\n    let m = transaction_test::Migrator {\n        use_transaction: Some(true),\n        should_fail: false,\n    };\n    m.up(db, None).await?;\n    assert!(manager.has_table(\"test_table\").await?);\n    m.down(db, None).await?;\n    assert!(!manager.has_table(\"test_table\").await?);\n    m.reset(db).await.ok();\n\n    // use_transaction = Some(false): disables transaction, including on Postgres.\n    println!(\"\\nTransaction test: use_transaction = Some(false)\");\n    let m = transaction_test::Migrator {\n        use_transaction: Some(false),\n        should_fail: false,\n    };\n    m.up(db, None).await?;\n    assert!(manager.has_table(\"test_table\").await?);\n    m.down(db, None).await?;\n    assert!(!manager.has_table(\"test_table\").await?);\n    m.reset(db).await.ok();\n\n    // Failure with transaction: DDL rolled back (except MySQL which auto-commits DDL).\n    println!(\"\\nTransaction test: failure with transaction\");\n    let m = transaction_test::Migrator {\n        use_transaction: Some(true),\n        should_fail: true,\n    };\n    assert!(m.up(db, None).await.is_err());\n    if backend != DbBackend::MySql {\n        assert!(\n            !manager.has_table(\"test_table\").await?,\n            \"DDL should be rolled back\"\n        );\n    }\n    m.reset(db).await.ok();\n\n    // Failure without transaction: DDL persists.\n    println!(\"\\nTransaction test: failure without transaction\");\n    let m = transaction_test::Migrator {\n        use_transaction: Some(false),\n        should_fail: true,\n    };\n    assert!(m.up(db, None).await.is_err());\n    assert!(manager.has_table(\"test_table\").await?, \"DDL should persist\");\n    db.execute_unprepared(\"DROP TABLE IF EXISTS test_table\")\n        .await?;\n    m.reset(db).await.ok();\n\n    // Manual transaction via manager.begin() / commit().\n    println!(\"\\nTransaction test: manual begin/commit\");\n    let m = transaction_test::ManualTxnMigrator;\n    m.up(db, None).await?;\n    assert!(manager.has_table(\"manual_txn_table\").await?);\n    m.down(db, None).await?;\n    assert!(!manager.has_table(\"manual_txn_table\").await?);\n    m.reset(db).await.ok();\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-migration/tests/postgres.rs",
    "content": "mod common;\n\n#[cfg(all(test, feature = \"sqlx-postgres\"))]\nmod inner {\n    use crate::common::migrator::default::*;\n    use sea_orm::{ConnectOptions, ConnectionTrait, Database, DbBackend, Statement, error::DbErr};\n    use sea_orm_migration::prelude::*;\n\n    #[tokio::test]\n    async fn test_fresh_with_extension() -> Result<(), DbErr> {\n        let url =\n            &std::env::var(\"DATABASE_URL\").expect(\"Environment variable 'DATABASE_URL' not set\");\n        let db_name = \"test_fresh_with_extension\";\n\n        let db_connect = |url: String| async {\n            let connect_options = ConnectOptions::new(url).to_owned();\n            Database::connect(connect_options).await\n        };\n\n        let db = db_connect(url.to_owned()).await?;\n        if !matches!(db.get_database_backend(), DbBackend::Postgres) {\n            return Ok(());\n        }\n\n        db.execute_unprepared(&format!(r#\"DROP DATABASE IF EXISTS \"{db_name}\"\"#))\n            .await?;\n        db.execute_unprepared(&format!(r#\"CREATE DATABASE \"{db_name}\"\"#))\n            .await?;\n\n        let url = format!(\"{url}/{db_name}\");\n        let db = db_connect(url).await?;\n\n        // Create the extension and a custom type\n        db.execute_unprepared(\"CREATE EXTENSION IF NOT EXISTS citext\")\n            .await?;\n        db.execute_unprepared(\"CREATE TYPE \\\"UserFruit\\\" AS ENUM ('Apple', 'Banana')\")\n            .await?;\n\n        // Run the fresh migration\n        Migrator::fresh(&db).await?;\n\n        // Check that the custom type was dropped and the extension's type was not\n        let citext_exists: Option<i32> = db\n            .query_one_raw(Statement::from_string(\n                DbBackend::Postgres,\n                r#\"SELECT 1 as \"value\" FROM pg_type WHERE typname = 'citext'\"#.to_owned(),\n            ))\n            .await?\n            .map(|row| row.try_get(\"\", \"value\").unwrap());\n\n        assert_eq!(citext_exists, Some(1), \"the citext type should still exist\");\n\n        let user_fruit_exists: Option<i32> = db\n            .query_one_raw(Statement::from_string(\n                DbBackend::Postgres,\n                r#\"SELECT 1 as \"value\" FROM pg_type WHERE typname = 'UserFruit'\"#.to_owned(),\n            ))\n            .await?\n            .map(|row| row.try_get(\"\", \"value\").unwrap());\n\n        assert_eq!(\n            user_fruit_exists, None,\n            \"the UserFruit type should have been dropped\"\n        );\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "sea-orm-rocket/Cargo.toml",
    "content": "[workspace]\nmembers = [\"codegen\", \"lib\"]\n"
  },
  {
    "path": "sea-orm-rocket/README.md",
    "content": "# SeaORM Rocket support crate.\n\nNot all versions of `sea-orm-rocket` are compatible with every version of Rocket\ndue to breaking changes in the Rocket database management API. Please reference\nthe below table to determine which version of `sea-orm-rocket` is appropriate\nfor your use case.\n\n| Rocket version | `sea-orm-rocket` version |\n| :------------- | -----------------------: |\n| v0.5.0 (+ RCs) |                   v0.5.5 |\n| v0.5.1         |                   v0.6.0 |\n"
  },
  {
    "path": "sea-orm-rocket/codegen/Cargo.toml",
    "content": "[package]\nauthors      = [\"Sergio Benitez <sb@sergio.bz>\", \"Jeb Rosen <jeb@jebrosen.com>\"]\ndescription  = \"Procedural macros for sea_orm_rocket.\"\nedition      = \"2024\"\nkeywords     = [\"rocket\", \"framework\", \"database\", \"pools\"]\nlicense      = \"MIT OR Apache-2.0\"\nname         = \"sea-orm-rocket-codegen\"\nreadme       = \"../README.md\"\nrepository   = \"https://github.com/SergioBenitez/Rocket/contrib/db_pools\"\nrust-version = \"1.85.0\"\nversion      = \"0.6.0\"\n\n[lib]\nproc-macro = true\n\n[dependencies]\ndevise = \"0.4\"\nquote  = \"1\"\n\n[dev-dependencies]\nrocket        = { version = \"0.5.1\", default-features = false }\ntrybuild      = \"1\"\nversion_check = \"0.9\"\n"
  },
  {
    "path": "sea-orm-rocket/codegen/src/database.rs",
    "content": "use proc_macro::TokenStream;\n\nuse devise::proc_macro2_diagnostics::SpanDiagnosticExt;\nuse devise::syn::{self, spanned::Spanned};\nuse devise::{DeriveGenerator, FromMeta, MapperBuild, Support, ValidatorBuild};\n\nconst ONE_DATABASE_ATTR: &str = \"missing `#[database(\\\"name\\\")]` attribute\";\nconst ONE_UNNAMED_FIELD: &str = \"struct must have exactly one unnamed field\";\n\n#[derive(Debug, FromMeta)]\nstruct DatabaseAttribute {\n    #[meta(naked)]\n    name: String,\n}\n\npub fn derive_database(input: TokenStream) -> TokenStream {\n    DeriveGenerator::build_for(input, quote!(impl rocket_db_pools::Database))\n        .support(Support::TupleStruct)\n        .validator(ValidatorBuild::new().struct_validate(|_, s| {\n            if s.fields.len() == 1 {\n                Ok(())\n            } else {\n                Err(s.span().error(ONE_UNNAMED_FIELD))\n            }\n        }))\n        .outer_mapper(MapperBuild::new().struct_map(|_, s| {\n            let pool_type = match &s.fields {\n                syn::Fields::Unnamed(f) => &f.unnamed[0].ty,\n                _ => unreachable!(\"Support::TupleStruct\"),\n            };\n\n            let decorated_type = &s.ident;\n            let db_ty = quote_spanned!(decorated_type.span() =>\n                <#decorated_type as rocket_db_pools::Database>\n            );\n\n            quote_spanned! { decorated_type.span() =>\n                impl From<#pool_type> for #decorated_type {\n                    fn from(pool: #pool_type) -> Self {\n                        Self(pool)\n                    }\n                }\n\n                impl std::ops::Deref for #decorated_type {\n                    type Target = #pool_type;\n\n                    fn deref(&self) -> &Self::Target {\n                        &self.0\n                    }\n                }\n\n                impl std::ops::DerefMut for #decorated_type {\n                    fn deref_mut(&mut self) -> &mut Self::Target {\n                        &mut self.0\n                    }\n                }\n\n                #[rocket::async_trait]\n                impl<'r> rocket::request::FromRequest<'r> for &'r #decorated_type {\n                    type Error = ();\n\n                    async fn from_request(\n                        req: &'r rocket::request::Request<'_>\n                    ) -> rocket::request::Outcome<Self, Self::Error> {\n                        match #db_ty::fetch(req.rocket()) {\n                            Some(db) => rocket::outcome::Outcome::Success(db),\n                            None => rocket::outcome::Outcome::Error((\n                                rocket::http::Status::InternalServerError, ()))\n                        }\n                    }\n                }\n\n                impl rocket::Sentinel for &#decorated_type {\n                    fn abort(rocket: &rocket::Rocket<rocket::Ignite>) -> bool {\n                        #db_ty::fetch(rocket).is_none()\n                    }\n                }\n            }\n        }))\n        .outer_mapper(quote!(#[rocket::async_trait]))\n        .inner_mapper(MapperBuild::new().try_struct_map(|_, s| {\n            let db_name = DatabaseAttribute::one_from_attrs(\"database\", &s.attrs)?\n                .map(|attr| attr.name)\n                .ok_or_else(|| s.span().error(ONE_DATABASE_ATTR))?;\n\n            let fairing_name = format!(\"'{db_name}' Database Pool\");\n\n            let pool_type = match &s.fields {\n                syn::Fields::Unnamed(f) => &f.unnamed[0].ty,\n                _ => unreachable!(\"Support::TupleStruct\"),\n            };\n\n            Ok(quote_spanned! { pool_type.span() =>\n                type Pool = #pool_type;\n\n                const NAME: &'static str = #db_name;\n\n                fn init() -> rocket_db_pools::Initializer<Self> {\n                    rocket_db_pools::Initializer::with_name(#fairing_name)\n                }\n            })\n        }))\n        .to_tokens()\n}\n"
  },
  {
    "path": "sea-orm-rocket/codegen/src/lib.rs",
    "content": "#![recursion_limit = \"256\"]\n#![warn(rust_2018_idioms)]\n\n//! # `sea_orm_rocket` - Code Generation\n//!\n//! Implements the code generation portion of the `sea_orm_rocket` crate. This\n//! is an implementation detail. This create should never be depended on\n//! directly.\n\n#[macro_use]\nextern crate quote;\n\nmod database;\n\n/// Automatic derive for the [`Database`] trait.\n///\n/// The derive generates an implementation of [`Database`] as follows:\n///\n/// * [`Database::NAME`] is set to the value in the `#[database(\"name\")]`\n///   attribute.\n///\n///   This names the database, providing an anchor to configure the database via\n///   `Rocket.toml` or any other configuration source. Specifically, the\n///   configuration in `databases.name` is used to configure the driver.\n///\n/// * [`Database::Pool`] is set to the wrapped type: `PoolType` above. The type\n///   must implement [`Pool`].\n///\n/// To meet the required [`Database`] supertrait bounds, this derive also\n/// generates implementations for:\n///\n/// * `From<Db::Pool>`\n///\n/// * `Deref<Target = Db::Pool>`\n///\n/// * `DerefMut<Target = Db::Pool>`\n///\n/// * `FromRequest<'_> for &Db`\n///\n/// * `Sentinel for &Db`\n///\n/// The `Deref` impls enable accessing the database pool directly from\n/// references `&Db` or `&mut Db`. To force a dereference to the underlying\n/// type, use `&db.0` or `&**db` or their `&mut` variants.\n///\n/// [`Database`]: ../sea_orm_rocket/trait.Database.html\n/// [`Database::NAME`]: ../sea_orm_rocket/trait.Database.html#associatedconstant.NAME\n/// [`Database::Pool`]: ../sea_orm_rocket/trait.Database.html#associatedtype.Pool\n/// [`Pool`]: ../sea_orm_rocket/trait.Pool.html\n#[proc_macro_derive(Database, attributes(database))]\npub fn derive_database(input: proc_macro::TokenStream) -> proc_macro::TokenStream {\n    crate::database::derive_database(input)\n}\n"
  },
  {
    "path": "sea-orm-rocket/lib/Cargo.toml",
    "content": "[package]\nauthors      = [\"Sergio Benitez <sb@sergio.bz>\", \"Jeb Rosen <jeb@jebrosen.com>\"]\ndescription  = \"SeaORM Rocket support crate\"\nedition      = \"2024\"\nkeywords     = [\"rocket\", \"framework\", \"database\", \"pools\"]\nlicense      = \"MIT OR Apache-2.0\"\nname         = \"sea-orm-rocket\"\nreadme       = \"../README.md\"\nrepository   = \"https://github.com/SeaQL/sea-orm\"\nrust-version = \"1.85.0\"\nversion      = \"0.6.0\"\n\n[package.metadata.docs.rs]\nall-features = true\n\n[dependencies.rocket]\ndefault-features = false\nversion          = \"0.5.1\"\n\n[dependencies.sea-orm-rocket-codegen]\npath    = \"../codegen\"\nversion = \"0.6.0\"\n\n[dependencies.rocket_okapi]\ndefault-features = false\noptional         = true\nversion          = \"0.9\"\n\n[dev-dependencies.rocket]\ndefault-features = false\nfeatures         = [\"json\"]\nversion          = \"0.5.1\"\n"
  },
  {
    "path": "sea-orm-rocket/lib/src/config.rs",
    "content": "use rocket::serde::{Deserialize, Serialize};\n\n/// Base configuration for all database drivers.\n///\n/// A dictionary matching this structure is extracted from the active\n/// [`Figment`](crate::figment::Figment), scoped to `databases.name`, where\n/// `name` is the name of the database, by the\n/// [`Initializer`](crate::Initializer) fairing on ignition and used to\n/// configure the relevant database and database pool.\n///\n/// With the default provider, these parameters are typically configured in a\n/// `Rocket.toml` file:\n///\n/// ```toml\n/// [default.databases.db_name]\n/// url = \"/path/to/db.sqlite\"\n///\n/// # only `url` is required. `Initializer` provides defaults for the rest.\n/// min_connections = 64\n/// max_connections = 1024\n/// connect_timeout = 5\n/// idle_timeout = 120\n/// ```\n///\n/// Alternatively, a custom provider can be used. For example, a custom `Figment`\n/// with a global `databases.name` configuration:\n///\n/// ```rust\n/// # use rocket::launch;\n/// #[launch]\n/// fn rocket() -> _ {\n///     let figment = rocket::Config::figment().merge((\n///         \"databases.name\",\n///         sea_orm_rocket::Config {\n///             url: \"db:specific@config&url\".into(),\n///             min_connections: None,\n///             max_connections: 1024,\n///             connect_timeout: 3,\n///             idle_timeout: None,\n///             sqlx_logging: true,\n///         },\n///     ));\n///\n///     rocket::custom(figment)\n/// }\n/// ```\n///\n/// For general information on configuration in Rocket, see [`rocket::config`].\n/// For higher-level details on configuring a database, see the [crate-level\n/// docs](crate#configuration).\n#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]\n#[serde(crate = \"rocket::serde\")]\npub struct Config {\n    /// Database-specific connection and configuration URL.\n    ///\n    /// The format of the URL is database specific; consult your database's\n    /// documentation.\n    pub url: String,\n    /// Minimum number of connections to maintain in the pool.\n    ///\n    /// **Note:** `deadpool` drivers do not support and thus ignore this value.\n    ///\n    /// _Default:_ `None`.\n    pub min_connections: Option<u32>,\n    /// Maximum number of connections to maintain in the pool.\n    ///\n    /// _Default:_ `workers * 4`.\n    pub max_connections: usize,\n    /// Number of seconds to wait for a connection before timing out.\n    ///\n    /// If the timeout elapses before a connection can be made or retrieved from\n    /// a pool, an error is returned.\n    ///\n    /// _Default:_ `5`.\n    pub connect_timeout: u64,\n    /// Maximum number of seconds to keep a connection alive for.\n    ///\n    /// After a connection is established, it is maintained in a pool for\n    /// efficient connection retrieval. When an `idle_timeout` is set, that\n    /// connection will be closed after the timeout elapses. If an\n    /// `idle_timeout` is not specified, the behavior is driver specific but\n    /// typically defaults to keeping a connection active indefinitely.\n    ///\n    /// _Default:_ `None`.\n    pub idle_timeout: Option<u64>,\n\n    /// Enable SQLx statement logging (default true)\n    #[serde(default)]\n    pub sqlx_logging: bool,\n}\n"
  },
  {
    "path": "sea-orm-rocket/lib/src/database.rs",
    "content": "use std::marker::PhantomData;\nuse std::ops::DerefMut;\n\nuse rocket::fairing::{self, Fairing, Info, Kind};\nuse rocket::http::Status;\nuse rocket::request::{FromRequest, Outcome, Request};\nuse rocket::{Build, Ignite, Phase, Rocket, Sentinel, error, info_};\n\nuse rocket::figment::providers::Serialized;\nuse rocket::yansi::Paint;\n\n#[cfg(feature = \"rocket_okapi\")]\nuse rocket_okapi::{\n    r#gen::OpenApiGenerator,\n    request::{OpenApiFromRequest, RequestHeaderInput},\n};\n\nuse crate::Pool;\n\n/// Derivable trait which ties a database [`Pool`] with a configuration name.\n///\n/// This trait should rarely, if ever, be implemented manually. Instead, it\n/// should be derived:\n///\n/// ```ignore\n/// use sea_orm_rocket::{Database};\n/// # use sea_orm_rocket::MockPool as SeaOrmPool;\n///\n/// #[derive(Database, Debug)]\n/// #[database(\"sea_orm\")]\n/// struct Db(SeaOrmPool);\n///\n/// #[launch]\n/// fn rocket() -> _ {\n///     rocket::build().attach(Db::init())\n/// }\n/// ```\n///\n/// See the [`Database` derive](derive@crate::Database) for details.\npub trait Database:\n    From<Self::Pool> + DerefMut<Target = Self::Pool> + Send + Sync + 'static\n{\n    /// The [`Pool`] type of connections to this database.\n    ///\n    /// When `Database` is derived, this takes the value of the `Inner` type in\n    /// `struct Db(Inner)`.\n    type Pool: Pool;\n\n    /// The configuration name for this database.\n    ///\n    /// When `Database` is derived, this takes the value `\"name\"` in the\n    /// `#[database(\"name\")]` attribute.\n    const NAME: &'static str;\n\n    /// Returns a fairing that initializes the database and its connection pool.\n    ///\n    /// # Example\n    ///\n    /// ```rust\n    /// # mod _inner {\n    /// # use rocket::launch;\n    /// use sea_orm_rocket::Database;\n    /// # use sea_orm_rocket::MockPool as SeaOrmPool;\n    ///\n    /// #[derive(Database)]\n    /// #[database(\"sea_orm\")]\n    /// struct Db(SeaOrmPool);\n    ///\n    /// #[launch]\n    /// fn rocket() -> _ {\n    ///     rocket::build().attach(Db::init())\n    /// }\n    /// # }\n    /// ```\n    fn init() -> Initializer<Self> {\n        Initializer::new()\n    }\n\n    /// Returns a reference to the initialized database in `rocket`. The\n    /// initializer fairing returned by `init()` must have already executed for\n    /// `Option` to be `Some`. This is guaranteed to be the case if the fairing\n    /// is attached and either:\n    ///\n    ///   * Rocket is in the [`Orbit`](rocket::Orbit) phase. That is, the\n    ///     application is running. This is always the case in request guards\n    ///     and liftoff fairings,\n    ///   * _or_ Rocket is in the [`Build`](rocket::Build) or\n    ///     [`Ignite`](rocket::Ignite) phase and the `Initializer` fairing has\n    ///     already been run. This is the case in all fairing callbacks\n    ///     corresponding to fairings attached _after_ the `Initializer`\n    ///     fairing.\n    ///\n    /// # Example\n    ///\n    /// Run database migrations in an ignite fairing. It is imperative that the\n    /// migration fairing be registered _after_ the `init()` fairing.\n    ///\n    /// ```rust\n    /// # mod _inner {\n    /// # use rocket::launch;\n    /// use rocket::fairing::{self, AdHoc};\n    /// use rocket::{Build, Rocket};\n    ///\n    /// use sea_orm_rocket::Database;\n    /// # use sea_orm_rocket::MockPool as SeaOrmPool;\n    ///\n    /// #[derive(Database)]\n    /// #[database(\"sea_orm\")]\n    /// struct Db(SeaOrmPool);\n    ///\n    /// async fn run_migrations(rocket: Rocket<Build>) -> fairing::Result {\n    ///     if let Some(db) = Db::fetch(&rocket) {\n    ///         // run migrations using `db`. get the inner type with &db.0.\n    ///         Ok(rocket)\n    ///     } else {\n    ///         Err(rocket)\n    ///     }\n    /// }\n    ///\n    /// #[launch]\n    /// fn rocket() -> _ {\n    ///     rocket::build()\n    ///         .attach(Db::init())\n    ///         .attach(AdHoc::try_on_ignite(\"DB Migrations\", run_migrations))\n    /// }\n    /// # }\n    /// ```\n    fn fetch<P: Phase>(rocket: &Rocket<P>) -> Option<&Self> {\n        if let Some(db) = rocket.state() {\n            return Some(db);\n        }\n\n        let dbtype = std::any::type_name::<Self>();\n        let fairing = Paint::new(format!(\"{dbtype}::init()\")).bold();\n        error!(\n            \"Attempted to fetch unattached database `{}`.\",\n            Paint::new(dbtype).bold()\n        );\n        info_!(\n            \"`{}` fairing must be attached prior to using this database.\",\n            fairing\n        );\n        None\n    }\n}\n\n/// A [`Fairing`] which initializes a [`Database`] and its connection pool.\n///\n/// A value of this type can be created for any type `D` that implements\n/// [`Database`] via the [`Database::init()`] method on the type. Normally, a\n/// value of this type _never_ needs to be constructed directly. This\n/// documentation exists purely as a reference.\n///\n/// This fairing initializes a database pool. Specifically, it:\n///\n///   1. Reads the configuration at `database.db_name`, where `db_name` is\n///      [`Database::NAME`].\n///\n///   2. Sets [`Config`](crate::Config) defaults on the configuration figment.\n///\n///   3. Calls [`Pool::init()`].\n///\n///   4. Stores the database instance in managed storage, retrievable via\n///      [`Database::fetch()`].\n///\n/// The name of the fairing itself is `Initializer<D>`, with `D` replaced with\n/// the type name `D` unless a name is explicitly provided via\n/// [`Self::with_name()`].\npub struct Initializer<D: Database>(Option<&'static str>, PhantomData<fn() -> D>);\n\n/// A request guard which retrieves a single connection to a [`Database`].\n///\n/// For a database type of `Db`, a request guard of `Connection<Db>` retrieves a\n/// single connection to `Db`.\n///\n/// The request guard succeeds if the database was initialized by the\n/// [`Initializer`] fairing and a connection is available within\n/// [`connect_timeout`](crate::Config::connect_timeout) seconds.\n///   * If the `Initializer` fairing was _not_ attached, the guard _fails_ with\n///   status `InternalServerError`. A [`Sentinel`] guards this condition, and so\n///   this type of failure is unlikely to occur. A `None` error is returned.\n///   * If a connection is not available within `connect_timeout` seconds or\n///   another error occurs, the guard _fails_ with status `ServiceUnavailable`\n///   and the error is returned in `Some`.\npub struct Connection<'a, D: Database>(&'a <D::Pool as Pool>::Connection);\n\nimpl<D: Database> Initializer<D> {\n    /// Returns a database initializer fairing for `D`.\n    ///\n    /// This method should never need to be called manually. See the [crate\n    /// docs](crate) for usage information.\n    #[allow(clippy::new_without_default)]\n    pub fn new() -> Self {\n        Self(None, std::marker::PhantomData)\n    }\n\n    /// Returns a database initializer fairing for `D` with name `name`.\n    ///\n    /// This method should never need to be called manually. See the [crate\n    /// docs](crate) for usage information.\n    pub fn with_name(name: &'static str) -> Self {\n        Self(Some(name), std::marker::PhantomData)\n    }\n}\n\nimpl<'a, D: Database> Connection<'a, D> {\n    /// Returns the internal connection value. See the [`Connection` Deref\n    /// column](crate#supported-drivers) for the expected type of this value.\n    pub fn into_inner(self) -> &'a <D::Pool as Pool>::Connection {\n        self.0\n    }\n}\n\n#[cfg(feature = \"rocket_okapi\")]\nimpl<'r, D: Database> OpenApiFromRequest<'r> for Connection<'r, D> {\n    fn from_request_input(\n        _gen: &mut OpenApiGenerator,\n        _name: String,\n        _required: bool,\n    ) -> rocket_okapi::Result<RequestHeaderInput> {\n        Ok(RequestHeaderInput::None)\n    }\n}\n\n#[rocket::async_trait]\nimpl<D: Database> Fairing for Initializer<D> {\n    fn info(&self) -> Info {\n        Info {\n            name: self.0.unwrap_or_else(std::any::type_name::<Self>),\n            kind: Kind::Ignite,\n        }\n    }\n\n    async fn on_ignite(&self, rocket: Rocket<Build>) -> fairing::Result {\n        let workers: usize = rocket\n            .figment()\n            .extract_inner(rocket::Config::WORKERS)\n            .unwrap_or_else(|_| rocket::Config::default().workers);\n\n        let figment = rocket\n            .figment()\n            .focus(&format!(\"databases.{}\", D::NAME))\n            .merge(Serialized::default(\"max_connections\", workers * 4))\n            .merge(Serialized::default(\"connect_timeout\", 5))\n            .merge(Serialized::default(\"sqlx_logging\", true));\n\n        match <D::Pool>::init(&figment).await {\n            Ok(pool) => Ok(rocket.manage(D::from(pool))),\n            Err(e) => {\n                error!(\"failed to initialize database: {}\", e);\n                Err(rocket)\n            }\n        }\n    }\n}\n\n#[rocket::async_trait]\nimpl<'r, D: Database> FromRequest<'r> for Connection<'r, D> {\n    type Error = Option<<D::Pool as Pool>::Error>;\n\n    async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {\n        match D::fetch(req.rocket()) {\n            Some(pool) => Outcome::Success(Connection(pool.borrow())),\n            None => Outcome::Error((Status::InternalServerError, None)),\n        }\n    }\n}\n\nimpl<D: Database> Sentinel for Connection<'_, D> {\n    fn abort(rocket: &Rocket<Ignite>) -> bool {\n        D::fetch(rocket).is_none()\n    }\n}\n"
  },
  {
    "path": "sea-orm-rocket/lib/src/error.rs",
    "content": "use std::fmt;\n\n/// A general error type for use by [`Pool`](crate::Pool#implementing)\n/// implementors and returned by the [`Connection`](crate::Connection) request\n/// guard.\n#[derive(Debug)]\npub enum Error<A, B = A> {\n    /// An error that occurred during database/pool initialization.\n    Init(A),\n\n    /// An error that occurred while retrieving a connection from the pool.\n    Get(B),\n\n    /// A [`Figment`](crate::figment::Figment) configuration error.\n    Config(crate::figment::Error),\n}\n\nimpl<A: fmt::Display, B: fmt::Display> fmt::Display for Error<A, B> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        match self {\n            Error::Init(e) => write!(f, \"failed to initialize database: {e}\"),\n            Error::Get(e) => write!(f, \"failed to get db connection: {e}\"),\n            Error::Config(e) => write!(f, \"bad configuration: {e}\"),\n        }\n    }\n}\n\nimpl<A, B> std::error::Error for Error<A, B>\nwhere\n    A: fmt::Debug + fmt::Display,\n    B: fmt::Debug + fmt::Display,\n{\n}\n\nimpl<A, B> From<crate::figment::Error> for Error<A, B> {\n    fn from(e: crate::figment::Error) -> Self {\n        Self::Config(e)\n    }\n}\n"
  },
  {
    "path": "sea-orm-rocket/lib/src/lib.rs",
    "content": "//! SeaORM Rocket support crate.\n#![deny(missing_docs)]\n\n/// Re-export of the `figment` crate.\n#[doc(inline)]\npub use rocket::figment;\n\npub use rocket;\n\nmod config;\nmod database;\nmod error;\nmod pool;\n\npub use self::config::Config;\npub use self::database::{Connection, Database, Initializer};\npub use self::error::Error;\npub use self::pool::{MockPool, Pool};\n\npub use sea_orm_rocket_codegen::*;\n"
  },
  {
    "path": "sea-orm-rocket/lib/src/pool.rs",
    "content": "use rocket::figment::Figment;\n\n/// Generic [`Database`](crate::Database) driver connection pool trait.\n///\n/// This trait provides a generic interface to various database pooling\n/// implementations in the Rust ecosystem. It can be implemented by anyone.\n///\n/// This is adapted from the original `rocket_db_pools`. But on top we require\n/// `Connection` itself to be `Sync`. Hence, instead of cloning or allocating\n/// a new connection per request, here we only borrow a reference to the pool.\n///\n/// In SeaORM, only *when* you are about to execute a SQL statement will a\n/// connection be acquired from the pool, and returned as soon as the query finishes.\n/// This helps a bit with concurrency if the lifecycle of a request is long enough.\n/// ```\n#[rocket::async_trait]\npub trait Pool: Sized + Send + Sync + 'static {\n    /// The connection type managed by this pool.\n    type Connection;\n\n    /// The error type returned by [`Self::init()`].\n    type Error: std::error::Error;\n\n    /// Constructs a pool from a [Value](rocket::figment::value::Value).\n    ///\n    /// It is up to each implementor of `Pool` to define its accepted\n    /// configuration value(s) via the `Config` associated type.  Most\n    /// integrations provided in `sea_orm_rocket` use [`Config`], which\n    /// accepts a (required) `url` and an (optional) `pool_size`.\n    ///\n    /// ## Errors\n    ///\n    /// This method returns an error if the configuration is not compatible, or\n    /// if creating a pool failed due to an unavailable database server,\n    /// insufficient resources, or another database-specific error.\n    async fn init(figment: &Figment) -> Result<Self, Self::Error>;\n\n    /// Borrows a reference to the pool\n    fn borrow(&self) -> &Self::Connection;\n}\n\n#[derive(Debug)]\n/// A mock object which impl `Pool`, for testing only\npub struct MockPool;\n\n#[derive(Debug)]\npub struct MockPoolErr;\n\nimpl std::fmt::Display for MockPoolErr {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(f, \"{self:?}\")\n    }\n}\n\nimpl std::error::Error for MockPoolErr {}\n\n#[rocket::async_trait]\nimpl Pool for MockPool {\n    type Error = MockPoolErr;\n\n    type Connection = bool;\n\n    async fn init(_figment: &Figment) -> Result<Self, Self::Error> {\n        Ok(MockPool)\n    }\n\n    fn borrow(&self) -> &Self::Connection {\n        &true\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/CLAUDE.md",
    "content": "# sea-orm-sync\n\nDo **not** edit code in `sea-orm-sync/src/` or `sea-orm-sync/tests/` directly. All source and test files are generated from the main `src/` and `tests/` directories by running:\n\n```bash\ncd /path/to/sea-orm\nbash build-tools/make-sync.sh\n```\n\nThe script copies `src/` and `tests/` into `sea-orm-sync/`, then applies sed transforms to strip async/await, remove `#[async_trait]`, replace `futures_util::lock::Mutex` with `std::sync::Mutex`, etc.\n\n## Workflow\n\n1. Make all code changes in the **root** `src/` and `tests/` directories.\n2. Edit `sea-orm-sync/Cargo.toml` directly if dependency or feature changes are needed.\n3. Regenerate sync code: `bash build-tools/make-sync.sh`\n4. Build and test: `cd sea-orm-sync && cargo check --features rusqlite`\n\n## Gotchas\n\n- **`make-sync.sh` requires full filesystem access.** It uses `sed -i`, `find`, `cp -r`, and `cargo fmt`. Running it inside a sandboxed environment (e.g. Cursor's default sandbox) will silently produce broken output — the sed substitutions won't apply, leaving `async_trait`, `futures_util`, `.await`, etc. in the generated code. Always run with full permissions.\n- **The root crate cannot compile with `--features rusqlite`** because it depends on `sea_query_rusqlite`, which is only wired up in `sea-orm-sync/Cargo.toml`. To check rusqlite code, you must regenerate and build from `sea-orm-sync/`.\n- **`#[sea_orm_macros::test]`** gates tests on `feature = \"rusqlite\"` in the sync crate (and on `sqlx-*` features in the async crate). When running tests, pass `--features rusqlite` and set `DATABASE_URL`, e.g.: `DATABASE_URL=\"sqlite::memory:\" cargo test --features rusqlite --test transaction_tests`\n"
  },
  {
    "path": "sea-orm-sync/Cargo.toml",
    "content": "[workspace]\nmembers = [\".\", \"examples/quickstart\", \"examples/pi_spigot\"]\n\n[package]\nauthors       = [\"Chris Tsang <chris.2y3@outlook.com>\"]\ncategories    = [\"database\"]\ndescription   = \"🐚 The sync version of SeaORM\"\ndocumentation = \"https://docs.rs/sea-orm\"\nedition       = \"2024\"\nhomepage      = \"https://www.sea-ql.org/SeaORM\"\nkeywords      = [\"orm\", \"mysql\", \"postgres\", \"sqlite\"]\nlicense       = \"MIT OR Apache-2.0\"\nname          = \"sea-orm-sync\"\nrepository    = \"https://github.com/SeaQL/sea-orm\"\nrust-version  = \"1.85.0\"\nversion       = \"2.0.0-rc.37\"\n\n[package.metadata.docs.rs]\nfeatures = [\n    \"default\",\n    \"mock\",\n    \"proxy\",\n    \"rbac\",\n    \"schema-sync\",\n    \"postgres-array\",\n    \"postgres-vector\",\n    \"with-arrow\",\n]\nrustdoc-args = [\"--cfg\", \"docsrs\"]\n\n[lib]\nname = \"sea_orm\"\npath = \"src/lib.rs\"\n\n[dependencies]\nbigdecimal = { version = \"0.4\", default-features = false, features = [\n    \"std\",\n], optional = true }\nchrono = { version = \"0.4.30\", default-features = false, optional = true }\nderive_more = { version = \"2\", features = [\"debug\"] }\ninventory = { version = \"0.3\", optional = true }\nipnetwork = { version = \"0.20\", default-features = false, optional = true }\nitertools = \"0.14.0\"\nlog = { version = \"0.4\", default-features = false }\nouroboros = { version = \"0.18\", default-features = false }\npgvector = { version = \"~0.4\", default-features = false, optional = true }\nrust_decimal = { version = \"1\", default-features = false, features = [\n    \"std\",\n], optional = true }\nsea-orm-arrow = { version = \"2.0.0-rc\", path = \"../sea-orm-arrow\", default-features = false, optional = true }\nsea-orm-macros = { version = \"~2.0.0-rc.20\", path = \"../sea-orm-macros\", default-features = false, features = [\n    \"strum\",\n] }\nsea-query = { version = \"=1.0.0-rc.31\", default-features = false, features = [\n    \"thread-safe\",\n    \"hashable-value\",\n    \"backend-mysql\",\n    \"backend-postgres\",\n    \"backend-sqlite\",\n    \"sea-orm\",\n] }\nsea-query-rusqlite = { version = \"0.8.0-rc.14\", optional = true }\nsea-schema-sync = { version = \"0.17.0-rc.15\", default-features = false, features = [\n    \"sync\",\n    \"discovery\",\n    \"writer\",\n    \"probe\",\n], optional = true }\nserde = { version = \"1.0\", default-features = false }\nserde_json = { version = \"1.0\", default-features = false, optional = true }\nstrum = { version = \"0.27\", default-features = false }\nthiserror = { version = \"2\", default-features = false }\ntime = { version = \"0.3.36\", default-features = false, optional = true }\ntracing = { version = \"0.1\", default-features = false, features = [\n    \"attributes\",\n    \"log\",\n] }\nurl = { version = \"2.2\", default-features = false }\nuuid = { version = \"1\", default-features = false, optional = true }\n\n[dev-dependencies]\ndotenv = \"0.15\"\nmaplit = { version = \"1\" }\npretty_assertions = { version = \"0.7\" }\nsea-orm-sync = { path = \".\", features = [\n    \"debug-print\",\n    \"mock\",\n    \"postgres-array\",\n    \"tests-cfg\",\n] }\ntime = { version = \"0.3.36\", features = [\"macros\"] }\ntracing-subscriber = { version = \"0.3.17\", features = [\"env-filter\"] }\nuuid = { version = \"1\", features = [\"v4\"] }\n\n[features]\ndebug-print = []\ndefault = [\n    \"sync\",\n    \"macros\",\n    \"with-json\",\n    \"with-chrono\",\n    \"with-rust_decimal\",\n    \"with-uuid\",\n    \"with-time\",\n    \"sqlite-use-returning-for-3_35\",\n]\nentity-registry = [\"inventory\", \"sea-orm-macros/entity-registry\"]\njson-array = [\n    \"postgres-array\",\n] # this does not actually enable postgres, but only a few traits to support array in sea-query\nmacros = [\"sea-orm-macros/derive\"]\nmariadb-use-returning = []\nmock = []\npostgres-array = [\n    \"sea-query/postgres-array\",\n    \"sea-orm-macros/postgres-array\",\n    \"sea-query-rusqlite?/postgres-array\",\n]\npostgres-vector = [\n    \"pgvector\",\n    \"sea-query/postgres-vector\",\n    \"sea-query-rusqlite?/postgres-vector\",\n]\nproxy = [\"serde_json\", \"serde/derive\"]\nrbac = [\"sea-query/audit\", \"macros\"]\nrusqlite = [\"sea-query-rusqlite/sea-orm\", \"sea-schema-sync/rusqlite\"]\nschema-sync = [\"sea-schema-sync\"]\nsea-orm-internal = []\nseaography = [\"sea-orm-macros/seaography\"]\nsqlite-no-row-value-before-3_15 = []\nsqlite-use-returning-for-3_35 = []\nsqlx-dep = []\nsqlx-mysql = []\nsqlx-postgres = []\nsqlx-sqlite = []\nsync = []\ntests-cfg = [\"serde/derive\"]\ntests-features = [\n    \"default\",\n    \"rbac\",\n    \"schema-sync\",\n    \"with-arrow\",\n    \"with-bigdecimal\",\n]\ntracing-spans = []\nwith-arrow = [\"sea-orm-arrow\", \"sea-orm-macros/with-arrow\"]\nwith-bigdecimal = [\n    \"bigdecimal\",\n    \"sea-query/with-bigdecimal\",\n    \"sea-query-rusqlite?/with-bigdecimal\",\n    \"sea-orm-arrow?/with-bigdecimal\",\n]\nwith-chrono = [\n    \"chrono\",\n    \"sea-query/with-chrono\",\n    \"sea-query-rusqlite?/with-chrono\",\n    \"sea-orm-arrow?/with-chrono\",\n]\nwith-ipnetwork = [\n    \"ipnetwork\",\n    \"sea-query/with-ipnetwork\",\n    \"sea-query-rusqlite?/with-ipnetwork\",\n]\nwith-json = [\n    \"serde_json\",\n    \"sea-query/with-json\",\n    \"sea-orm-macros/with-json\",\n    \"chrono?/serde\",\n    \"rust_decimal?/serde\",\n    \"bigdecimal?/serde\",\n    \"uuid?/serde\",\n    \"time?/serde\",\n    \"pgvector?/serde\",\n    \"sea-query-rusqlite?/with-json\",\n]\nwith-rust_decimal = [\n    \"rust_decimal\",\n    \"sea-query/with-rust_decimal\",\n    \"sea-query-rusqlite?/with-rust_decimal\",\n    \"sea-orm-arrow?/with-rust_decimal\",\n]\nwith-time = [\n    \"time\",\n    \"sea-query/with-time\",\n    \"sea-query-rusqlite?/with-time\",\n    \"sea-orm-arrow?/with-time\",\n]\nwith-uuid = [\"uuid\", \"sea-query/with-uuid\", \"sea-query-rusqlite?/with-uuid\"]\n\n[patch.crates-io]\n# sea-query = { path = \"../sea-query\" }\n"
  },
  {
    "path": "sea-orm-sync/README.md",
    "content": "<div align=\"center\">\n\n  <img alt=\"SeaORM\" src=\"https://www.sea-ql.org/blog/img/SeaORM 2.0 Banner.png\"/>\n\n  <h1></h1>\n  <h3>SeaORM is a powerful ORM for building web services in Rust</h3>\n\n  [![crate](https://img.shields.io/crates/v/sea-orm.svg)](https://crates.io/crates/sea-orm)\n  [![build status](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml/badge.svg)](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml)\n  [![GitHub stars](https://img.shields.io/github/stars/SeaQL/sea-orm.svg?style=social&label=Star&maxAge=1)](https://github.com/SeaQL/sea-orm/stargazers/)\n  <br>Support us with a ⭐ !\n\n</div>\n\n# 🐚 SeaORM\n\n[中文文档](https://github.com/SeaQL/sea-orm/blob/master/README-zh.md)\n\n### Advanced Relations\n\nModel complex relationships 1-1, 1-N, M-N, and even self-referential in a high-level, conceptual way.\n\n### Familiar Concepts\n\nInspired by popular ORMs in the Ruby, Python, and Node.js ecosystem, SeaORM offers a developer experience that feels instantly recognizable.\n\n### Feature Rich\n\nSeaORM is a batteries-included ORM with filters, pagination, and nested queries to accelerate building REST, GraphQL, and gRPC APIs.\n\n### Production Ready\n\nWith 250k+ weekly downloads, SeaORM is production-ready, trusted by startups and enterprises worldwide.\n\n## Getting Started\n\n[![Discord](https://img.shields.io/discord/873880840487206962?label=Discord)](https://discord.com/invite/uCPdDXzbdv)\nJoin our Discord server to chat with others!\n\n+ [Documentation](https://www.sea-ql.org/SeaORM)\n\nIntegration examples:\n\n+ [Actix Example](https://github.com/SeaQL/sea-orm/tree/master/examples/actix_example)\n+ [Axum Example](https://github.com/SeaQL/sea-orm/tree/master/examples/axum_example)\n+ [GraphQL Example](https://github.com/SeaQL/sea-orm/tree/master/examples/graphql_example)\n+ [jsonrpsee Example](https://github.com/SeaQL/sea-orm/tree/master/examples/jsonrpsee_example)\n+ [Loco Example](https://github.com/SeaQL/sea-orm/tree/master/examples/loco_example) / [Loco REST Starter](https://github.com/SeaQL/sea-orm/tree/master/examples/loco_starter)\n+ [Poem Example](https://github.com/SeaQL/sea-orm/tree/master/examples/poem_example)\n+ [Rocket Example](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_example) / [Rocket OpenAPI Example](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_okapi_example)\n+ [Salvo Example](https://github.com/SeaQL/sea-orm/tree/master/examples/salvo_example)\n+ [Tonic Example](https://github.com/SeaQL/sea-orm/tree/master/examples/tonic_example)\n+ [Seaography Example (Bakery)](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) / [Seaography Example (Sakila)](https://github.com/SeaQL/seaography/tree/main/examples/sqlite)\n\nIf you want a simple, clean example that fits in a single file that demonstrates the best of SeaORM, you can try:\n+ [Quickstart](https://github.com/SeaQL/sea-orm/blob/master/examples/quickstart/src/main.rs)\n\nLet's have a quick walk through of the unique features of SeaORM.\n\n## Expressive Entity format\nYou don't have to write this by hand! Entity files can be generated from an existing database using `sea-orm-cli`,\nfollowing is generated with `--entity-format dense` *(new in 2.0)*.\n```rust\nmod user {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"user\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n        #[sea_orm(unique)]\n        pub email: String,\n        #[sea_orm(has_one)]\n        pub profile: HasOne<super::profile::Entity>,\n        #[sea_orm(has_many)]\n        pub posts: HasMany<super::post::Entity>,\n    }\n}\nmod post {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"post\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub user_id: i32,\n        pub title: String,\n        #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n        pub author: HasOne<super::user::Entity>,\n        #[sea_orm(has_many, via = \"post_tag\")] // M-N relation with junction\n        pub tags: HasMany<super::tag::Entity>,\n    }\n}\n```\n\n## Smart Entity Loader\nThe Entity Loader intelligently uses join for 1-1 and data loader for 1-N relations,\neliminating the N+1 problem even when performing nested queries.\n```rust\n// join paths:\n// user -> profile\n// user -> post\n//         post -> post_tag -> tag\nlet smart_user = user::Entity::load()\n    .filter_by_id(42) // shorthand for .filter(user::COLUMN.id.eq(42))\n    .with(profile::Entity) // 1-1 uses join\n    .with((post::Entity, tag::Entity)) // 1-N uses data loader\n    .one(db)\n    ?\n    .unwrap();\n\n// 3 queries are executed under the hood:\n// 1. SELECT FROM user JOIN profile WHERE id = $\n// 2. SELECT FROM post WHERE user_id IN (..)\n// 3. SELECT FROM tag JOIN post_tag WHERE post_id IN (..)\n\nsmart_user\n    == user::ModelEx {\n        id: 42,\n        name: \"Bob\".into(),\n        email: \"bob@sea-ql.org\".into(),\n        profile: HasOne::Loaded(\n            profile::ModelEx {\n                picture: \"image.jpg\".into(),\n            }\n            .into(),\n        ),\n        posts: HasMany::Loaded(vec![post::ModelEx {\n            title: \"Nice weather\".into(),\n            tags: HasMany::Loaded(vec![tag::ModelEx {\n                tag: \"sunny\".into(),\n            }]),\n        }]),\n    };\n```\n\n## ActiveModel: nested persistence made simple\nPersist an entire object graph: user, profile (1-1), posts (1-N), and tags (M-N)\nin a single operation using a fluent builder API. SeaORM automatically determines\nthe dependencies and inserts or deletes objects in the correct order.\n\n```rust\n// this creates the nested object as shown above:\nlet user = user::ActiveModel::builder()\n    .set_name(\"Bob\")\n    .set_email(\"bob@sea-ql.org\")\n    .set_profile(profile::ActiveModel::builder().set_picture(\"image.jpg\"))\n    .add_post(\n        post::ActiveModel::builder()\n            .set_title(\"Nice weather\")\n            .add_tag(tag::ActiveModel::builder().set_tag(\"sunny\")),\n    )\n    .save(db)\n    ?;\n```\n\n## Schema first or Entity first? Your choice\n\nSeaORM provides a powerful migration system that lets you create tables, modify schemas, and seed data with ease.\n\nWith SeaORM 2.0, you also get a first-class [Entity First Workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/):\nsimply define new entities or add columns to existing ones,\nand SeaORM will automatically detect the changes and create the new tables, columns, unique keys, and foreign keys.\n\n```rust\n// SeaORM resolves foreign key dependencies and creates the tables in topological order.\n// Requires the `entity-registry` and `schema-sync` feature flags.\ndb.get_schema_registry(\"my_crate::entity::*\").sync(db);\n```\n\n## Ergonomic Raw SQL\n\nLet SeaORM handle 95% of your transactional queries.\nFor the remaining cases that are too complex to express,\nSeaORM still offers convenient support for writing raw SQL.\n```rust\nlet user = Item { name: \"Bob\" }; // nested parameter access\nlet ids = [2, 3, 4]; // expanded by the `..` operator\n\nlet user: Option<user::Model> = user::Entity::find()\n    .from_raw_sql(raw_sql!(\n        Sqlite,\n        r#\"SELECT \"id\", \"name\" FROM \"user\"\n           WHERE \"name\" LIKE {user.name}\n           AND \"id\" in ({..ids})\n        \"#\n    ))\n    .one(db)\n    ?;\n```\n\n## Synchronous Support\n\n[`sea-orm-sync`](https://crates.io/crates/sea-orm-sync) provides the full SeaORM API without requiring an runtime, making it ideal for lightweight CLI programs with SQLite.\n\nSee the [quickstart example](https://github.com/SeaQL/sea-orm/blob/master/sea-orm-sync/examples/quickstart/src/main.rs) for usage.\n\n## Basics\n\n### Select\nSeaORM models 1-N and M-N relationships at the Entity level,\nletting you traverse many-to-many links through a junction table in a single call.\n```rust\n// find all models\nlet cakes: Vec<cake::Model> = Cake::find().all(db)?;\n\n// find and filter\nlet chocolate: Vec<cake::Model> = Cake::find()\n    .filter(Cake::COLUMN.name.contains(\"chocolate\"))\n    .all(db)\n    ?;\n\n// find one model\nlet cheese: Option<cake::Model> = Cake::find_by_id(1).one(db)?;\nlet cheese: cake::Model = cheese.unwrap();\n\n// find related models (lazy)\nlet fruit: Option<fruit::Model> = cheese.find_related(Fruit).one(db)?;\n\n// find related models (eager): for 1-1 relations\nlet cake_with_fruit: Vec<(cake::Model, Option<fruit::Model>)> =\n    Cake::find().find_also_related(Fruit).all(db)?;\n\n// find related models (eager): works for both 1-N and M-N relations\nlet cake_with_fillings: Vec<(cake::Model, Vec<filling::Model>)> = Cake::find()\n    .find_with_related(Filling) // for M-N relations, two joins are performed\n    .all(db) // rows are automatically consolidated by left entity\n    ?;\n```\n### Nested Select\n\nPartial models prevent overfetching by letting you querying only the fields\nyou need; it also makes writing deeply nested relational queries simple.\n```rust\nuse sea_orm::DerivePartialModel;\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"cake::Entity\")]\nstruct CakeWithFruit {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    fruit: Option<fruit::Model>, // this can be a regular or another partial model\n}\n\nlet cakes: Vec<CakeWithFruit> = Cake::find()\n    .left_join(fruit::Entity) // no need to specify join condition\n    .into_partial_model() // only the columns in the partial model will be selected\n    .all(db)\n    ?;\n```\n\n### Insert\nSeaORM's ActiveModel lets you work directly with Rust data structures and\npersist them through a simple API.\nIt's easy to insert large batches of rows from different data sources.\n```rust\nlet apple = fruit::ActiveModel {\n    name: Set(\"Apple\".to_owned()),\n    ..Default::default() // no need to set primary key\n};\n\nlet pear = fruit::ActiveModel {\n    name: Set(\"Pear\".to_owned()),\n    ..Default::default()\n};\n\n// insert one: Active Record style\nlet apple = apple.insert(db)?;\napple.id == 1;\n\n// insert one: repository style\nlet result = Fruit::insert(apple).exec(db)?;\nresult.last_insert_id == 1;\n\n// insert many returning last insert id\nlet result = Fruit::insert_many([apple, pear]).exec(db)?;\nresult.last_insert_id == Some(2);\n```\n\n### Insert (advanced)\nYou can take advantage of database specific features to perform upsert and idempotent insert.\n```rust\n// insert many with returning (if supported by database)\nlet models: Vec<fruit::Model> = Fruit::insert_many([apple, pear])\n    .exec_with_returning(db)\n    ?;\nmodels[0]\n    == fruit::Model {\n        id: 1, // database assigned value\n        name: \"Apple\".to_owned(),\n        cake_id: None,\n    };\n\n// insert with ON CONFLICT on primary key do nothing, with MySQL specific polyfill\nlet result = Fruit::insert_many([apple, pear])\n    .on_conflict_do_nothing()\n    .exec(db)\n    ?;\n\nmatches!(result, TryInsertResult::Conflicted);\n```\n\n### Update\nActiveModel avoids race conditions by updating only the fields you've changed,\nnever overwriting untouched columns.\nYou can also craft complex bulk update queries with a fluent query building API.\n```rust\nuse sea_orm::sea_query::{Expr, Value};\n\nlet pear: Option<fruit::Model> = Fruit::find_by_id(1).one(db)?;\nlet mut pear: fruit::ActiveModel = pear.unwrap().into();\n\npear.name = Set(\"Sweet pear\".to_owned()); // update value of a single field\n\n// update one: only changed columns will be updated\nlet pear: fruit::Model = pear.update(db)?;\n\n// update many: UPDATE \"fruit\" SET \"cake_id\" = \"cake_id\" + 2\n//               WHERE \"fruit\".\"name\" LIKE '%Apple%'\nFruit::update_many()\n    .col_expr(fruit::COLUMN.cake_id, fruit::COLUMN.cake_id.add(2))\n    .filter(fruit::COLUMN.name.contains(\"Apple\"))\n    .exec(db)\n    ?;\n```\n### Save\nYou can perform \"insert or update\" operation with ActiveModel, making it easy to compose transactional operations.\n```rust\nlet banana = fruit::ActiveModel {\n    id: NotSet,\n    name: Set(\"Banana\".to_owned()),\n    ..Default::default()\n};\n\n// create, because primary key `id` is `NotSet`\nlet mut banana = banana.save(db)?;\n\nbanana.id == Unchanged(2);\nbanana.name = Set(\"Banana Mongo\".to_owned());\n\n// update, because primary key `id` is present\nlet banana = banana.save(db)?;\n```\n### Delete\nThe same ActiveModel API consistent with insert and update.\n```rust\n// delete one: Active Record style\nlet orange: Option<fruit::Model> = Fruit::find_by_id(1).one(db)?;\nlet orange: fruit::Model = orange.unwrap();\norange.delete(db)?;\n\n// delete one: repository style\nlet orange = fruit::ActiveModel {\n    id: Set(2),\n    ..Default::default()\n};\nfruit::Entity::delete(orange).exec(db)?;\n\n// delete many: DELETE FROM \"fruit\" WHERE \"fruit\".\"name\" LIKE '%Orange%'\nfruit::Entity::delete_many()\n    .filter(fruit::COLUMN.name.contains(\"Orange\"))\n    .exec(db)\n    ?;\n\n```\n### Raw SQL Query\nThe `raw_sql!` macro is like the `format!` macro but without the risk of SQL injection.\nIt supports nested parameter interpolation, array and tuple expansion, and even repeating group,\noffering great flexibility in crafting complex queries.\n\n```rust\n#[derive(FromQueryResult)]\nstruct CakeWithBakery {\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<Bakery>,\n}\n\n#[derive(FromQueryResult)]\nstruct Bakery {\n    #[sea_orm(alias = \"bakery_name\")]\n    name: String,\n}\n\nlet cake_ids = [2, 3, 4]; // expanded by the `..` operator\n\n// can use many APIs with raw SQL, including nested select\nlet cake: Option<CakeWithBakery> = CakeWithBakery::find_by_statement(raw_sql!(\n    Sqlite,\n    r#\"SELECT \"cake\".\"name\", \"bakery\".\"name\" AS \"bakery_name\"\n       FROM \"cake\"\n       LEFT JOIN \"bakery\" ON \"cake\".\"bakery_id\" = \"bakery\".\"id\"\n       WHERE \"cake\".\"id\" IN ({..cake_ids})\"#\n))\n.one(db)\n?;\n```\n\n## 🧭 Seaography: instant GraphQL API\n\n[Seaography](https://github.com/SeaQL/seaography) is a GraphQL framework built for SeaORM.\nSeaography allows you to build GraphQL resolvers quickly.\nWith just a few commands, you can launch a fullly-featured GraphQL server from SeaORM entities,\ncomplete with filter, pagination, relational queries and mutations!\n\nLook at the [Seaography Example](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) to learn more.\n\n<img src=\"https://raw.githubusercontent.com/SeaQL/sea-orm/master/examples/seaography_example/Seaography%20example.png\"/>\n\n## 🖥️ SeaORM Pro: Professional Admin Panel\n\n[SeaORM Pro](https://github.com/SeaQL/sea-orm-pro/) is an admin panel solution allowing you to quickly and easily launch an admin panel for your application - frontend development skills not required, but certainly nice to have!\n\nSeaORM Pro has been updated to support the latest features in SeaORM 2.0.\n\nFeatures:\n\n+ Full CRUD\n+ Built on React + GraphQL\n+ Built-in GraphQL resolver\n+ Customize the UI with TOML config\n+ Role Based Access Control *(new in 2.0)*\n\nRead the [Getting Started](https://www.sea-ql.org/sea-orm-pro/docs/install-and-config/getting-started/) guide to learn more.\n\n![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-dark.png#gh-dark-mode-only)\n![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-light.png#gh-light-mode-only)\n\n## SQL Server Support\n\n[SQL Server for SeaORM](https://www.sea-ql.org/SeaORM-X/) offers the same SeaORM API for MSSQL. We ported all test cases and examples, complemented by MSSQL specific documentation. If you are building enterprise software, you can [request commercial access](https://forms.office.com/r/1MuRPJmYBR). It is currently based on SeaORM 1.0, but we will offer free upgrade to existing users when SeaORM 2.0 is finalized.\n\n## Releases\n\nSeaORM 2.0 has reached its release candidate phase. We'd love for you to try it out and help shape the final release by [sharing your feedback](https://github.com/SeaQL/sea-orm/discussions/).\n\n+ [Change Log](https://github.com/SeaQL/sea-orm/tree/master/CHANGELOG.md)\n\nSeaORM 2.0 is shaping up to be our most significant release yet - with a few breaking changes, plenty of enhancements, and a clear focus on developer experience.\n\n+ [A Sneak Peek at SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-16-sea-orm-2.0/)\n+ [SeaORM 2.0: A closer look](https://www.sea-ql.org/blog/2025-09-24-sea-orm-2.0/)\n+ [Role Based Access Control in SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-30-sea-orm-rbac/)\n+ [Seaography 2.0: A Powerful and Extensible GraphQL Framework](https://www.sea-ql.org/blog/2025-10-08-seaography/)\n+ [SeaORM 2.0: New Entity Format](https://www.sea-ql.org/blog/2025-10-20-sea-orm-2.0/)\n+ [SeaORM 2.0: Entity First Workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/)\n+ [SeaORM 2.0: Strongly-Typed Column](https://www.sea-ql.org/blog/2025-11-11-sea-orm-2.0/)\n+ [What's new in SeaORM Pro 2.0](https://www.sea-ql.org/blog/2025-11-21-whats-new-in-seaormpro-2.0/)\n+ [SeaORM 2.0: Nested ActiveModel](https://www.sea-ql.org/blog/2025-11-25-sea-orm-2.0/)\n+ [A walk-through of SeaORM 2.0](https://www.sea-ql.org/blog/2025-12-05-sea-orm-2.0/)\n+ [How we made SeaORM synchronous](https://www.sea-ql.org/blog/2025-12-12-sea-orm-2.0/)\n+ [SeaORM 2.0 Migration Guide](https://www.sea-ql.org/blog/2026-01-12-sea-orm-2.0/)\n\nIf you make extensive use of SeaQuery, we recommend checking out our blog post on SeaQuery 1.0 release:\n\n+ [The road to SeaQuery 1.0](https://www.sea-ql.org/blog/2025-08-30-sea-query-1.0/)\n\n## License\n\nLicensed under either of\n\n-   Apache License, Version 2.0\n    ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)\n-   MIT license\n    ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)\n\nat your option.\n\n## Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in the work by you, as defined in the Apache-2.0 license, shall be\ndual licensed as above, without any additional terms or conditions.\n\nWe invite you to participate, contribute and together help build Rust's future.\n\nA big shout out to our contributors!\n\n[![Contributors](https://opencollective.com/sea-orm/contributors.svg?width=1000&button=false)](https://github.com/SeaQL/sea-orm/graphs/contributors)\n\n## Who's using SeaORM?\n\nHere is a short list of awesome open source software built with SeaORM. Feel free to [submit yours](https://github.com/SeaQL/sea-orm/blob/master/COMMUNITY.md#built-with-seaorm)!\n\n| Project | GitHub | Tagline |\n|---------|--------|---------|\n| [Zed](https://github.com/zed-industries/zed) | ![GitHub stars](https://img.shields.io/github/stars/zed-industries/zed.svg?style=social) | A high-performance, multiplayer code editor |\n| [OpenObserve](https://github.com/openobserve/openobserve) | ![GitHub stars](https://img.shields.io/github/stars/openobserve/openobserve.svg?style=social) | Open-source observability platform |\n| [RisingWave](https://github.com/risingwavelabs/risingwave) | ![GitHub stars](https://img.shields.io/github/stars/risingwavelabs/risingwave.svg?style=social) | Stream processing and management platform |\n| [LLDAP](https://github.com/nitnelave/lldap) | ![GitHub stars](https://img.shields.io/github/stars/nitnelave/lldap.svg?style=social) | A light LDAP server for user management |\n| [Warpgate](https://github.com/warp-tech/warpgate) | ![GitHub stars](https://img.shields.io/github/stars/warp-tech/warpgate.svg?style=social) | Smart SSH bastion that works with any SSH client |\n| [Svix](https://github.com/svix/svix-webhooks) | ![GitHub stars](https://img.shields.io/github/stars/svix/svix-webhooks.svg?style=social) | The enterprise ready webhooks service |\n| [Ryot](https://github.com/IgnisDa/ryot) | ![GitHub stars](https://img.shields.io/github/stars/ignisda/ryot.svg?style=social) | The only self hosted tracker you will ever need |\n| [Lapdev](https://github.com/lapce/lapdev) | ![GitHub stars](https://img.shields.io/github/stars/lapce/lapdev.svg?style=social) | Self-hosted remote development enviroment |\n| [System Initiative](https://github.com/systeminit/si) | ![GitHub stars](https://img.shields.io/github/stars/systeminit/si.svg?style=social) | DevOps Automation Platform |\n| [OctoBase](https://github.com/toeverything/OctoBase) | ![GitHub stars](https://img.shields.io/github/stars/toeverything/OctoBase.svg?style=social) | A light-weight, scalable, offline collaborative data backend |\n\n## Sponsorship\n\n[SeaQL.org](https://www.sea-ql.org/) is an independent open-source organization run by passionate developers.\nIf you feel generous, a small donation via [GitHub Sponsor](https://github.com/sponsors/SeaQL) will be greatly appreciated, and goes a long way towards sustaining the organization.\n\n### Gold Sponsors\n\n<table><tr>\n<td><a href=\"https://qdx.co/\">\n  <img src=\"https://www.sea-ql.org/static/sponsors/QDX.svg\" width=\"138\"/>\n</a></td>\n</tr></table>\n\n[QDX](https://qdx.co/) pioneers quantum dynamics-powered drug discovery, leveraging AI and supercomputing to accelerate molecular modeling.\nWe're immensely grateful to QDX for sponsoring the development of SeaORM, the SQL toolkit that powers their data intensive applications.\n\n### Silver Sponsors\n\nWe're grateful to our silver sponsors: Digital Ocean, for sponsoring our servers. And JetBrains, for sponsoring our IDE.\n\n<table><tr>\n<td><a href=\"https://www.digitalocean.com/\">\n  <img src=\"https://www.sea-ql.org/static/sponsors/DigitalOcean.svg\" width=\"125\">\n</a></td>\n\n<td><a href=\"https://www.jetbrains.com/\">\n  <img src=\"https://www.sea-ql.org/static/sponsors/JetBrains.svg\" width=\"125\">\n</a></td>\n</tr></table>\n\n## Mascot\n\nA friend of Ferris, Terres the hermit crab is the official mascot of SeaORM. His hobby is collecting shells.\n\n<img alt=\"Terres\" src=\"https://www.sea-ql.org/SeaORM/img/Terres.png\" width=\"400\"/>\n\n## 🦀 Rustacean Sticker Pack\nThe Rustacean Sticker Pack is the perfect way to express your passion for Rust. Our stickers are made with a premium water-resistant vinyl with a unique matte finish.\n\nSticker Pack Contents:\n\n+ Logo of SeaQL projects: SeaQL, SeaORM, SeaQuery, Seaography\n+ Mascots: Ferris the Crab x 3, Terres the Hermit Crab\n+ The Rustacean wordmark\n\n[Support SeaQL and get a Sticker Pack!](https://www.sea-ql.org/sticker-pack/) All proceeds contributes directly to the ongoing development of SeaQL projects.\n\n<a href=\"https://www.sea-ql.org/sticker-pack/\"><img alt=\"Rustacean Sticker Pack by SeaQL\" src=\"https://www.sea-ql.org/static/sticker-pack-1s.jpg\" width=\"600\"/></a>\n"
  },
  {
    "path": "sea-orm-sync/examples/parquet_example/Cargo.toml",
    "content": "[workspace]\n# A separate workspace\n\n[package]\nedition      = \"2024\"\nname         = \"sea-orm-parquet-example\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nenv_logger = { version = \"0.11\" }\nfastrand   = \"2\"\nlog        = { version = \"0.4\" }\nparquet    = { version = \"58\", default-features = false, features = [\"arrow\"] }\n\n[dependencies.sea-orm-sync]\nfeatures = [\n    \"rusqlite\",\n    \"with-arrow\",\n    \"with-chrono\",\n    \"with-rust_decimal\",\n]\npath = \"../../\"\n"
  },
  {
    "path": "sea-orm-sync/examples/parquet_example/src/main.rs",
    "content": "use sea_orm::{\n    ArrowSchema,\n    entity::*,\n    prelude::{ChronoUtc, Decimal},\n    sea_query::prelude::chrono::Timelike,\n};\n\nuse log::info;\n\nmod measurement {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"measurement\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub recorded_at: ChronoDateTimeUtc,\n        pub sensor_id: i32,\n        pub temperature: f64,\n        #[sea_orm(column_type = \"Decimal(Some((10, 4)))\")]\n        pub voltage: Decimal,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    let env = env_logger::Env::default().filter_or(\"RUST_LOG\", \"info,sea_orm=info,sqlx=warn\");\n    env_logger::Builder::from_env(env).init();\n\n    // -----------------------------------------------------------------------\n    // Step 1: Generate 100 random rows\n    // -----------------------------------------------------------------------\n    let base_ts = ChronoUtc::now();\n    let base_ts = base_ts\n        .with_nanosecond((base_ts.nanosecond() / 1000) * 1000)\n        .unwrap(); // truncate to microsecond\n    let mut rng = fastrand::Rng::new();\n\n    let models: Vec<measurement::ActiveModel> = (1..=100)\n        .map(|i| {\n            let offset = std::time::Duration::from_secs(rng.u64(0..86_400));\n            let ts = base_ts + offset;\n            let sensor_id = rng.i32(100..110);\n            let temperature = -10.0 + rng.f64() * 50.0; // -10 .. 40 °C\n            let voltage_raw = 30000 + rng.i64(0..5000); // 3.0000 .. 3.5000\n            measurement::ActiveModel {\n                id: Set(i),\n                recorded_at: Set(ts),\n                sensor_id: Set(sensor_id),\n                temperature: Set(temperature),\n                voltage: Set(Decimal::new(voltage_raw, 4)),\n            }\n        })\n        .collect();\n\n    let schema = measurement::Entity::arrow_schema();\n    info!(\"Arrow schema: {schema:?}\");\n\n    // -----------------------------------------------------------------------\n    // Step 2: Convert to Arrow RecordBatch and write to Parquet\n    // -----------------------------------------------------------------------\n    let batch = measurement::ActiveModel::to_arrow(&models, &schema)?;\n    info!(\n        \"RecordBatch: {} rows, {} columns\",\n        batch.num_rows(),\n        batch.num_columns()\n    );\n\n    let parquet_path = \"measurements.parquet\";\n\n    {\n        let file = std::fs::File::create(parquet_path)?;\n        let mut writer = parquet::arrow::ArrowWriter::try_new(file, schema.into(), None)?;\n        writer.write(&batch)?;\n        writer.close()?;\n    }\n    info!(\"Wrote Parquet file: {parquet_path}\");\n\n    // -----------------------------------------------------------------------\n    // Step 3: Read the Parquet file back into a RecordBatch\n    // -----------------------------------------------------------------------\n    let file = std::fs::File::open(parquet_path)?;\n    let reader =\n        parquet::arrow::arrow_reader::ParquetRecordBatchReaderBuilder::try_new(file)?.build()?;\n\n    let batches: Vec<_> = reader.collect::<Result<_, _>>()?;\n    info!(\"Read {} batch(es) from Parquet\", batches.len());\n\n    let read_batch = &batches[0];\n    assert_eq!(read_batch.num_rows(), 100);\n\n    // Convert back to ActiveModels\n    let restored = measurement::ActiveModel::from_arrow(read_batch)?;\n    info!(\"Restored {} ActiveModels from Parquet\", restored.len());\n\n    for (original, restored) in models.iter().zip(restored.iter()) {\n        assert_eq!(original, restored, \"Roundtrip mismatch\");\n    }\n    info!(\"Parquet roundtrip verified: all rows match.\");\n\n    // -----------------------------------------------------------------------\n    // Step 4: Dump into SQLite\n    // -----------------------------------------------------------------------\n\n    match std::fs::remove_file(\"measurements.sqlite\") {\n        Ok(_) => (),\n        Err(e) if e.kind() == std::io::ErrorKind::NotFound => (),\n        Err(e) => panic!(\"Failed to remove file: {e}\"),\n    }\n\n    let db = &sea_orm::Database::connect(\"sqlite://measurements.sqlite\")?;\n\n    db.get_schema_builder()\n        .register(measurement::Entity)\n        .apply(db)?;\n    info!(\"SQLite schema created.\");\n\n    measurement::Entity::insert_many(restored).exec(db)?;\n    info!(\"Inserted all rows into SQLite.\");\n\n    info!(\"Done!\");\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/examples/pi_spigot/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"sea-orm-pi-spigot\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nclap       = { version = \"4\", features = [\"derive\"] }\nserde      = { version = \"1\", features = [\"derive\"] }\nserde_json = { version = \"1\" }\n\n[dependencies.sea-orm-sync]\nfeatures = [\"rusqlite\", \"with-json\", \"schema-sync\"]\npath     = \"../../\"\n"
  },
  {
    "path": "sea-orm-sync/examples/pi_spigot/README.md",
    "content": "# Pi Spigot Algorithm Resumable Program Example\n\nThis example shows how easy it is to add SQLite-backed checkpointing to a\nlong-running computation using SeaORM. The idea applies to any stateful program:\nbatch jobs, data pipelines, simulations: anything you want to pause and resume.\n\nWe use the Rabinowitz-Wagon pi spigot algorithm as the example workload. It\nstreams decimal digits of pi one at a time, making it a perfect fit for\ndemonstrating incremental persistence.\n\n## The Pattern: State Machine + Serialization\n\nAny computation that can be modeled as a state machine can be made resumable.\nThe recipe has four parts:\n\n```\nnew()        → initialize fresh state\nstep()       → advance one iteration, mutating &mut self\nfinalize()   → flush any buffered output\nto_state()   → serialize self into a database row\nfrom_state() → deserialize a database row back into self\n```\n\n### Step 1: Define your state as a SeaORM entity\n\nMap every mutable field to a column:\n\n```rust\npub mod state {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"state\")]\n    pub struct Model {\n        #[sea_orm(primary_key, auto_increment = false)]\n        pub digits: u32,         // identifies this computation\n        pub boxes: JsonVec,      // algorithm working memory\n        pub i: u32,              // current iteration\n        pub nines: u32,          // buffered 9s\n        pub predigit: u8,        // held digit\n        pub have_predigit: bool,\n        pub count: u32,          // digits emitted so far\n        #[sea_orm(column_type = \"Text\")]\n        pub result: String,      // emitted digits\n    }\n}\n```\n\nComplex types like `Vec<u32>` are stored as JSON columns via `FromJsonQueryResult`.\n\n### Step 2: Write `to_state` / `from_state`\n\nThese convert between your in-memory struct and the entity model:\n\n```rust\nfn to_state(&self, i: u32) -> state::Model {\n    state::Model {\n        digits: self.digits,\n        boxes: state::JsonVec(self.boxes.clone()),\n        i,\n        nines: self.nines,\n        // ... every field\n    }\n}\n\nfn from_state(s: state::Model) -> Self {\n    Self {\n        digits: s.digits,\n        boxes: s.boxes.0,\n        nines: s.nines,\n        // ... every field\n    }\n}\n```\n\n### Step 3: Checkpoint with transactions\n\nInside your main loop, periodically save state. Use a transaction so the\ncheckpoint is atomic: either everything is saved or nothing is:\n\n```rust\nif self.count % checkpoint_interval == 0 {\n    let txn = db.begin()?;\n    state::Entity::delete_by_id(self.digits).exec(&txn)?;\n    self.to_state(i + 1).into_active_model().insert(&txn)?;\n    txn.commit()?;\n}\n```\n\n### Step 4: Resume on startup\n\nCheck for an existing checkpoint. If found, reconstruct from it; otherwise\nstart fresh:\n\n```rust\npub fn resume(db: &DatabaseConnection, digits: u32) -> Result<Self, DbErr> {\n    db.get_schema_builder()\n        .register(state::Entity)\n        .sync(db)?;   // creates table if it doesn't exist\n\n    match state::Entity::find_by_id(digits).one(db)? {\n        Some(s) => Ok(Self::from_state(s)),\n        None => Ok(Self::new(digits)),\n    }\n}\n```\n\nNote that `get_schema_builder().sync()` creates the table from the entity\ndefinition automatically: no migrations needed.\n\n## Running the example\n\n```sh\n# Compute 10000 digits of pi (checkpoints every 100 digits to pi.sqlite)\ncargo run -- --digits 10000\n\n# Press Ctrl-C at any time, then run again: it resumes from the last checkpoint\ncargo run -- --digits 10000\n\n# Use in-memory SQLite (no persistence, useful for testing)\ncargo run -- --digits 1000 --db \"sqlite::memory:\"\n```\n\n## Running the tests\n\n```sh\ncargo test\n```\n\nThe tests verify correctness against a known 1000-digit reference, including a\nthree-phase checkpoint/resume test: checkpoint at iteration 100, resume and\ncheckpoint again at 500, resume and finish at 1000.\n"
  },
  {
    "path": "sea-orm-sync/examples/pi_spigot/bdigits.html",
    "content": "<!--#include virtual=\"/organics/includes/paperhead.inc\" -->\n<HR>\n<PRE>\n3.1415926535 8979323846 2643383279 5028841971 6939937510\n  5820974944 5923078164 0628620899 8628034825 3421170679\n  8214808651 3282306647 0938446095 5058223172 5359408128\n  4811174502 8410270193 8521105559 6446229489 5493038196\n  4428810975 6659334461 2847564823 3786783165 2712019091\n  4564856692 3460348610 4543266482 1339360726 0249141273\n  7245870066 0631558817 4881520920 9628292540 9171536436\n  7892590360 0113305305 4882046652 1384146951 9415116094\n  3305727036 5759591953 0921861173 8193261179 3105118548\n  0744623799 6274956735 1885752724 8912279381 8301194912\n\n  9833673362 4406566430 8602139494 6395224737 1907021798\n  6094370277 0539217176 2931767523 8467481846 7669405132\n  0005681271 4526356082 7785771342 7577896091 7363717872\n  1468440901 2249534301 4654958537 1050792279 6892589235\n  4201995611 2129021960 8640344181 5981362977 4771309960\n  5187072113 4999999837 2978049951 0597317328 1609631859\n  5024459455 3469083026 4252230825 3344685035 2619311881\n  7101000313 7838752886 5875332083 8142061717 7669147303\n  5982534904 2875546873 1159562863 8823537875 9375195778\n  1857780532 1712268066 1300192787 6611195909 2164201989\n\n  3809525720 1065485863 2788659361 5338182796 8230301952\n  0353018529 6899577362 2599413891 2497217752 8347913151\n  5574857242 4541506959 5082953311 6861727855 8890750983\n  8175463746 4939319255 0604009277 0167113900 9848824012\n  8583616035 6370766010 4710181942 9555961989 4676783744\n  9448255379 7747268471 0404753464 6208046684 2590694912\n  9331367702 8989152104 7521620569 6602405803 8150193511\n  2533824300 3558764024 7496473263 9141992726 0426992279\n  6782354781 6360093417 2164121992 4586315030 2861829745\n  5570674983 8505494588 5869269956 9092721079 7509302955\n\n  3211653449 8720275596 0236480665 4991198818 3479775356\n  6369807426 5425278625 5181841757 4672890977 7727938000\n  8164706001 6145249192 1732172147 7235014144 1973568548\n  1613611573 5255213347 5741849468 4385233239 0739414333\n  4547762416 8625189835 6948556209 9219222184 2725502542\n  5688767179 0494601653 4668049886 2723279178 6085784383\n  8279679766 8145410095 3883786360 9506800642 2512520511\n  7392984896 0841284886 2694560424 1965285022 2106611863\n  0674427862 2039194945 0471237137 8696095636 4371917287\n  4677646575 7396241389 0865832645 9958133904 7802759009\n\n  9465764078 9512694683 9835259570 9825822620 5224894077\n  2671947826 8482601476 9909026401 3639443745 5305068203\n  4962524517 4939965143 1429809190 6592509372 2169646151\n  5709858387 4105978859 5977297549 8930161753 9284681382\n  6868386894 2774155991 8559252459 5395943104 9972524680\n  8459872736 4469584865 3836736222 6260991246 0805124388\n  4390451244 1365497627 8079771569 1435997700 1296160894\n  4169486855 5848406353 4220722258 2848864815 8456028506\n  0168427394 5226746767 8895252138 5225499546 6672782398\n  6456596116 3548862305 7745649803 5593634568 1743241125\n\n  1507606947 9451096596 0940252288 7971089314 5669136867\n  2287489405 6010150330 8617928680 9208747609 1782493858\n  9009714909 6759852613 6554978189 3129784821 6829989487\n  2265880485 7564014270 4775551323 7964145152 3746234364\n  5428584447 9526586782 1051141354 7357395231 1342716610\n  2135969536 2314429524 8493718711 0145765403 5902799344\n  0374200731 0578539062 1983874478 0847848968 3321445713\n  8687519435 0643021845 3191048481 0053706146 8067491927\n  8191197939 9520614196 6342875444 0643745123 7181921799\n  9839101591 9561814675 1426912397 4894090718 6494231961\n\n  5679452080 9514655022 5231603881 9301420937 6213785595\n  6638937787 0830390697 9207734672 2182562599 6615014215\n  0306803844 7734549202 6054146659 2520149744 2850732518\n  6660021324 3408819071 0486331734 6496514539 0579626856\n  1005508106 6587969981 6357473638 4052571459 1028970641\n  4011097120 6280439039 7595156771 5770042033 7869936007\n  2305587631 7635942187 3125147120 5329281918 2618612586\n  7321579198 4148488291 6447060957 5270695722 0917567116\n  7229109816 9091528017 3506712748 5832228718 3520935396\n  5725121083 5791513698 8209144421 0067510334 6711031412\n\n  6711136990 8658516398 3150197016 5151168517 1437657618\n  3515565088 4909989859 9823873455 2833163550 7647918535\n  8932261854 8963213293 3089857064 2046752590 7091548141\n  6549859461 6371802709 8199430992 4488957571 2828905923\n  2332609729 9712084433 5732654893 8239119325 9746366730\n  5836041428 1388303203 8249037589 8524374417 0291327656\n  1809377344 4030707469 2112019130 2033038019 7621101100\n  4492932151 6084244485 9637669838 9522868478 3123552658\n  2131449576 8572624334 4189303968 6426243410 7732269780\n  2807318915 4411010446 8232527162 0105265227 2111660396\n\n  6655730925 4711055785 3763466820 6531098965 2691862056\n  4769312570 5863566201 8558100729 3606598764 8611791045\n  3348850346 1136576867 5324944166 8039626579 7877185560\n  8455296541 2665408530 6143444318 5867697514 5661406800\n  7002378776 5913440171 2749470420 5622305389 9456131407\n  1127000407 8547332699 3908145466 4645880797 2708266830\n  6343285878 5698305235 8089330657 5740679545 7163775254\n  2021149557 6158140025 0126228594 1302164715 5097925923\n  0990796547 3761255176 5675135751 7829666454 7791745011\n  2996148903 0463994713 2962107340 4375189573 5961458901\n\n  9389713111 7904297828 5647503203 1986915140 2870808599\n  0480109412 1472213179 4764777262 2414254854 5403321571\n  8530614228 8137585043 0633217518 2979866223 7172159160\n  7716692547 4873898665 4949450114 6540628433 6639379003\n  9769265672 1463853067 3609657120 9180763832 7166416274\n  8888007869 2560290228 4721040317 2118608204 1900042296\n  6171196377 9213375751 1495950156 6049631862 9472654736\n  4252308177 0367515906 7350235072 8354056704 0386743513\n  6222247715 8915049530 9844489333 0963408780 7693259939\n  7805419341 4473774418 4263129860 8099888687 4132604721\n\n  5695162396 5864573021 6315981931 9516735381 2974167729\n  4786724229 2465436680 0980676928 2382806899 6400482435\n  4037014163 1496589794 0924323789 6907069779 4223625082\n  2168895738 3798623001 5937764716 5122893578 6015881617\n  5578297352 3344604281 5126272037 3431465319 7777416031\n  9906655418 7639792933 4419521541 3418994854 4473456738\n  3162499341 9131814809 2777710386 3877343177 2075456545\n  3220777092 1201905166 0962804909 2636019759 8828161332\n  3166636528 6193266863 3606273567 6303544776 2803504507\n  7723554710 5859548702 7908143562 4014517180 6246436267\n\n  9456127531 8134078330 3362542327 8394497538 2437205835\n  3114771199 2606381334 6776879695 9703098339 1307710987\n  0408591337 4641442822 7726346594 7047458784 7787201927\n  7152807317 6790770715 7213444730 6057007334 9243693113\n  8350493163 1284042512 1925651798 0694113528 0131470130\n  4781643788 5185290928 5452011658 3934196562 1349143415\n  9562586586 5570552690 4965209858 0338507224 2648293972\n  8584783163 0577775606 8887644624 8246857926 0395352773\n  4803048029 0058760758 2510474709 1643961362 6760449256\n  2742042083 2085661190 6254543372 1315359584 5068772460\n\n  2901618766 7952406163 4252257719 5429162991 9306455377\n  9914037340 4328752628 8896399587 9475729174 6426357455\n  2540790914 5135711136 9410911939 3251910760 2082520261\n  8798531887 7058429725 9167781314 9699009019 2116971737\n  2784768472 6860849003 3770242429 1651300500 5168323364\n  3503895170 2989392233 4517220138 1280696501 1784408745\n  1960121228 5993716231 3017114448 4640903890 6449544400\n  6198690754 8516026327 5052983491 8740786680 8818338510\n  2283345085 0486082503 9302133219 7155184306 3545500766\n  8282949304 1377655279 3975175461 3953984683 3936383047\n\n  4611996653 8581538420 5685338621 8672523340 2830871123\n  2827892125 0771262946 3229563989 8989358211 6745627010\n  2183564622 0134967151 8819097303 8119800497 3407239610\n  3685406643 1939509790 1906996395 5245300545 0580685501\n  9567302292 1913933918 5680344903 9820595510 0226353536\n  1920419947 4553859381 0234395544 9597783779 0237421617\n  2711172364 3435439478 2218185286 2408514006 6604433258\n  8856986705 4315470696 5747458550 3323233421 0730154594\n  0516553790 6866273337 9958511562 5784322988 2737231989\n  8757141595 7811196358 3300594087 3068121602 8764962867\n\n  4460477464 9159950549 7374256269 0104903778 1986835938\n  1465741268 0492564879 8556145372 3478673303 9046883834\n  3634655379 4986419270 5638729317 4872332083 7601123029\n  9113679386 2708943879 9362016295 1541337142 4892830722\n  0126901475 4668476535 7616477379 4675200490 7571555278\n  1965362132 3926406160 1363581559 0742202020 3187277605\n  2772190055 6148425551 8792530343 5139844253 2234157623\n  3610642506 3904975008 6562710953 5919465897 5141310348\n  2276930624 7435363256 9160781547 8181152843 6679570611\n  0861533150 4452127473 9245449454 2368288606 1340841486\n\n  3776700961 2071512491 4043027253 8607648236 3414334623\n  5189757664 5216413767 9690314950 1910857598 4423919862\n  9164219399 4907236234 6468441173 9403265918 4044378051\n  3338945257 4239950829 6591228508 5558215725 0310712570\n  1266830240 2929525220 1187267675 6220415420 5161841634\n  8475651699 9811614101 0029960783 8690929160 3028840026\n  9104140792 8862150784 2451670908 7000699282 1206604183\n  7180653556 7252532567 5328612910 4248776182 5829765157\n  9598470356 2226293486 0034158722 9805349896 5022629174\n  8788202734 2092222453 3985626476 6914905562 8425039127\n\n  5771028402 7998066365 8254889264 8802545661 0172967026\n  6407655904 2909945681 5065265305 3718294127 0336931378\n  5178609040 7086671149 6558343434 7693385781 7113864558\n  7367812301 4587687126 6034891390 9562009939 3610310291\n  6161528813 8437909904 2317473363 9480457593 1493140529\n  7634757481 1935670911 0137751721 0080315590 2485309066\n  9203767192 2033229094 3346768514 2214477379 3937517034\n  4366199104 0337511173 5471918550 4644902636 5512816228\n  8244625759 1633303910 7225383742 1821408835 0865739177\n  1509682887 4782656995 9957449066 1758344137 5223970968\n\n  3408005355 9849175417 3818839994 4697486762 6551658276\n  5848358845 3142775687 9002909517 0283529716 3445621296\n  4043523117 6006651012 4120065975 5851276178 5838292041\n  9748442360 8007193045 7618932349 2292796501 9875187212\n  7267507981 2554709589 0455635792 1221033346 6974992356\n  3025494780 2490114195 2123828153 0911407907 3860251522\n  7429958180 7247162591 6685451333 1239480494 7079119153\n  2673430282 4418604142 6363954800 0448002670 4962482017\n  9289647669 7583183271 3142517029 6923488962 7668440323\n  2609275249 6035799646 9256504936 8183609003 2380929345\n\n  9588970695 3653494060 3402166544 3755890045 6328822505\n  4525564056 4482465151 8754711962 1844396582 5337543885\n  6909411303 1509526179 3780029741 2076651479 3942590298\n  9695946995 5657612186 5619673378 6236256125 2163208628\n  6922210327 4889218654 3648022967 8070576561 5144632046\n  9279068212 0738837781 4233562823 6089632080 6822246801\n  2248261177 1858963814 0918390367 3672220888 3215137556\n  0037279839 4004152970 0287830766 7094447456 0134556417\n  2543709069 7939612257 1429894671 5435784687 8861444581\n  2314593571 9849225284 7160504922 1242470141 2147805734\n\n  5510500801 9086996033 0276347870 8108175450 1193071412\n  2339086639 3833952942 5786905076 4310063835 1983438934\n  1596131854 3475464955 6978103829 3097164651 4384070070\n  7360411237 3599843452 2516105070 2705623526 6012764848\n  3084076118 3013052793 2054274628 6540360367 4532865105\n  7065874882 2569815793 6789766974 2205750596 8344086973\n  5020141020 6723585020 0724522563 2651341055 9240190274\n  2162484391 4035998953 5394590944 0704691209 1409387001\n  2645600162 3742880210 9276457931 0657922955 2498872758\n  4610126483 6999892256 9596881592 0560010165 5256375679\n</PRE>\n<!--#include virtual=\"/organics/includes/paperfoot.inc\" -->\n"
  },
  {
    "path": "sea-orm-sync/examples/pi_spigot/src/lib.rs",
    "content": "use sea_orm::{\n    ActiveModelTrait, DatabaseConnection, EntityTrait, IntoActiveModel, NotSet, Set,\n    TransactionTrait,\n};\n\npub mod state {\n    use sea_orm::entity::prelude::*;\n    use serde::{Deserialize, Serialize};\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"state\")]\n    pub struct Model {\n        #[sea_orm(primary_key, auto_increment = false)]\n        pub digits: u32,\n        pub boxes: JsonVec,\n        pub i: u32,\n        pub nines: u32,\n        pub predigit: u8,\n        pub have_predigit: bool,\n        pub count: u32,\n        #[sea_orm(column_type = \"Text\")]\n        pub result: String,\n    }\n\n    #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, FromJsonQueryResult)]\n    pub struct JsonVec(pub Vec<u32>);\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod run_log {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"run_log\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub digits: u32,\n        #[sea_orm(column_type = \"Text\")]\n        pub pi_digits: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n/// Tracks the mutable computation state of the spigot algorithm.\npub struct PiSpigot {\n    digits: u32,\n    boxes: Vec<u32>,\n    nines: u32,\n    predigit: u8,\n    have_predigit: bool,\n    count: u32,\n    result: String,\n    start_i: u32,\n}\n\nimpl PiSpigot {\n    /// Create a new computation for the given number of decimal digits (after \"3.\").\n    pub fn new(digits: u32) -> Self {\n        let len = digits as usize * 10 / 3 + 1;\n        Self {\n            digits,\n            boxes: vec![2u32; len],\n            nines: 0,\n            predigit: 0,\n            have_predigit: false,\n            count: 0,\n            result: String::new(),\n            start_i: 0,\n        }\n    }\n\n    /// Load from a checkpoint if one exists, otherwise create fresh.\n    pub fn resume(db: &DatabaseConnection, digits: u32) -> Result<Self, sea_orm::DbErr> {\n        db.get_schema_builder()\n            .register(state::Entity)\n            .register(run_log::Entity)\n            .sync(db)?;\n\n        match state::Entity::find_by_id(digits).one(db)? {\n            Some(s) => {\n                eprintln!(\n                    \"Resuming from checkpoint (iteration {}, {} digits result)\",\n                    s.i, s.count\n                );\n                Ok(Self::from_state(s))\n            }\n            None => Ok(Self::new(digits)),\n        }\n    }\n\n    /// Compute all digits without database persistence. Returns the decimal\n    /// digits of pi after \"3.\" (e.g. \"14159265...\" for 8 digits).\n    pub fn compute(mut self) -> String {\n        for _ in 0..=self.digits {\n            self.step();\n        }\n        self.finalize();\n        self.result\n    }\n\n    /// Compute with database persistence, checkpointing every `checkpoint_interval` iterations.\n    /// Returns the fractional digits of pi (after \"3.\").\n    pub fn compute_with_db(\n        mut self,\n        db: &DatabaseConnection,\n        checkpoint_interval: u32,\n    ) -> Result<String, sea_orm::DbErr> {\n        db.get_schema_builder()\n            .register(state::Entity)\n            .register(run_log::Entity)\n            .sync(db)?;\n\n        let mut run_log = run_log::ActiveModel {\n            id: NotSet,\n            digits: Set(self.digits),\n            pi_digits: Set(String::new()),\n        }\n        .save(db)?;\n\n        for i in self.start_i..=self.digits {\n            self.step();\n\n            if checkpoint_interval > 0 && self.count > 0 && self.count % checkpoint_interval == 0 {\n                let txn = db.begin()?;\n                state::Entity::delete_by_id(self.digits).exec(&txn)?;\n                self.to_state(i + 1).into_active_model().insert(&txn)?;\n                run_log.pi_digits = Set(self.result.clone());\n                run_log = run_log.save(&txn)?;\n                txn.commit()?;\n                let start = self\n                    .result\n                    .len()\n                    .saturating_sub(checkpoint_interval as usize);\n                eprintln!(\"[{}] {}\", self.count, &self.result[start..]);\n            }\n        }\n\n        self.finalize();\n\n        state::Entity::delete_by_id(self.digits).exec(db)?;\n\n        run_log.pi_digits = Set(self.result.clone());\n        run_log.save(db)?;\n\n        Ok(self.result)\n    }\n\n    /// Resume from a persisted state, recovering previously result digits.\n    fn from_state(s: state::Model) -> Self {\n        Self {\n            digits: s.digits,\n            boxes: s.boxes.0,\n            nines: s.nines,\n            predigit: s.predigit,\n            have_predigit: s.have_predigit,\n            count: s.count,\n            result: s.result,\n            start_i: s.i,\n        }\n    }\n\n    /// Build a state model for checkpoint persistence.\n    fn to_state(&self, i: u32) -> state::Model {\n        state::Model {\n            digits: self.digits,\n            boxes: state::JsonVec(self.boxes.clone()),\n            i,\n            nines: self.nines,\n            predigit: self.predigit,\n            have_predigit: self.have_predigit,\n            count: self.count,\n            result: self.result.clone(),\n        }\n    }\n\n    fn push_digit(&mut self, digit: u8) {\n        self.result.push((b'0' + digit) as char);\n        self.count += 1;\n    }\n\n    /// Run one iteration of the spigot algorithm, producing zero or more digits.\n    fn step(&mut self) {\n        let len = self.boxes.len();\n        let mut carry: u32 = 0;\n\n        for j in (1..len).rev() {\n            let j_u = j as u32;\n            let x = self.boxes[j] * 10 + carry;\n            self.boxes[j] = x % (2 * j_u + 1);\n            carry = (x / (2 * j_u + 1)) * j_u;\n        }\n        let x = self.boxes[0] * 10 + carry;\n        let q = (x / 10) as u8;\n        self.boxes[0] = x % 10;\n\n        if q == 9 {\n            self.nines += 1;\n        } else if q == 10 {\n            if self.have_predigit {\n                self.push_digit(self.predigit + 1);\n            } else {\n                self.push_digit(1);\n                self.have_predigit = true;\n            }\n            for _ in 0..self.nines {\n                self.push_digit(0);\n            }\n            self.predigit = 0;\n            self.nines = 0;\n        } else {\n            if self.have_predigit {\n                self.push_digit(self.predigit);\n            } else {\n                self.have_predigit = true;\n            }\n            self.predigit = q;\n            for _ in 0..self.nines {\n                self.push_digit(9);\n            }\n            self.nines = 0;\n        }\n    }\n\n    /// Flush the final predigit and strip the leading \"3\" so the result\n    /// contains only fractional digits (e.g. \"14159...\" not \"314159...\").\n    fn finalize(&mut self) {\n        self.push_digit(self.predigit);\n        for _ in 0..self.nines {\n            self.push_digit(9);\n        }\n        self.nines = 0;\n        // The spigot algorithm produces digits starting with 3; strip it.\n        if self.result.starts_with('3') {\n            self.result.remove(0);\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    const PI_1000: &str = \"\\\n        14159265358979323846264338327950288419716939937510\\\n        58209749445923078164062862089986280348253421170679\\\n        82148086513282306647093844609550582231725359408128\\\n        48111745028410270193852110555964462294895493038196\\\n        44288109756659334461284756482337867831652712019091\\\n        45648566923460348610454326648213393607260249141273\\\n        72458700660631558817488152092096282925409171536436\\\n        78925903600113305305488204665213841469519415116094\\\n        33057270365759591953092186117381932611793105118548\\\n        07446237996274956735188575272489122793818301194912\\\n        98336733624406566430860213949463952247371907021798\\\n        60943702770539217176293176752384674818467669405132\\\n        00056812714526356082778577134275778960917363717872\\\n        14684409012249534301465495853710507922796892589235\\\n        42019956112129021960864034418159813629774771309960\\\n        51870721134999999837297804995105973173281609631859\\\n        50244594553469083026425223082533446850352619311881\\\n        71010003137838752886587533208381420617177669147303\\\n        59825349042875546873115956286388235378759375195778\\\n        18577805321712268066130019278766111959092164201989\";\n\n    #[test]\n    fn test_compute_10_digits() {\n        let result = PiSpigot::new(10).compute();\n        assert_eq!(&result[..10], &PI_1000[..10]);\n    }\n\n    #[test]\n    fn test_compute_100_digits() {\n        let result = PiSpigot::new(100).compute();\n        assert_eq!(&result[..100], &PI_1000[..100]);\n    }\n\n    #[test]\n    fn test_compute_1000_digits() {\n        let result = PiSpigot::new(1000).compute();\n        assert_eq!(&result[..1000], PI_1000);\n    }\n\n    #[test]\n    fn test_compute_with_db() {\n        let db = sea_orm::Database::connect(\"sqlite::memory:\").unwrap();\n        let spigot = PiSpigot::new(100);\n        let result = spigot.compute_with_db(&db, 10).unwrap();\n        assert_eq!(&result[..100], &PI_1000[..100]);\n    }\n\n    #[test]\n    fn test_checkpoint_resume() {\n        let db = sea_orm::Database::connect(\"sqlite::memory:\").unwrap();\n\n        db.get_schema_builder()\n            .register(state::Entity)\n            .register(run_log::Entity)\n            .sync(&db)\n            .unwrap();\n\n        // Phase 1: step 0..100, checkpoint\n        let mut spigot = PiSpigot::new(1000);\n        for _ in 0..100 {\n            spigot.step();\n        }\n        spigot\n            .to_state(100)\n            .into_active_model()\n            .insert(&db)\n            .unwrap();\n\n        // Phase 2: resume, step 100..500, checkpoint again\n        let mut spigot = PiSpigot::resume(&db, 1000).unwrap();\n        assert_eq!(spigot.start_i, 100);\n        for _ in 100..500 {\n            spigot.step();\n        }\n        state::Entity::delete_by_id(1000u32).exec(&db).unwrap();\n        spigot\n            .to_state(500)\n            .into_active_model()\n            .insert(&db)\n            .unwrap();\n\n        // Phase 3: resume from second checkpoint, finish\n        let resumed = PiSpigot::resume(&db, 1000).unwrap();\n        assert_eq!(resumed.start_i, 500);\n        let result = resumed.compute_with_db(&db, 0).unwrap();\n        assert_eq!(result, PI_1000);\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/examples/pi_spigot/src/main.rs",
    "content": "use clap::Parser;\nuse sea_orm::Database;\nuse sea_orm_pi_spigot::PiSpigot;\n\n#[derive(Parser)]\n#[command(name = \"pi-spigot\", about = \"Compute digits of pi with checkpointing\")]\nstruct Cli {\n    /// Number of decimal digits to compute (after \"3.\")\n    #[arg(short, long, default_value_t = 100)]\n    digits: u32,\n\n    /// Checkpoint every N digits (0 to disable)\n    #[arg(short, long, default_value_t = 100)]\n    checkpoint: u32,\n\n    /// SQLite database path for persistence\n    #[arg(long, default_value = \"sqlite://pi.sqlite\")]\n    db: String,\n}\n\nfn main() {\n    let cli = Cli::parse();\n\n    let db = Database::connect(&cli.db).expect(\"Failed to connect to database\");\n\n    let spigot = PiSpigot::resume(&db, cli.digits).expect(\"Failed to initialize\");\n\n    println!(\"Computing {} decimal digits of pi...\", cli.digits);\n    let result = spigot\n        .compute_with_db(&db, cli.checkpoint)\n        .expect(\"Computation failed\");\n\n    println!(\"Finished computing {} digits of pi.\", cli.digits);\n    println!(\"3.{result}\");\n}\n"
  },
  {
    "path": "sea-orm-sync/examples/quickstart/Cargo.toml",
    "content": "[package]\nedition      = \"2024\"\nname         = \"sea-orm-quickstart\"\npublish      = false\nrust-version = \"1.85.0\"\nversion      = \"0.1.0\"\n\n[dependencies]\nenv_logger = { version = \"0.11\" }\nlog        = { version = \"0.4\" }\n\n[dependencies.sea-orm-sync]\nfeatures = [\n    \"rusqlite\",\n    \"debug-print\",\n    \"entity-registry\",\n    \"schema-sync\",\n]\npath = \"../../\"\n"
  },
  {
    "path": "sea-orm-sync/examples/quickstart/README.md",
    "content": "# SeaORM Quick Start\n\nThis is a single file app that strives to minimize dependency and code noise. It uses an in-memory SQLite database so there is no setup. Just do `cargo run`!"
  },
  {
    "path": "sea-orm-sync/examples/quickstart/src/main.rs",
    "content": "use log::info;\n\nmod user {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"user\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n        #[sea_orm(unique)]\n        pub email: String,\n        #[sea_orm(has_one)]\n        pub profile: HasOne<super::profile::Entity>,\n        #[sea_orm(has_many)]\n        pub posts: HasMany<super::post::Entity>,\n        #[sea_orm(self_ref, via = \"user_follower\", from = \"User\", to = \"Follower\")]\n        pub followers: HasMany<Entity>,\n        #[sea_orm(self_ref, via = \"user_follower\", reverse)]\n        pub following: HasMany<Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod profile {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"profile\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub picture: String,\n        #[sea_orm(unique)]\n        pub user_id: i32,\n        #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n        pub user: HasOne<super::user::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod post {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"post\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub user_id: i32,\n        pub title: String,\n        #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n        pub author: HasOne<super::user::Entity>,\n        #[sea_orm(has_many)]\n        pub comments: HasMany<super::comment::Entity>,\n        #[sea_orm(has_many, via = \"post_tag\")]\n        pub tags: HasMany<super::tag::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod comment {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"comment\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub comment: String,\n        pub user_id: i32,\n        pub post_id: i32,\n        #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n        pub user: HasOne<super::user::Entity>,\n        #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n        pub post: HasOne<super::post::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod tag {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"tag\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub tag: String,\n        #[sea_orm(has_many, via = \"post_tag\")]\n        pub posts: HasMany<super::post::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod post_tag {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n    #[sea_orm(table_name = \"post_tag\")]\n    pub struct Model {\n        #[sea_orm(primary_key, auto_increment = false)]\n        pub post_id: i32,\n        #[sea_orm(primary_key, auto_increment = false)]\n        pub tag_id: i32,\n        #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n        pub post: Option<super::post::Entity>,\n        #[sea_orm(belongs_to, from = \"tag_id\", to = \"id\")]\n        pub tag: Option<super::tag::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod user_follower {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n    #[sea_orm(table_name = \"user_follower\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub user_id: i32,\n        #[sea_orm(primary_key)]\n        pub follower_id: i32,\n        #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n        pub user: Option<super::user::Entity>,\n        #[sea_orm(\n            belongs_to,\n            relation_enum = \"Follower\",\n            from = \"follower_id\",\n            to = \"id\"\n        )]\n        pub follower: Option<super::user::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nfn main() -> Result<(), sea_orm::DbErr> {\n    ///// Part 0: Setup Environment /////\n\n    // This disables sqlx's logging and enables sea-orm's logging with parameter injection,\n    // which is easier to debug.\n    let env = env_logger::Env::default().filter_or(\"RUST_LOG\", \"info,sea_orm=debug,sqlx=warn\");\n    env_logger::Builder::from_env(env).init();\n\n    use sea_orm::{entity::*, query::*};\n\n    // Use a SQLite in memory database so no setup needed.\n    // SeaORM supports MySQL, Postgres, SQL Server as well.\n    let db = &sea_orm::Database::connect(\"sqlite::memory:\")?;\n\n    // Populate this fresh database with tables.\n    //\n    // All entities defined in this crate are automatically registered\n    // into the schema registry, regardless of which module they live in.\n    //\n    // The registry may also include entities from upstream crates,\n    // so here we restrict it to entities defined in this crate only.\n    //\n    // The order of entity definitions does not matter.\n    // SeaORM resolves foreign key dependencies automatically\n    // and creates the tables in the correct order with their keys.\n    db.get_schema_registry(\"sea_orm_quickstart::*\").sync(db)?;\n\n    info!(\"Schema created.\");\n\n    ///// Part 1: CRUD with nested 1-1 and 1-N relations /////\n\n    info!(\"Create user Bob with a profile:\");\n    let bob = user::ActiveModel::builder()\n        .set_name(\"Bob\")\n        .set_email(\"bob@sea-ql.org\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Tennis\"))\n        .insert(db)?;\n\n    info!(\"Find Bob by email:\");\n    assert_eq!(\n        bob,\n        // this method is generated by #[sea_orm::model] on unique keys\n        user::Entity::find_by_email(\"bob@sea-ql.org\")\n            .one(db)?\n            .unwrap()\n    );\n\n    info!(\"Query user with profile in a single query:\");\n    let mut bob = user::Entity::load()\n        .filter_by_id(bob.id)\n        .with(profile::Entity)\n        .one(db)?\n        .expect(\"Not found\");\n    assert_eq!(bob.name, \"Bob\");\n    assert_eq!(bob.profile.as_ref().unwrap().picture, \"Tennis\");\n\n    // Here we take ownership of the nested model, modify in place and save it\n    info!(\"Update Bob's profile:\");\n    bob.profile\n        .take()\n        .unwrap()\n        .into_active_model()\n        .set_picture(\"Landscape\")\n        .save(db)?;\n\n    info!(\"Confirmed that it's been updated:\");\n    assert_eq!(\n        profile::Entity::find_by_user_id(bob.id).all(db)?[0].picture,\n        \"Landscape\"\n    );\n\n    // we don't have to set the `user_id` of the posts, they're automatically set to Bob\n    info!(\"Bob wrote some posts:\");\n    let mut bob = bob.into_active_model();\n    bob.posts\n        .push(\n            post::ActiveModel::builder()\n                .set_title(\"Lorem ipsum dolor sit amet, consectetur adipiscing elit\"),\n        )\n        .push(\n            post::ActiveModel::builder()\n                .set_title(\"Ut enim ad minim veniam, quis nostrud exercitation\"),\n        );\n    bob.save(db)?;\n\n    info!(\"Find Bob's profile and his posts:\");\n    let bob = user::Entity::load()\n        .filter(user::COLUMN.name.eq(\"Bob\"))\n        .with(profile::Entity)\n        .with(post::Entity)\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(bob.name, \"Bob\");\n    assert_eq!(bob.profile.as_ref().unwrap().picture, \"Landscape\");\n    assert!(bob.posts[0].title.starts_with(\"Lorem ipsum\"));\n    assert!(bob.posts[1].title.starts_with(\"Ut enim ad\"));\n\n    // It's actually fine to create user + profile the other way round.\n    // SeaORM figures out the dependency and creates the user first.\n    info!(\"Create a new user Alice:\");\n    let alice = profile::ActiveModel::builder()\n        .set_user(\n            user::ActiveModel::builder()\n                .set_name(\"Alice\")\n                .set_email(\"alice@rust-lang.org\"),\n        )\n        .set_picture(\"Park\")\n        .insert(db)?\n        .user\n        .unwrap();\n\n    // Not only can we insert new posts via the bob active model,\n    // we can also add new comments to the posts.\n    // SeaORM walks the document tree and figures out what's changed,\n    // and perform the operation in one transaction.\n    let mut bob = bob.into_active_model();\n    info!(\"Alice commented on Bob's post:\");\n    bob.posts[0].comments.push(\n        comment::ActiveModel::builder()\n            .set_comment(\"nice post!\")\n            .set_user_id(alice.id),\n    );\n    bob.posts[1].comments.push(\n        comment::ActiveModel::builder()\n            .set_comment(\"interesting!\")\n            .set_user_id(alice.id),\n    );\n    let bob = bob.save(db)?;\n\n    info!(\"Find all posts with author along with comments and who commented:\");\n    let posts = post::Entity::load()\n        .with(user::Entity)\n        .with((comment::Entity, user::Entity))\n        .all(db)?;\n\n    assert!(posts[0].title.starts_with(\"Lorem ipsum\"));\n    assert_eq!(posts[0].author.as_ref().unwrap().name, \"Bob\");\n    assert_eq!(posts[0].comments.len(), 1);\n    assert_eq!(posts[0].comments[0].comment, \"nice post!\");\n    assert_eq!(posts[0].comments[0].user.as_ref().unwrap().name, \"Alice\");\n\n    assert!(posts[1].title.starts_with(\"Ut enim ad\"));\n    assert_eq!(posts[1].author.as_ref().unwrap().name, \"Bob\");\n    assert_eq!(posts[1].comments.len(), 1);\n    assert_eq!(posts[1].comments[0].comment, \"interesting!\");\n\n    // Again, we can apply multiple changes in one operation,\n    // the queries are executed inside a transaction.\n    info!(\"Update post title and comment on first post:\");\n    let mut post = posts[0].clone().into_active_model();\n    post.title = Set(\"Lorem ipsum dolor sit amet\".into()); // shorten it\n    post.comments[0].comment = Set(\"nice post! I learnt a lot\".into());\n    post.save(db)?;\n\n    info!(\"Confirm the post and comment is updated\");\n    let post = post::Entity::load()\n        .filter_by_id(posts[0].id)\n        .with(comment::Entity)\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(post.title, \"Lorem ipsum dolor sit amet\");\n    assert_eq!(post.comments[0].comment, \"nice post! I learnt a lot\");\n\n    // Comments belongs to post. They will be deleted first, otherwise the foreign key\n    // would prevent the operation.\n    info!(\"Delete the post along with all comments\");\n    post.delete(db)?;\n\n    assert!(post::Entity::find_by_id(posts[0].id).one(db)?.is_none());\n\n    ///// Part 2: managing M-N relations /////\n\n    // A unique feature of SeaORM is modelling many-to-many relations in a high level way\n\n    info!(\"Insert one tag for later use\");\n    let sunny = tag::ActiveModel::builder().set_tag(\"sunny\").save(db)?;\n\n    info!(\"Insert a new post with 2 tags\");\n    let mut post = post::ActiveModel::builder()\n        .set_title(\"A perfect day out\")\n        .set_user_id(alice.id)\n        .add_tag(sunny.clone()) // an existing tag\n        .add_tag(tag::ActiveModel::builder().set_tag(\"foodie\")) // a new tag\n        .save(db) // new tag will be created and associcated to the new post\n        ?;\n\n    let post_id = post.id.clone().unwrap();\n\n    {\n        info!(\"get back the post and tags\");\n        let post = post::Entity::load()\n            .filter_by_id(post_id)\n            .with(tag::Entity)\n            .one(db)?\n            .unwrap();\n        assert_eq!(post.title, \"A perfect day out\");\n        assert_eq!(post.tags.len(), 2);\n        assert_eq!(post.tags[0].tag, \"sunny\");\n        assert_eq!(post.tags[1].tag, \"foodie\");\n    }\n\n    info!(\"Add new tag to post\");\n    post.tags\n        .push(tag::ActiveModel::builder().set_tag(\"downtown\"));\n    let mut post = post.save(db)?;\n\n    {\n        info!(\"get back the post and tags\");\n        let post = post::Entity::load()\n            .filter_by_id(post_id)\n            .with(tag::Entity)\n            .one(db)?\n            .unwrap();\n        assert_eq!(post.tags.len(), 3);\n        assert_eq!(post.tags[0].tag, \"sunny\");\n        assert_eq!(post.tags[1].tag, \"foodie\");\n        assert_eq!(post.tags[2].tag, \"downtown\");\n    }\n\n    info!(\"Update post title and remove a tag\");\n    let mut tags = post.tags.take();\n    tags.as_mut_vec().remove(0); // it actually rained\n    post.title = Set(\"Almost a perfect day out\".into());\n    post.tags.replace_all(tags);\n    // converting the field from append to replace would delete associations not in this list\n    let post = post.save(db)?;\n\n    {\n        info!(\"get back the post and tags\");\n        let post = post::Entity::load()\n            .filter_by_id(post_id)\n            .with(tag::Entity)\n            .one(db)?\n            .unwrap();\n        assert_eq!(post.tags.len(), 2);\n        assert_eq!(post.title, \"Almost a perfect day out\");\n        assert_eq!(post.tags[0].tag, \"foodie\");\n        assert_eq!(post.tags[1].tag, \"downtown\");\n    }\n\n    // only the association between post and tag is removed,\n    // but the tag itself is not deleted\n    info!(\"check that the tag sunny still exists\");\n    assert!(tag::Entity::find_by_tag(\"sunny\").one(db)?.is_some());\n\n    info!(\"cascade delete post, remove tag associations\");\n    post.delete(db)?;\n\n    ///// Part 3: self-referencing relations /////\n\n    info!(\"save a new user with a new profile\");\n    let sam = user::ActiveModel::builder()\n        .set_name(\"Sam\")\n        .set_email(\"sam@rustacean.net\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Crab.jpg\"))\n        .save(db)?;\n\n    // we can do it from left to right: user <- follower\n    info!(\"Add follower to Alice\");\n    let alice = alice.into_active_model().add_follower(bob).save(db)?;\n\n    // we can also do it in reverse: user -> following\n    info!(\"Sam starts following Alice\");\n    sam.add_following(alice).save(db)?;\n\n    info!(\"Query Alice's profile and followers\");\n    let alice = user::Entity::load()\n        .filter_by_email(\"alice@rust-lang.org\")\n        .with(profile::Entity)\n        .with(user_follower::Entity)\n        .with(user_follower::Entity::REVERSE)\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(alice.name, \"Alice\");\n    assert_eq!(alice.profile.as_ref().unwrap().picture, \"Park\");\n    assert_eq!(alice.followers.len(), 2);\n    assert_eq!(alice.followers[0].name, \"Bob\");\n    assert_eq!(alice.followers[1].name, \"Sam\");\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/connection.rs",
    "content": "use crate::{\n    DbBackend, DbErr, ExecResult, QueryResult, Statement, StatementBuilder, TransactionError,\n};\n\n/// The generic API for a database connection that can perform query or execute statements.\n/// It abstracts database connection and transaction\npub trait ConnectionTrait {\n    /// Get the database backend for the connection. This depends on feature flags enabled.\n    fn get_database_backend(&self) -> DbBackend;\n\n    /// Execute a [Statement]\n    fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr>;\n\n    /// Execute a [QueryStatement]\n    fn execute<S: StatementBuilder>(&self, stmt: &S) -> Result<ExecResult, DbErr> {\n        let db_backend = self.get_database_backend();\n        let stmt = db_backend.build(stmt);\n        self.execute_raw(stmt)\n    }\n\n    /// Execute a unprepared [Statement]\n    fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr>;\n\n    /// Execute a [Statement] and return a single row of `QueryResult`\n    fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr>;\n\n    /// Execute a [QueryStatement] and return a single row of `QueryResult`\n    fn query_one<S: StatementBuilder>(&self, stmt: &S) -> Result<Option<QueryResult>, DbErr> {\n        let db_backend = self.get_database_backend();\n        let stmt = db_backend.build(stmt);\n        self.query_one_raw(stmt)\n    }\n\n    /// Execute a [Statement] and return a vector of `QueryResult`\n    fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr>;\n\n    /// Execute a [QueryStatement] and return a vector of `QueryResult`\n    fn query_all<S: StatementBuilder>(&self, stmt: &S) -> Result<Vec<QueryResult>, DbErr> {\n        let db_backend = self.get_database_backend();\n        let stmt = db_backend.build(stmt);\n        self.query_all_raw(stmt)\n    }\n\n    /// Check if the connection supports `RETURNING` syntax on insert and update\n    fn support_returning(&self) -> bool {\n        let db_backend = self.get_database_backend();\n        db_backend.support_returning()\n    }\n\n    /// Check if the connection is a test connection for the Mock database\n    fn is_mock_connection(&self) -> bool {\n        false\n    }\n}\n\n/// Stream query results\npub trait StreamTrait {\n    /// Create a stream for the [QueryResult]\n    type Stream<'a>: Iterator<Item = Result<QueryResult, DbErr>>\n    where\n        Self: 'a;\n\n    /// Get the database backend for the connection. This depends on feature flags enabled.\n    fn get_database_backend(&self) -> DbBackend;\n\n    /// Execute a [Statement] and return a stream of results\n    fn stream_raw<'a>(&'a self, stmt: Statement) -> Result<Self::Stream<'a>, DbErr>;\n\n    /// Execute a [QueryStatement] and return a stream of results\n    fn stream<'a, S: StatementBuilder>(&'a self, stmt: &S) -> Result<Self::Stream<'a>, DbErr> {\n        let db_backend = self.get_database_backend();\n        let stmt = db_backend.build(stmt);\n        self.stream_raw(stmt)\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\n/// Isolation level\npub enum IsolationLevel {\n    /// Consistent reads within the same transaction read the snapshot established by the first read.\n    RepeatableRead,\n    /// Each consistent read, even within the same transaction, sets and reads its own fresh snapshot.\n    ReadCommitted,\n    /// SELECT statements are performed in a nonlocking fashion, but a possible earlier version of a row might be used.\n    ReadUncommitted,\n    /// All statements of the current transaction can only see rows committed before the first query or data-modification statement was executed in this transaction.\n    Serializable,\n}\n\nimpl std::fmt::Display for IsolationLevel {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            IsolationLevel::RepeatableRead => write!(f, \"REPEATABLE READ\"),\n            IsolationLevel::ReadCommitted => write!(f, \"READ COMMITTED\"),\n            IsolationLevel::ReadUncommitted => write!(f, \"READ UNCOMMITTED\"),\n            IsolationLevel::Serializable => write!(f, \"SERIALIZABLE\"),\n        }\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\n/// Access mode\npub enum AccessMode {\n    /// Data can't be modified in this transaction\n    ReadOnly,\n    /// Data can be modified in this transaction (default)\n    ReadWrite,\n}\n\nimpl std::fmt::Display for AccessMode {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            AccessMode::ReadOnly => write!(f, \"READ ONLY\"),\n            AccessMode::ReadWrite => write!(f, \"READ WRITE\"),\n        }\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\n/// Which kind of transaction to start. Only supported by SQLite.\n/// <https://www.sqlite.org/lang_transaction.html>\npub enum SqliteTransactionMode {\n    /// The default. Transaction starts when the next statement is executed, and\n    /// will be a read or write transaction depending on that statement.\n    Deferred,\n    /// Start a write transaction as soon as the BEGIN statement is received.\n    Immediate,\n    /// Start a write transaction as soon as the BEGIN statement is received.\n    /// When in non-WAL mode, also block all other transactions from reading the\n    /// database.\n    Exclusive,\n}\n\nimpl SqliteTransactionMode {\n    /// The keyword used to start a transaction in this mode (the word coming after \"BEGIN\").\n    pub fn sqlite_keyword(&self) -> &'static str {\n        match self {\n            SqliteTransactionMode::Deferred => \"DEFERRED\",\n            SqliteTransactionMode::Immediate => \"IMMEDIATE\",\n            SqliteTransactionMode::Exclusive => \"EXCLUSIVE\",\n        }\n    }\n}\n\n/// Configuration for starting a transaction\n#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]\npub struct TransactionOptions {\n    /// Isolation level for the new transaction\n    pub isolation_level: Option<IsolationLevel>,\n    /// Access mode for the new transaction\n    pub access_mode: Option<AccessMode>,\n    /// Transaction mode (deferred, immediate, exclusive) for the new transaction. Supported only by SQLite.\n    pub sqlite_transaction_mode: Option<SqliteTransactionMode>,\n}\n\n/// Spawn database transaction\npub trait TransactionTrait {\n    /// The concrete type for the transaction\n    type Transaction: ConnectionTrait + TransactionTrait + TransactionSession;\n\n    /// Execute SQL `BEGIN` transaction.\n    /// Returns a Transaction that can be committed or rolled back\n    fn begin(&self) -> Result<Self::Transaction, DbErr>;\n\n    /// Execute SQL `BEGIN` transaction with isolation level and/or access mode.\n    /// Returns a Transaction that can be committed or rolled back\n    fn begin_with_config(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<Self::Transaction, DbErr>;\n\n    /// Execute SQL `BEGIN` transaction with isolation level and/or access mode.\n    /// Returns a Transaction that can be committed or rolled back\n    fn begin_with_options(&self, options: TransactionOptions) -> Result<Self::Transaction, DbErr>;\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    fn transaction<F, T, E>(&self, callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(&'c Self::Transaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug;\n\n    /// Execute the function inside a transaction with isolation level and/or access mode.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    fn transaction_with_config<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(&'c Self::Transaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug;\n}\n\n/// Represents an open transaction\npub trait TransactionSession {\n    /// Commit a transaction\n    fn commit(self) -> Result<(), DbErr>;\n\n    /// Rolls back a transaction explicitly\n    fn rollback(self) -> Result<(), DbErr>;\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/db_connection.rs",
    "content": "use crate::{\n    AccessMode, ConnectionTrait, DatabaseTransaction, ExecResult, IsolationLevel, QueryResult,\n    Schema, SchemaBuilder, Statement, StatementBuilder, StreamTrait, TransactionError,\n    TransactionOptions, TransactionTrait, error::*,\n};\nuse std::fmt::Debug;\nuse tracing::instrument;\nuse url::Url;\n\n#[cfg(feature = \"sqlx-dep\")]\nuse sqlx::pool::PoolConnection;\n\n#[cfg(feature = \"rusqlite\")]\nuse crate::driver::rusqlite::{RusqliteInnerConnection, RusqliteSharedConnection};\n\n#[cfg(any(feature = \"mock\", feature = \"proxy\"))]\nuse std::sync::Arc;\n\n/// Handle a database connection depending on the backend enabled by the feature\n/// flags. This creates a connection pool internally (for SQLx connections),\n/// and so is cheap to clone.\n#[derive(Debug, Clone)]\n#[non_exhaustive]\npub struct DatabaseConnection {\n    /// `DatabaseConnection` used to be a enum. Now it's moved into inner,\n    /// because we have to attach other contexts.\n    pub inner: DatabaseConnectionType,\n    #[cfg(feature = \"rbac\")]\n    pub(crate) rbac: crate::RbacEngineMount,\n}\n\n/// The underlying database connection type.\n#[derive(Clone)]\npub enum DatabaseConnectionType {\n    /// MySql database connection pool\n    #[cfg(feature = \"sqlx-mysql\")]\n    SqlxMySqlPoolConnection(crate::SqlxMySqlPoolConnection),\n\n    /// PostgreSQL database connection pool\n    #[cfg(feature = \"sqlx-postgres\")]\n    SqlxPostgresPoolConnection(crate::SqlxPostgresPoolConnection),\n\n    /// SQLite database connection pool\n    #[cfg(feature = \"sqlx-sqlite\")]\n    SqlxSqlitePoolConnection(crate::SqlxSqlitePoolConnection),\n\n    /// SQLite database connection sharable across threads\n    #[cfg(feature = \"rusqlite\")]\n    RusqliteSharedConnection(RusqliteSharedConnection),\n\n    /// Mock database connection useful for testing\n    #[cfg(feature = \"mock\")]\n    MockDatabaseConnection(Arc<crate::MockDatabaseConnection>),\n\n    /// Proxy database connection\n    #[cfg(feature = \"proxy\")]\n    ProxyDatabaseConnection(Arc<crate::ProxyDatabaseConnection>),\n\n    /// The connection has never been established\n    Disconnected,\n}\n\n/// The same as a [DatabaseConnection]\npub type DbConn = DatabaseConnection;\n\nimpl Default for DatabaseConnection {\n    fn default() -> Self {\n        DatabaseConnectionType::Disconnected.into()\n    }\n}\n\nimpl From<DatabaseConnectionType> for DatabaseConnection {\n    fn from(inner: DatabaseConnectionType) -> Self {\n        Self {\n            inner,\n            #[cfg(feature = \"rbac\")]\n            rbac: Default::default(),\n        }\n    }\n}\n\n/// The type of database backend for real world databases.\n/// This is enabled by feature flags as specified in the crate documentation\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\n#[non_exhaustive]\npub enum DatabaseBackend {\n    /// A MySQL backend\n    MySql,\n    /// A PostgreSQL backend\n    Postgres,\n    /// A SQLite backend\n    Sqlite,\n}\n\n/// A shorthand for [DatabaseBackend].\npub type DbBackend = DatabaseBackend;\n\n#[derive(Debug)]\npub(crate) enum InnerConnection {\n    #[cfg(feature = \"sqlx-mysql\")]\n    MySql(PoolConnection<sqlx::MySql>),\n    #[cfg(feature = \"sqlx-postgres\")]\n    Postgres(PoolConnection<sqlx::Postgres>),\n    #[cfg(feature = \"sqlx-sqlite\")]\n    Sqlite(PoolConnection<sqlx::Sqlite>),\n    #[cfg(feature = \"rusqlite\")]\n    Rusqlite(RusqliteInnerConnection),\n    #[cfg(feature = \"mock\")]\n    Mock(Arc<crate::MockDatabaseConnection>),\n    #[cfg(feature = \"proxy\")]\n    Proxy(Arc<crate::ProxyDatabaseConnection>),\n}\n\nimpl Debug for DatabaseConnectionType {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(\n            f,\n            \"{}\",\n            match self {\n                #[cfg(feature = \"sqlx-mysql\")]\n                Self::SqlxMySqlPoolConnection(_) => \"SqlxMySqlPoolConnection\",\n                #[cfg(feature = \"sqlx-postgres\")]\n                Self::SqlxPostgresPoolConnection(_) => \"SqlxPostgresPoolConnection\",\n                #[cfg(feature = \"sqlx-sqlite\")]\n                Self::SqlxSqlitePoolConnection(_) => \"SqlxSqlitePoolConnection\",\n                #[cfg(feature = \"rusqlite\")]\n                Self::RusqliteSharedConnection(_) => \"RusqliteSharedConnection\",\n                #[cfg(feature = \"mock\")]\n                Self::MockDatabaseConnection(_) => \"MockDatabaseConnection\",\n                #[cfg(feature = \"proxy\")]\n                Self::ProxyDatabaseConnection(_) => \"ProxyDatabaseConnection\",\n                Self::Disconnected => \"Disconnected\",\n            }\n        )\n    }\n}\n\nimpl ConnectionTrait for DatabaseConnection {\n    fn get_database_backend(&self) -> DbBackend {\n        self.get_database_backend()\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.execute\",\n            self.get_database_backend(),\n            stmt.sql.as_str(),\n            record_stmt = true,\n            {\n                match &self.inner {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => conn.execute(stmt),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => conn.execute(stmt),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => conn.execute(stmt),\n                    #[cfg(feature = \"rusqlite\")]\n                    DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.execute(stmt),\n                    #[cfg(feature = \"mock\")]\n                    DatabaseConnectionType::MockDatabaseConnection(conn) => conn.execute(stmt),\n                    #[cfg(feature = \"proxy\")]\n                    DatabaseConnectionType::ProxyDatabaseConnection(conn) => conn.execute(stmt),\n                    DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.execute_unprepared\",\n            self.get_database_backend(),\n            sql,\n            record_stmt = false,\n            {\n                match &self.inner {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                        conn.execute_unprepared(sql)\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                        conn.execute_unprepared(sql)\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                        conn.execute_unprepared(sql)\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    DatabaseConnectionType::RusqliteSharedConnection(conn) => {\n                        conn.execute_unprepared(sql)\n                    }\n                    #[cfg(feature = \"mock\")]\n                    DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                        let db_backend = conn.get_database_backend();\n                        let stmt = Statement::from_string(db_backend, sql);\n                        conn.execute(stmt)\n                    }\n                    #[cfg(feature = \"proxy\")]\n                    DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                        let db_backend = conn.get_database_backend();\n                        let stmt = Statement::from_string(db_backend, sql);\n                        conn.execute(stmt)\n                    }\n                    DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.query_one\",\n            self.get_database_backend(),\n            stmt.sql.as_str(),\n            record_stmt = true,\n            {\n                match &self.inner {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => conn.query_one(stmt),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                        conn.query_one(stmt)\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => conn.query_one(stmt),\n                    #[cfg(feature = \"rusqlite\")]\n                    DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.query_one(stmt),\n                    #[cfg(feature = \"mock\")]\n                    DatabaseConnectionType::MockDatabaseConnection(conn) => conn.query_one(stmt),\n                    #[cfg(feature = \"proxy\")]\n                    DatabaseConnectionType::ProxyDatabaseConnection(conn) => conn.query_one(stmt),\n                    DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.query_all\",\n            self.get_database_backend(),\n            stmt.sql.as_str(),\n            record_stmt = true,\n            {\n                match &self.inner {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => conn.query_all(stmt),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                        conn.query_all(stmt)\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => conn.query_all(stmt),\n                    #[cfg(feature = \"rusqlite\")]\n                    DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.query_all(stmt),\n                    #[cfg(feature = \"mock\")]\n                    DatabaseConnectionType::MockDatabaseConnection(conn) => conn.query_all(stmt),\n                    #[cfg(feature = \"proxy\")]\n                    DatabaseConnectionType::ProxyDatabaseConnection(conn) => conn.query_all(stmt),\n                    DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[cfg(feature = \"mock\")]\n    fn is_mock_connection(&self) -> bool {\n        matches!(\n            self,\n            DatabaseConnection {\n                inner: DatabaseConnectionType::MockDatabaseConnection(_),\n                ..\n            }\n        )\n    }\n}\n\nimpl StreamTrait for DatabaseConnection {\n    type Stream<'a> = crate::QueryStream;\n\n    fn get_database_backend(&self) -> DbBackend {\n        self.get_database_backend()\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    fn stream_raw<'a>(&'a self, stmt: Statement) -> Result<Self::Stream<'a>, DbErr> {\n        ({\n            match &self.inner {\n                #[cfg(feature = \"sqlx-mysql\")]\n                DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => conn.stream(stmt),\n                #[cfg(feature = \"sqlx-postgres\")]\n                DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => conn.stream(stmt),\n                #[cfg(feature = \"sqlx-sqlite\")]\n                DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => conn.stream(stmt),\n                #[cfg(feature = \"rusqlite\")]\n                DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.stream(stmt),\n                #[cfg(feature = \"mock\")]\n                DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                    Ok(crate::QueryStream::from((Arc::clone(conn), stmt, None)))\n                }\n                #[cfg(feature = \"proxy\")]\n                DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                    Ok(crate::QueryStream::from((Arc::clone(conn), stmt, None)))\n                }\n                DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n            }\n        })\n    }\n}\n\nimpl TransactionTrait for DatabaseConnection {\n    type Transaction = DatabaseTransaction;\n\n    #[instrument(level = \"trace\")]\n    fn begin(&self) -> Result<DatabaseTransaction, DbErr> {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => conn.begin(None, None),\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => conn.begin(None, None),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => conn.begin(None, None, None),\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.begin(None, None, None),\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                DatabaseTransaction::new_mock(Arc::clone(conn), None)\n            }\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                DatabaseTransaction::new_proxy(conn.clone(), None)\n            }\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n        }\n    }\n\n    #[instrument(level = \"trace\")]\n    fn begin_with_config(\n        &self,\n        _isolation_level: Option<IsolationLevel>,\n        _access_mode: Option<AccessMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode)\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode)\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode, None)\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode, None)\n            }\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                DatabaseTransaction::new_mock(Arc::clone(conn), None)\n            }\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                DatabaseTransaction::new_proxy(conn.clone(), None)\n            }\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n        }\n    }\n\n    #[instrument(level = \"trace\")]\n    fn begin_with_options(\n        &self,\n        TransactionOptions {\n            isolation_level: _isolation_level,\n            access_mode: _access_mode,\n            sqlite_transaction_mode: _sqlite_transaction_mode,\n        }: TransactionOptions,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode)\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode)\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode, _sqlite_transaction_mode)\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode, _sqlite_transaction_mode)\n            }\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                DatabaseTransaction::new_mock(Arc::clone(conn), None)\n            }\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                DatabaseTransaction::new_proxy(conn.clone(), None)\n            }\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n        }\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(_callback))]\n    fn transaction<F, T, E>(&self, _callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(&'c DatabaseTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                conn.transaction(_callback, None, None)\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                conn.transaction(_callback, None, None)\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                conn.transaction(_callback, None, None)\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => {\n                conn.transaction(_callback, None, None)\n            }\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                let transaction = DatabaseTransaction::new_mock(Arc::clone(conn), None)\n                    .map_err(TransactionError::Connection)?;\n                transaction.run(_callback)\n            }\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                let transaction = DatabaseTransaction::new_proxy(conn.clone(), None)\n                    .map_err(TransactionError::Connection)?;\n                transaction.run(_callback)\n            }\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\").into()),\n        }\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(_callback))]\n    fn transaction_with_config<F, T, E>(\n        &self,\n        _callback: F,\n        _isolation_level: Option<IsolationLevel>,\n        _access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(&'c DatabaseTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                conn.transaction(_callback, _isolation_level, _access_mode)\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                conn.transaction(_callback, _isolation_level, _access_mode)\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                conn.transaction(_callback, _isolation_level, _access_mode)\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => {\n                conn.transaction(_callback, _isolation_level, _access_mode)\n            }\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                let transaction = DatabaseTransaction::new_mock(Arc::clone(conn), None)\n                    .map_err(TransactionError::Connection)?;\n                transaction.run(_callback)\n            }\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                let transaction = DatabaseTransaction::new_proxy(conn.clone(), None)\n                    .map_err(TransactionError::Connection)?;\n                transaction.run(_callback)\n            }\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\").into()),\n        }\n    }\n}\n\n#[cfg(feature = \"mock\")]\nimpl DatabaseConnection {\n    /// Generate a database connection for testing the Mock database\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DbConn] is not a mock connection.\n    pub fn as_mock_connection(&self) -> &crate::MockDatabaseConnection {\n        match &self.inner {\n            DatabaseConnectionType::MockDatabaseConnection(mock_conn) => mock_conn,\n            _ => panic!(\"Not mock connection\"),\n        }\n    }\n\n    /// Get the transaction log as a collection Vec<[crate::Transaction]>\n    ///\n    /// # Panics\n    ///\n    /// Panics if the mocker mutex is being held by another thread.\n    pub fn into_transaction_log(self) -> Vec<crate::Transaction> {\n        let mut mocker = self\n            .as_mock_connection()\n            .get_mocker_mutex()\n            .lock()\n            .expect(\"Fail to acquire mocker\");\n        mocker.drain_transaction_log()\n    }\n}\n\n#[cfg(feature = \"proxy\")]\nimpl DatabaseConnection {\n    /// Generate a database connection for testing the Proxy database\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DbConn] is not a proxy connection.\n    pub fn as_proxy_connection(&self) -> &crate::ProxyDatabaseConnection {\n        match &self.inner {\n            DatabaseConnectionType::ProxyDatabaseConnection(proxy_conn) => proxy_conn,\n            _ => panic!(\"Not proxy connection\"),\n        }\n    }\n}\n\n#[cfg(feature = \"rbac\")]\nimpl DatabaseConnection {\n    /// Load RBAC data from the same database as this connection and setup RBAC engine.\n    /// If the RBAC engine already exists, it will be replaced.\n    pub fn load_rbac(&self) -> Result<(), DbErr> {\n        self.load_rbac_from(self)\n    }\n\n    /// Load RBAC data from the given database connection and setup RBAC engine.\n    /// This could be from another database.\n    pub fn load_rbac_from(&self, db: &DbConn) -> Result<(), DbErr> {\n        let engine = crate::rbac::RbacEngine::load_from(db)?;\n        self.rbac.replace(engine);\n        Ok(())\n    }\n\n    /// Replace the internal RBAC engine.\n    pub fn replace_rbac(&self, engine: crate::rbac::RbacEngine) {\n        self.rbac.replace(engine);\n    }\n\n    /// Create a restricted connection with access control specific for the user.\n    pub fn restricted_for(\n        &self,\n        user_id: crate::rbac::RbacUserId,\n    ) -> Result<crate::RestrictedConnection, DbErr> {\n        if self.rbac.is_some() {\n            Ok(crate::RestrictedConnection {\n                user_id,\n                conn: self.clone(),\n            })\n        } else {\n            Err(DbErr::RbacError(\"engine not set up\".into()))\n        }\n    }\n}\n\nimpl DatabaseConnection {\n    /// Get the database backend for this connection\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DatabaseConnection] is `Disconnected`.\n    pub fn get_database_backend(&self) -> DbBackend {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(_) => DbBackend::MySql,\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(_) => DbBackend::Postgres,\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(_) => DbBackend::Sqlite,\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(_) => DbBackend::Sqlite,\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => conn.get_database_backend(),\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => conn.get_database_backend(),\n            DatabaseConnectionType::Disconnected => panic!(\"Disconnected\"),\n        }\n    }\n\n    /// Creates a [`SchemaBuilder`] for this backend\n    pub fn get_schema_builder(&self) -> SchemaBuilder {\n        Schema::new(self.get_database_backend()).builder()\n    }\n\n    #[cfg(feature = \"entity-registry\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"entity-registry\")))]\n    /// Builds a schema for all the entites in the given module\n    pub fn get_schema_registry(&self, prefix: &str) -> SchemaBuilder {\n        let schema = Schema::new(self.get_database_backend());\n        crate::EntityRegistry::build_schema(schema, prefix)\n    }\n\n    /// Sets a callback to metric this connection\n    pub fn set_metric_callback<F>(&mut self, _callback: F)\n    where\n        F: Fn(&crate::metric::Info<'_>) + 'static,\n    {\n        match &mut self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                conn.set_metric_callback(_callback)\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                conn.set_metric_callback(_callback)\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                conn.set_metric_callback(_callback)\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => {\n                conn.set_metric_callback(_callback)\n            }\n            _ => {}\n        }\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub fn ping(&self) -> Result<(), DbErr> {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => conn.ping(),\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => conn.ping(),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => conn.ping(),\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.ping(),\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => conn.ping(),\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => conn.ping(),\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n        }\n    }\n\n    /// Explicitly close the database connection.\n    /// See [`Self::close_by_ref`] for usage with references.\n    pub fn close(self) -> Result<(), DbErr> {\n        self.close_by_ref()\n    }\n\n    /// Explicitly close the database connection\n    pub fn close_by_ref(&self) -> Result<(), DbErr> {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => conn.close_by_ref(),\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => conn.close_by_ref(),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => conn.close_by_ref(),\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.close_by_ref(),\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(_) => {\n                // Nothing to cleanup, we just consume the `DatabaseConnection`\n                Ok(())\n            }\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(_) => {\n                // Nothing to cleanup, we just consume the `DatabaseConnection`\n                Ok(())\n            }\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n        }\n    }\n}\n\nimpl DatabaseConnection {\n    /// Get [sqlx::MySqlPool]\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DbConn] is not a MySQL connection.\n    #[cfg(feature = \"sqlx-mysql\")]\n    pub fn get_mysql_connection_pool(&self) -> &sqlx::MySqlPool {\n        match &self.inner {\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => &conn.pool,\n            _ => panic!(\"Not MySQL Connection\"),\n        }\n    }\n\n    /// Get [sqlx::PgPool]\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DbConn] is not a Postgres connection.\n    #[cfg(feature = \"sqlx-postgres\")]\n    pub fn get_postgres_connection_pool(&self) -> &sqlx::PgPool {\n        match &self.inner {\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => &conn.pool,\n            _ => panic!(\"Not Postgres Connection\"),\n        }\n    }\n\n    /// Get [sqlx::SqlitePool]\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DbConn] is not a SQLite connection.\n    #[cfg(feature = \"sqlx-sqlite\")]\n    pub fn get_sqlite_connection_pool(&self) -> &sqlx::SqlitePool {\n        match &self.inner {\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => &conn.pool,\n            _ => panic!(\"Not SQLite Connection\"),\n        }\n    }\n}\n\nimpl DbBackend {\n    /// Check if the URI is the same as the specified database backend.\n    /// Returns true if they match.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `base_url` cannot be parsed as `Url`.\n    pub fn is_prefix_of(self, base_url: &str) -> bool {\n        let base_url_parsed = Url::parse(base_url).expect(\"Fail to parse database URL\");\n        match self {\n            Self::Postgres => {\n                base_url_parsed.scheme() == \"postgres\" || base_url_parsed.scheme() == \"postgresql\"\n            }\n            Self::MySql => base_url_parsed.scheme() == \"mysql\",\n            Self::Sqlite => base_url_parsed.scheme() == \"sqlite\",\n        }\n    }\n\n    /// Build an SQL [Statement]\n    pub fn build<S>(&self, statement: &S) -> Statement\n    where\n        S: StatementBuilder,\n    {\n        statement.build(self)\n    }\n\n    /// Check if the database supports `RETURNING` syntax on insert and update\n    pub fn support_returning(&self) -> bool {\n        match self {\n            Self::Postgres => true,\n            Self::Sqlite if cfg!(feature = \"sqlite-use-returning-for-3_35\") => true,\n            Self::MySql if cfg!(feature = \"mariadb-use-returning\") => true,\n            _ => false,\n        }\n    }\n\n    /// A getter for database dependent boolean value\n    pub fn boolean_value(&self, boolean: bool) -> sea_query::Value {\n        match self {\n            Self::MySql | Self::Postgres | Self::Sqlite => boolean.into(),\n        }\n    }\n\n    /// Get the display string for this enum\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            DatabaseBackend::MySql => \"MySql\",\n            DatabaseBackend::Postgres => \"Postgres\",\n            DatabaseBackend::Sqlite => \"Sqlite\",\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::DatabaseConnection;\n\n    #[cfg(not(feature = \"sync\"))]\n    #[test]\n    fn assert_database_connection_traits() {\n        fn assert_send_sync<T: Send>() {}\n\n        assert_send_sync::<DatabaseConnection>();\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/executor.rs",
    "content": "use crate::{\n    AccessMode, ConnectionTrait, DatabaseConnection, DatabaseTransaction, DbBackend, DbErr,\n    ExecResult, IsolationLevel, QueryResult, Statement, TransactionError, TransactionOptions,\n    TransactionTrait,\n};\nuse crate::{Schema, SchemaBuilder};\nuse std::future::Future;\nuse std::pin::Pin;\n\n/// A wrapper that holds either a reference to a [`DatabaseConnection`] or [`DatabaseTransaction`],\n/// or an owned [`DatabaseTransaction`].\n#[derive(Debug)]\npub enum DatabaseExecutor<'c> {\n    /// A reference to a database connection\n    Connection(&'c DatabaseConnection),\n    /// A reference to a database transaction\n    Transaction(&'c DatabaseTransaction),\n    /// An owned database transaction (used by migration's `SchemaManager::begin()`)\n    OwnedTransaction(DatabaseTransaction),\n}\n\nimpl<'c> From<&'c DatabaseConnection> for DatabaseExecutor<'c> {\n    fn from(conn: &'c DatabaseConnection) -> Self {\n        Self::Connection(conn)\n    }\n}\n\nimpl<'c> From<&'c DatabaseTransaction> for DatabaseExecutor<'c> {\n    fn from(trans: &'c DatabaseTransaction) -> Self {\n        Self::Transaction(trans)\n    }\n}\n\nimpl ConnectionTrait for DatabaseExecutor<'_> {\n    fn get_database_backend(&self) -> DbBackend {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.get_database_backend(),\n            DatabaseExecutor::Transaction(trans) => trans.get_database_backend(),\n            DatabaseExecutor::OwnedTransaction(trans) => trans.get_database_backend(),\n        }\n    }\n\n    fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.execute_raw(stmt),\n            DatabaseExecutor::Transaction(trans) => trans.execute_raw(stmt),\n            DatabaseExecutor::OwnedTransaction(trans) => trans.execute_raw(stmt),\n        }\n    }\n\n    fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.execute_unprepared(sql),\n            DatabaseExecutor::Transaction(trans) => trans.execute_unprepared(sql),\n            DatabaseExecutor::OwnedTransaction(trans) => trans.execute_unprepared(sql),\n        }\n    }\n\n    fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.query_one_raw(stmt),\n            DatabaseExecutor::Transaction(trans) => trans.query_one_raw(stmt),\n            DatabaseExecutor::OwnedTransaction(trans) => trans.query_one_raw(stmt),\n        }\n    }\n\n    fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.query_all_raw(stmt),\n            DatabaseExecutor::Transaction(trans) => trans.query_all_raw(stmt),\n            DatabaseExecutor::OwnedTransaction(trans) => trans.query_all_raw(stmt),\n        }\n    }\n}\n\nimpl TransactionTrait for DatabaseExecutor<'_> {\n    type Transaction = DatabaseTransaction;\n\n    fn begin(&self) -> Result<DatabaseTransaction, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.begin(),\n            DatabaseExecutor::Transaction(trans) => trans.begin(),\n            DatabaseExecutor::OwnedTransaction(trans) => trans.begin(),\n        }\n    }\n\n    fn begin_with_config(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => {\n                conn.begin_with_config(isolation_level, access_mode)\n            }\n            DatabaseExecutor::Transaction(trans) => {\n                trans.begin_with_config(isolation_level, access_mode)\n            }\n            DatabaseExecutor::OwnedTransaction(trans) => {\n                trans.begin_with_config(isolation_level, access_mode)\n            }\n        }\n    }\n\n    fn begin_with_options(\n        &self,\n        options: TransactionOptions,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.begin_with_options(options),\n            DatabaseExecutor::Transaction(trans) => trans.begin_with_options(options),\n            DatabaseExecutor::OwnedTransaction(trans) => trans.begin_with_options(options),\n        }\n    }\n\n    fn transaction<F, T, E>(&self, callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(&'c DatabaseTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.transaction(callback),\n            DatabaseExecutor::Transaction(trans) => trans.transaction(callback),\n            DatabaseExecutor::OwnedTransaction(trans) => trans.transaction(callback),\n        }\n    }\n\n    fn transaction_with_config<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(&'c DatabaseTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        match self {\n            DatabaseExecutor::Connection(conn) => {\n                conn.transaction_with_config(callback, isolation_level, access_mode)\n            }\n            DatabaseExecutor::Transaction(trans) => {\n                trans.transaction_with_config(callback, isolation_level, access_mode)\n            }\n            DatabaseExecutor::OwnedTransaction(trans) => {\n                trans.transaction_with_config(callback, isolation_level, access_mode)\n            }\n        }\n    }\n}\n\n/// A trait for converting into [`DatabaseExecutor`]\npub trait IntoDatabaseExecutor<'c>\nwhere\n    Self: 'c,\n{\n    /// Convert into a [`DatabaseExecutor`]\n    fn into_database_executor(self) -> DatabaseExecutor<'c>;\n}\n\nimpl<'c> IntoDatabaseExecutor<'c> for DatabaseExecutor<'c> {\n    fn into_database_executor(self) -> DatabaseExecutor<'c> {\n        self\n    }\n}\n\nimpl<'c> IntoDatabaseExecutor<'c> for &'c DatabaseConnection {\n    fn into_database_executor(self) -> DatabaseExecutor<'c> {\n        DatabaseExecutor::Connection(self)\n    }\n}\n\nimpl<'c> IntoDatabaseExecutor<'c> for &'c DatabaseTransaction {\n    fn into_database_executor(self) -> DatabaseExecutor<'c> {\n        DatabaseExecutor::Transaction(self)\n    }\n}\n\nimpl IntoDatabaseExecutor<'static> for DatabaseTransaction {\n    fn into_database_executor(self) -> DatabaseExecutor<'static> {\n        DatabaseExecutor::OwnedTransaction(self)\n    }\n}\n\nimpl DatabaseExecutor<'_> {\n    /// Returns `true` if this executor is backed by a transaction (borrowed or owned).\n    pub fn is_transaction(&self) -> bool {\n        matches!(\n            self,\n            DatabaseExecutor::Transaction(_) | DatabaseExecutor::OwnedTransaction(_)\n        )\n    }\n\n    /// Creates a [`SchemaBuilder`] for this backend\n    pub fn get_schema_builder(&self) -> SchemaBuilder {\n        Schema::new(self.get_database_backend()).builder()\n    }\n\n    #[cfg(feature = \"entity-registry\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"entity-registry\")))]\n    /// Builds a schema for all the entities in the given module\n    pub fn get_schema_registry(&self, prefix: &str) -> SchemaBuilder {\n        let schema = Schema::new(self.get_database_backend());\n        crate::EntityRegistry::build_schema(schema, prefix)\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/mock.rs",
    "content": "use crate::{\n    DatabaseConnection, DatabaseConnectionType, DbBackend, EntityTrait, ExecResult,\n    ExecResultHolder, Iden, IdenStatic, Iterable, MockDatabaseConnection, MockDatabaseTrait,\n    ModelTrait, QueryResult, QueryResultRow, SelectA, SelectB, Statement, error::*,\n};\nuse sea_query::{Value, ValueType, Values};\nuse std::{collections::BTreeMap, sync::Arc};\nuse tracing::instrument;\n\n/// Defines a Mock database suitable for testing\n#[derive(Debug)]\npub struct MockDatabase {\n    db_backend: DbBackend,\n    transaction: Option<OpenTransaction>,\n    transaction_log: Vec<Transaction>,\n    exec_results: Vec<Result<MockExecResult, DbErr>>,\n    query_results: Vec<Result<Vec<MockRow>, DbErr>>,\n}\n\n/// Defines the results obtained from a [MockDatabase]\n#[derive(Clone, Debug, Default)]\npub struct MockExecResult {\n    /// The last inserted id on auto-increment\n    pub last_insert_id: u64,\n    /// The number of rows affected by the database operation\n    pub rows_affected: u64,\n}\n\n/// Defines the structure of a test Row for the [MockDatabase]\n/// which is just a [BTreeMap]<[String], [Value]>\n#[derive(Clone, Debug)]\npub struct MockRow {\n    /// The values of the single row\n    pub(crate) values: BTreeMap<String, Value>,\n}\n\n/// A trait to get a [MockRow] from a type useful for testing in the [MockDatabase]\npub trait IntoMockRow {\n    /// The method to perform this operation\n    fn into_mock_row(self) -> MockRow;\n}\n\n/// Defines a transaction that is has not been committed\n#[derive(Debug)]\npub struct OpenTransaction {\n    stmts: Vec<Statement>,\n    transaction_depth: usize,\n}\n\n/// Defines a database transaction as it holds a Vec<[Statement]>\n#[derive(Debug, Clone, PartialEq)]\npub struct Transaction {\n    stmts: Vec<Statement>,\n}\n\nimpl MockDatabase {\n    /// Instantiate a mock database with a [DbBackend] to simulate real\n    /// world SQL databases\n    pub fn new(db_backend: DbBackend) -> Self {\n        Self {\n            db_backend,\n            transaction: None,\n            transaction_log: Vec::new(),\n            exec_results: Vec::new(),\n            query_results: Vec::new(),\n        }\n    }\n\n    /// Create a database connection\n    pub fn into_connection(self) -> DatabaseConnection {\n        DatabaseConnectionType::MockDatabaseConnection(Arc::new(MockDatabaseConnection::new(self)))\n            .into()\n    }\n\n    /// Add some [MockExecResult]s to `exec_results`\n    pub fn append_exec_results<I>(mut self, vec: I) -> Self\n    where\n        I: IntoIterator<Item = MockExecResult>,\n    {\n        self.exec_results.extend(vec.into_iter().map(Result::Ok));\n        self\n    }\n\n    /// Add some Values to `query_results`\n    pub fn append_query_results<T, I, II>(mut self, vec: II) -> Self\n    where\n        T: IntoMockRow,\n        I: IntoIterator<Item = T>,\n        II: IntoIterator<Item = I>,\n    {\n        for row in vec.into_iter() {\n            let row = row.into_iter().map(|vec| Ok(vec.into_mock_row())).collect();\n            self.query_results.push(row);\n        }\n        self\n    }\n\n    /// Add some [DbErr]s to `exec_results`\n    pub fn append_exec_errors<I>(mut self, vec: I) -> Self\n    where\n        I: IntoIterator<Item = DbErr>,\n    {\n        self.exec_results.extend(vec.into_iter().map(Result::Err));\n        self\n    }\n\n    /// Add some [DbErr]s to `query_results`\n    pub fn append_query_errors<I>(mut self, vec: I) -> Self\n    where\n        I: IntoIterator<Item = DbErr>,\n    {\n        self.query_results.extend(vec.into_iter().map(Result::Err));\n        self\n    }\n}\n\nimpl MockDatabaseTrait for MockDatabase {\n    #[instrument(level = \"trace\")]\n    fn execute(&mut self, counter: usize, statement: Statement) -> Result<ExecResult, DbErr> {\n        if let Some(transaction) = &mut self.transaction {\n            transaction.push(statement);\n        } else {\n            self.transaction_log.push(Transaction::one(statement));\n        }\n        if counter < self.exec_results.len() {\n            match std::mem::replace(\n                &mut self.exec_results[counter],\n                Err(exec_err(\"this value has been consumed already\")),\n            ) {\n                Ok(result) => Ok(ExecResult {\n                    result: ExecResultHolder::Mock(result),\n                }),\n                Err(err) => Err(err),\n            }\n        } else {\n            Err(exec_err(\"`exec_results` buffer is empty\"))\n        }\n    }\n\n    #[instrument(level = \"trace\")]\n    fn query(&mut self, counter: usize, statement: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        if let Some(transaction) = &mut self.transaction {\n            transaction.push(statement);\n        } else {\n            self.transaction_log.push(Transaction::one(statement));\n        }\n        if counter < self.query_results.len() {\n            match std::mem::replace(\n                &mut self.query_results[counter],\n                Err(query_err(\"this value has been consumed already\")),\n            ) {\n                Ok(result) => Ok(result\n                    .into_iter()\n                    .map(|row| QueryResult {\n                        row: QueryResultRow::Mock(row),\n                    })\n                    .collect()),\n                Err(err) => Err(err),\n            }\n        } else {\n            Err(query_err(\"`query_results` buffer is empty.\"))\n        }\n    }\n\n    #[instrument(level = \"trace\")]\n    fn begin(&mut self) {\n        match self.transaction.as_mut() {\n            Some(transaction) => transaction.begin_nested(self.db_backend),\n            None => self.transaction = Some(OpenTransaction::init()),\n        }\n    }\n\n    #[instrument(level = \"trace\")]\n    fn commit(&mut self) {\n        match self.transaction.as_mut() {\n            Some(transaction) => {\n                if transaction.commit(self.db_backend) {\n                    if let Some(transaction) = self.transaction.take() {\n                        self.transaction_log.push(transaction.into_transaction());\n                    }\n                }\n            }\n            None => panic!(\"There is no open transaction to commit\"),\n        }\n    }\n\n    #[instrument(level = \"trace\")]\n    fn rollback(&mut self) {\n        match self.transaction.as_mut() {\n            Some(transaction) => {\n                if transaction.rollback(self.db_backend) {\n                    if let Some(transaction) = self.transaction.take() {\n                        self.transaction_log.push(transaction.into_transaction());\n                    }\n                }\n            }\n            None => panic!(\"There is no open transaction to rollback\"),\n        }\n    }\n\n    fn drain_transaction_log(&mut self) -> Vec<Transaction> {\n        std::mem::take(&mut self.transaction_log)\n    }\n\n    fn get_database_backend(&self) -> DbBackend {\n        self.db_backend\n    }\n\n    fn ping(&self) -> Result<(), DbErr> {\n        Ok(())\n    }\n}\n\nimpl MockRow {\n    /// Get a value from the [MockRow]\n    pub fn try_get<T, I: crate::ColIdx>(&self, index: I) -> Result<T, DbErr>\n    where\n        T: ValueType,\n    {\n        if let Some(index) = index.as_str() {\n            T::try_from(\n                self.values\n                    .get(index)\n                    .ok_or_else(|| query_err(format!(\"No column for ColIdx {index:?}\")))?\n                    .clone(),\n            )\n            .map_err(type_err)\n        } else if let Some(index) = index.as_usize() {\n            let (_, value) = self\n                .values\n                .iter()\n                .nth(*index)\n                .ok_or_else(|| query_err(format!(\"Column at index {index} not found\")))?;\n            T::try_from(value.clone()).map_err(type_err)\n        } else {\n            unreachable!(\"Missing ColIdx implementation for MockRow\");\n        }\n    }\n\n    /// An iterator over the keys and values of a mock row\n    pub fn into_column_value_tuples(self) -> impl Iterator<Item = (String, Value)> {\n        self.values.into_iter()\n    }\n}\n\nimpl IntoMockRow for MockRow {\n    fn into_mock_row(self) -> MockRow {\n        self\n    }\n}\n\nimpl<M> IntoMockRow for M\nwhere\n    M: ModelTrait,\n{\n    fn into_mock_row(self) -> MockRow {\n        let mut values = BTreeMap::new();\n        for col in <<M::Entity as EntityTrait>::Column>::iter() {\n            values.insert(col.to_string(), self.get(col));\n        }\n        MockRow { values }\n    }\n}\n\nimpl<M, N> IntoMockRow for (M, N)\nwhere\n    M: ModelTrait,\n    N: ModelTrait,\n{\n    fn into_mock_row(self) -> MockRow {\n        let mut mapped_join = BTreeMap::new();\n\n        for column in <<M as ModelTrait>::Entity as EntityTrait>::Column::iter() {\n            mapped_join.insert(\n                format!(\"{}{}\", SelectA.as_str(), column.as_str()),\n                self.0.get(column),\n            );\n        }\n        for column in <<N as ModelTrait>::Entity as EntityTrait>::Column::iter() {\n            mapped_join.insert(\n                format!(\"{}{}\", SelectB.as_str(), column.as_str()),\n                self.1.get(column),\n            );\n        }\n\n        mapped_join.into_mock_row()\n    }\n}\n\nimpl<M, N> IntoMockRow for (M, Option<N>)\nwhere\n    M: ModelTrait,\n    N: ModelTrait,\n{\n    fn into_mock_row(self) -> MockRow {\n        let mut mapped_join = BTreeMap::new();\n\n        for column in <<M as ModelTrait>::Entity as EntityTrait>::Column::iter() {\n            mapped_join.insert(\n                format!(\"{}{}\", SelectA.as_str(), column.as_str()),\n                self.0.get(column),\n            );\n        }\n        if let Some(b_entity) = self.1 {\n            for column in <<N as ModelTrait>::Entity as EntityTrait>::Column::iter() {\n                mapped_join.insert(\n                    format!(\"{}{}\", SelectB.as_str(), column.as_str()),\n                    b_entity.get(column),\n                );\n            }\n        }\n\n        mapped_join.into_mock_row()\n    }\n}\n\nimpl<T> IntoMockRow for BTreeMap<T, Value>\nwhere\n    T: Into<String>,\n{\n    fn into_mock_row(self) -> MockRow {\n        MockRow {\n            values: self.into_iter().map(|(k, v)| (k.into(), v)).collect(),\n        }\n    }\n}\n\nimpl Transaction {\n    /// Get the [Value]s from s raw SQL statement depending on the [DatabaseBackend](crate::DatabaseBackend)\n    pub fn from_sql_and_values<I, T>(db_backend: DbBackend, sql: T, values: I) -> Self\n    where\n        I: IntoIterator<Item = Value>,\n        T: Into<String>,\n    {\n        Self::one(Statement::from_string_values_tuple(\n            db_backend,\n            (sql, Values(values.into_iter().collect())),\n        ))\n    }\n\n    /// Create a Transaction with one statement\n    pub fn one(stmt: Statement) -> Self {\n        Self { stmts: vec![stmt] }\n    }\n\n    /// Create a Transaction with many statements\n    pub fn many<I>(stmts: I) -> Self\n    where\n        I: IntoIterator<Item = Statement>,\n    {\n        Self {\n            stmts: stmts.into_iter().collect(),\n        }\n    }\n\n    /// Wrap each Statement as a single-statement Transaction\n    pub fn wrap<I>(stmts: I) -> Vec<Self>\n    where\n        I: IntoIterator<Item = Statement>,\n    {\n        stmts.into_iter().map(Self::one).collect()\n    }\n\n    /// Get the list of statements\n    pub fn statements(&self) -> &[Statement] {\n        &self.stmts\n    }\n}\n\nimpl OpenTransaction {\n    fn init() -> Self {\n        Self {\n            stmts: vec![Statement::from_string(DbBackend::Postgres, \"BEGIN\")],\n            transaction_depth: 0,\n        }\n    }\n\n    fn begin_nested(&mut self, db_backend: DbBackend) {\n        self.transaction_depth += 1;\n        self.push(Statement::from_string(\n            db_backend,\n            format!(\"SAVEPOINT savepoint_{}\", self.transaction_depth),\n        ));\n    }\n\n    fn commit(&mut self, db_backend: DbBackend) -> bool {\n        if self.transaction_depth == 0 {\n            self.push(Statement::from_string(db_backend, \"COMMIT\"));\n            true\n        } else {\n            self.push(Statement::from_string(\n                db_backend,\n                format!(\"RELEASE SAVEPOINT savepoint_{}\", self.transaction_depth),\n            ));\n            self.transaction_depth -= 1;\n            false\n        }\n    }\n\n    fn rollback(&mut self, db_backend: DbBackend) -> bool {\n        if self.transaction_depth == 0 {\n            self.push(Statement::from_string(db_backend, \"ROLLBACK\"));\n            true\n        } else {\n            self.push(Statement::from_string(\n                db_backend,\n                format!(\"ROLLBACK TO SAVEPOINT savepoint_{}\", self.transaction_depth),\n            ));\n            self.transaction_depth -= 1;\n            false\n        }\n    }\n\n    fn push(&mut self, stmt: Statement) {\n        self.stmts.push(stmt);\n    }\n\n    fn into_transaction(self) -> Transaction {\n        match self.transaction_depth {\n            0 => Transaction { stmts: self.stmts },\n            _ => panic!(\"There is uncommitted nested transaction\"),\n        }\n    }\n}\n\n#[cfg(test)]\n#[cfg(feature = \"mock\")]\nmod tests {\n    #[cfg(feature = \"sync\")]\n    use crate::util::StreamShim;\n    use crate::{\n        DbBackend, DbErr, IntoMockRow, MockDatabase, Statement, Transaction, TransactionError,\n        TransactionTrait, entity::*, error::*, tests_cfg::*,\n    };\n    use pretty_assertions::assert_eq;\n\n    #[derive(Debug, PartialEq, Eq)]\n    pub struct MyErr(String);\n\n    impl std::error::Error for MyErr {}\n\n    impl std::fmt::Display for MyErr {\n        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n            write!(f, \"{}\", self.0.as_str())\n        }\n    }\n\n    #[test]\n    fn test_transaction_1() {\n        let db = MockDatabase::new(DbBackend::Postgres).into_connection();\n\n        db.transaction::<_, (), DbErr>(|txn| {\n            ({\n                let _1 = cake::Entity::find().one(txn);\n                let _2 = fruit::Entity::find().all(txn);\n\n                Ok(())\n            })\n        })\n        .unwrap();\n\n        let _ = cake::Entity::find().all(&db);\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [\n                Transaction::many([\n                    Statement::from_string(DbBackend::Postgres, \"BEGIN\"),\n                    Statement::from_sql_and_values(\n                        DbBackend::Postgres,\n                        r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" LIMIT $1\"#,\n                        [1u64.into()]\n                    ),\n                    Statement::from_sql_and_values(\n                        DbBackend::Postgres,\n                        r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\"\"#,\n                        []\n                    ),\n                    Statement::from_string(DbBackend::Postgres, \"COMMIT\"),\n                ]),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n                    []\n                ),\n            ]\n        );\n    }\n\n    #[test]\n    fn test_transaction_2() {\n        let db = MockDatabase::new(DbBackend::Postgres).into_connection();\n\n        let result = db.transaction::<_, (), MyErr>(|txn| {\n            ({\n                let _ = cake::Entity::find().one(txn);\n                Err(MyErr(\"test\".to_owned()))\n            })\n        });\n\n        match result {\n            Err(TransactionError::Transaction(err)) => {\n                assert_eq!(err, MyErr(\"test\".to_owned()))\n            }\n            _ => unreachable!(),\n        }\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([\n                Statement::from_string(DbBackend::Postgres, \"BEGIN\"),\n                Statement::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" LIMIT $1\"#,\n                    [1u64.into()]\n                ),\n                Statement::from_string(DbBackend::Postgres, \"ROLLBACK\"),\n            ])]\n        );\n    }\n\n    #[test]\n    fn test_nested_transaction_1() {\n        let db = MockDatabase::new(DbBackend::Postgres).into_connection();\n\n        db.transaction::<_, (), DbErr>(|txn| {\n            ({\n                let _ = cake::Entity::find().one(txn);\n\n                txn.transaction::<_, (), DbErr>(|txn| {\n                    ({\n                        let _ = fruit::Entity::find().all(txn);\n\n                        Ok(())\n                    })\n                })\n                .unwrap();\n\n                Ok(())\n            })\n        })\n        .unwrap();\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([\n                Statement::from_string(DbBackend::Postgres, \"BEGIN\"),\n                Statement::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" LIMIT $1\"#,\n                    [1u64.into()]\n                ),\n                Statement::from_string(DbBackend::Postgres, \"SAVEPOINT savepoint_1\"),\n                Statement::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\"\"#,\n                    []\n                ),\n                Statement::from_string(DbBackend::Postgres, \"RELEASE SAVEPOINT savepoint_1\"),\n                Statement::from_string(DbBackend::Postgres, \"COMMIT\"),\n            ]),]\n        );\n    }\n\n    #[test]\n    fn test_nested_transaction_2() {\n        let db = MockDatabase::new(DbBackend::Postgres).into_connection();\n\n        db.transaction::<_, (), DbErr>(|txn| {\n            ({\n                let _ = cake::Entity::find().one(txn);\n\n                txn.transaction::<_, (), DbErr>(|txn| {\n                    ({\n                        let _ = fruit::Entity::find().all(txn);\n\n                        txn.transaction::<_, (), DbErr>(|txn| {\n                            ({\n                                let _ = cake::Entity::find().all(txn);\n\n                                Ok(())\n                            })\n                        })\n                        .unwrap();\n\n                        Ok(())\n                    })\n                })\n                .unwrap();\n\n                Ok(())\n            })\n        })\n        .unwrap();\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([\n                Statement::from_string(DbBackend::Postgres, \"BEGIN\"),\n                Statement::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" LIMIT $1\"#,\n                    [1u64.into()]\n                ),\n                Statement::from_string(DbBackend::Postgres, \"SAVEPOINT savepoint_1\"),\n                Statement::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\"\"#,\n                    []\n                ),\n                Statement::from_string(DbBackend::Postgres, \"SAVEPOINT savepoint_2\"),\n                Statement::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n                    []\n                ),\n                Statement::from_string(DbBackend::Postgres, \"RELEASE SAVEPOINT savepoint_2\"),\n                Statement::from_string(DbBackend::Postgres, \"RELEASE SAVEPOINT savepoint_1\"),\n                Statement::from_string(DbBackend::Postgres, \"COMMIT\"),\n            ]),]\n        );\n    }\n\n    #[test]\n    fn test_stream_1() -> Result<(), DbErr> {\n        let apple = fruit::Model {\n            id: 1,\n            name: \"Apple\".to_owned(),\n            cake_id: Some(1),\n        };\n\n        let orange = fruit::Model {\n            id: 2,\n            name: \"orange\".to_owned(),\n            cake_id: None,\n        };\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[apple.clone(), orange.clone()]])\n            .into_connection();\n\n        let mut stream = fruit::Entity::find().stream(&db)?;\n\n        assert_eq!(stream.try_next()?, Some(apple));\n\n        assert_eq!(stream.try_next()?, Some(orange));\n\n        assert_eq!(stream.try_next()?, None);\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_stream_2() -> Result<(), DbErr> {\n        use fruit::Entity as Fruit;\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([Vec::<fruit::Model>::new()])\n            .into_connection();\n\n        let mut stream = Fruit::find().stream(&db)?;\n\n        while let Some(item) = stream.try_next()? {\n            let _item: fruit::ActiveModel = item.into();\n        }\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_stream_in_transaction() -> Result<(), DbErr> {\n        let apple = fruit::Model {\n            id: 1,\n            name: \"Apple\".to_owned(),\n            cake_id: Some(1),\n        };\n\n        let orange = fruit::Model {\n            id: 2,\n            name: \"orange\".to_owned(),\n            cake_id: None,\n        };\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[apple.clone(), orange.clone()]])\n            .into_connection();\n\n        let txn = db.begin()?;\n\n        if let Ok(mut stream) = fruit::Entity::find().stream(&txn) {\n            assert_eq!(stream.try_next()?, Some(apple));\n\n            assert_eq!(stream.try_next()?, Some(orange));\n\n            assert_eq!(stream.try_next()?, None);\n\n            // stream will be dropped end of scope\n        }\n\n        txn.commit()?;\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_mocked_join() {\n        let row = (\n            cake::Model {\n                id: 1,\n                name: \"Apple Cake\".to_owned(),\n            },\n            fruit::Model {\n                id: 2,\n                name: \"Apple\".to_owned(),\n                cake_id: Some(1),\n            },\n        );\n        let mocked_row = row.into_mock_row();\n\n        let a_id = mocked_row.try_get::<i32, _>(\"A_id\");\n        assert!(a_id.is_ok());\n        assert_eq!(1, a_id.unwrap());\n        let b_id = mocked_row.try_get::<i32, _>(\"B_id\");\n        assert!(b_id.is_ok());\n        assert_eq!(2, b_id.unwrap());\n    }\n\n    #[test]\n    fn test_find_also_related_1() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                cake::Model {\n                    id: 1,\n                    name: \"Apple Cake\".to_owned(),\n                },\n                fruit::Model {\n                    id: 2,\n                    name: \"Apple\".to_owned(),\n                    cake_id: Some(1),\n                },\n            )]])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_related(fruit::Entity)\n                .all(&db)?,\n            [(\n                cake::Model {\n                    id: 1,\n                    name: \"Apple Cake\".to_owned(),\n                },\n                Some(fruit::Model {\n                    id: 2,\n                    name: \"Apple\".to_owned(),\n                    cake_id: Some(1),\n                })\n            )]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::from_sql_and_values(\n                DbBackend::Postgres,\n                r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\", \"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\" FROM \"cake\" LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                []\n            ),]\n        );\n\n        Ok(())\n    }\n\n    #[cfg(feature = \"postgres-array\")]\n    #[test]\n    fn test_postgres_array_1() -> Result<(), DbErr> {\n        mod collection {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"collection\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                pub integers: Vec<i32>,\n                pub integers_opt: Option<Vec<i32>>,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                collection::Model {\n                    id: 1,\n                    integers: vec![1, 2, 3],\n                    integers_opt: Some(vec![1, 2, 3]),\n                },\n                collection::Model {\n                    id: 2,\n                    integers: vec![],\n                    integers_opt: Some(vec![]),\n                },\n                collection::Model {\n                    id: 3,\n                    integers: vec![3, 1, 4],\n                    integers_opt: None,\n                },\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            collection::Entity::find().all(&db)?,\n            [\n                collection::Model {\n                    id: 1,\n                    integers: vec![1, 2, 3],\n                    integers_opt: Some(vec![1, 2, 3]),\n                },\n                collection::Model {\n                    id: 2,\n                    integers: vec![],\n                    integers_opt: Some(vec![]),\n                },\n                collection::Model {\n                    id: 3,\n                    integers: vec![3, 1, 4],\n                    integers_opt: None,\n                },\n            ]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::from_sql_and_values(\n                DbBackend::Postgres,\n                r#\"SELECT \"collection\".\"id\", \"collection\".\"integers\", \"collection\".\"integers_opt\" FROM \"collection\"\"#,\n                []\n            ),]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_query_err() {\n        let db = MockDatabase::new(DbBackend::MySql)\n            .append_query_errors([query_err(\"this is a mock query error\")])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find().all(&db),\n            Err(query_err(\"this is a mock query error\"))\n        );\n    }\n\n    #[test]\n    fn test_exec_err() {\n        let db = MockDatabase::new(DbBackend::MySql)\n            .append_exec_errors([exec_err(\"this is a mock exec error\")])\n            .into_connection();\n\n        let model = cake::ActiveModel::new();\n\n        assert_eq!(model.save(&db), Err(exec_err(\"this is a mock exec error\")));\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/mod.rs",
    "content": "use std::{sync::Arc, time::Duration};\n\n#[cfg(feature = \"sqlx-mysql\")]\nuse sqlx::mysql::MySqlConnectOptions;\n#[cfg(feature = \"sqlx-postgres\")]\nuse sqlx::postgres::PgConnectOptions;\n#[cfg(feature = \"sqlx-sqlite\")]\nuse sqlx::sqlite::SqliteConnectOptions;\n\nmod connection;\nmod db_connection;\nmod executor;\n#[cfg(feature = \"mock\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"mock\")))]\nmod mock;\n#[cfg(feature = \"proxy\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"proxy\")))]\nmod proxy;\n#[cfg(feature = \"rbac\")]\nmod restricted_connection;\n#[cfg(all(feature = \"schema-sync\", feature = \"rusqlite\"))]\nmod sea_schema_rusqlite;\n#[cfg(all(feature = \"schema-sync\", feature = \"sqlx-dep\"))]\nmod sea_schema_shim;\nmod statement;\nmod stream;\nmod tracing_spans;\nmod transaction;\n\npub use connection::*;\npub use db_connection::*;\npub use executor::*;\n#[cfg(feature = \"mock\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"mock\")))]\npub use mock::*;\n#[cfg(feature = \"proxy\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"proxy\")))]\npub use proxy::*;\n#[cfg(feature = \"rbac\")]\npub use restricted_connection::*;\npub use statement::*;\nuse std::borrow::Cow;\npub use stream::*;\nuse tracing::instrument;\npub use transaction::*;\n\nuse crate::error::*;\n\n/// Defines a database\n#[derive(Debug, Default)]\npub struct Database;\n\n#[cfg(feature = \"sync\")]\ntype BoxFuture<'a, T> = T;\n\ntype AfterConnectCallback =\n    Option<Arc<dyn Fn(DatabaseConnection) -> BoxFuture<'static, Result<(), DbErr>> + 'static>>;\n\n/// Defines the configuration options of a database\n#[derive(derive_more::Debug, Clone)]\npub struct ConnectOptions {\n    /// The URI of the database\n    pub(crate) url: String,\n    /// Maximum number of connections for a pool\n    pub(crate) max_connections: Option<u32>,\n    /// Minimum number of connections for a pool\n    pub(crate) min_connections: Option<u32>,\n    /// The connection timeout for a packet connection\n    pub(crate) connect_timeout: Option<Duration>,\n    /// Maximum idle time for a particular connection to prevent\n    /// network resource exhaustion\n    pub(crate) idle_timeout: Option<Option<Duration>>,\n    /// Set the maximum amount of time to spend waiting for acquiring a connection\n    pub(crate) acquire_timeout: Option<Duration>,\n    /// Set the maximum lifetime of individual connections\n    pub(crate) max_lifetime: Option<Option<Duration>>,\n    /// Enable SQLx statement logging\n    pub(crate) sqlx_logging: bool,\n    /// SQLx statement logging level (ignored if `sqlx_logging` is false)\n    pub(crate) sqlx_logging_level: log::LevelFilter,\n    /// SQLx slow statements logging level (ignored if `sqlx_logging` is false)\n    pub(crate) sqlx_slow_statements_logging_level: log::LevelFilter,\n    /// SQLx slow statements duration threshold (ignored if `sqlx_logging` is false)\n    pub(crate) sqlx_slow_statements_logging_threshold: Duration,\n    /// set sqlcipher key\n    pub(crate) sqlcipher_key: Option<Cow<'static, str>>,\n    /// Schema search path (PostgreSQL only)\n    pub(crate) schema_search_path: Option<String>,\n    /// Application name (PostgreSQL only)\n    pub(crate) application_name: Option<String>,\n    /// Statement timeout (PostgreSQL only)\n    pub(crate) statement_timeout: Option<Duration>,\n    pub(crate) test_before_acquire: bool,\n    /// Only establish connections to the DB as needed. If set to `true`, the db connection will\n    /// be created using SQLx's [connect_lazy](https://docs.rs/sqlx/latest/sqlx/struct.Pool.html#method.connect_lazy)\n    /// method.\n    pub(crate) connect_lazy: bool,\n\n    #[debug(skip)]\n    pub(crate) after_connect: AfterConnectCallback,\n\n    #[cfg(feature = \"sqlx-mysql\")]\n    #[debug(skip)]\n    pub(crate) mysql_opts_fn: Option<Arc<dyn Fn(MySqlConnectOptions) -> MySqlConnectOptions>>,\n    #[cfg(feature = \"sqlx-postgres\")]\n    #[debug(skip)]\n    pub(crate) pg_opts_fn: Option<Arc<dyn Fn(PgConnectOptions) -> PgConnectOptions>>,\n    #[cfg(feature = \"sqlx-sqlite\")]\n    #[debug(skip)]\n    pub(crate) sqlite_opts_fn: Option<Arc<dyn Fn(SqliteConnectOptions) -> SqliteConnectOptions>>,\n}\n\nimpl Database {\n    /// Method to create a [DatabaseConnection] on a database. This method will return an error\n    /// if the database is not available.\n    #[instrument(level = \"trace\", skip(opt))]\n    pub fn connect<C>(opt: C) -> Result<DatabaseConnection, DbErr>\n    where\n        C: Into<ConnectOptions>,\n    {\n        let opt: ConnectOptions = opt.into();\n\n        if url::Url::parse(&opt.url).is_err() {\n            return Err(conn_err(format!(\n                \"The connection string '{}' cannot be parsed.\",\n                opt.url\n            )));\n        }\n\n        #[cfg(feature = \"sqlx-mysql\")]\n        if DbBackend::MySql.is_prefix_of(&opt.url) {\n            return crate::SqlxMySqlConnector::connect(opt);\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        if DbBackend::Postgres.is_prefix_of(&opt.url) {\n            return crate::SqlxPostgresConnector::connect(opt);\n        }\n        #[cfg(feature = \"sqlx-sqlite\")]\n        if DbBackend::Sqlite.is_prefix_of(&opt.url) {\n            return crate::SqlxSqliteConnector::connect(opt);\n        }\n        #[cfg(feature = \"rusqlite\")]\n        if DbBackend::Sqlite.is_prefix_of(&opt.url) {\n            return crate::driver::rusqlite::RusqliteConnector::connect(opt);\n        }\n        #[cfg(feature = \"mock\")]\n        if crate::MockDatabaseConnector::accepts(&opt.url) {\n            return crate::MockDatabaseConnector::connect(&opt.url);\n        }\n\n        Err(conn_err(format!(\n            \"The connection string '{}' has no supporting driver.\",\n            opt.url\n        )))\n    }\n\n    /// Method to create a [DatabaseConnection] on a proxy database\n    #[cfg(feature = \"proxy\")]\n    #[instrument(level = \"trace\", skip(proxy_func_arc))]\n    pub fn connect_proxy(\n        db_type: DbBackend,\n        proxy_func_arc: std::sync::Arc<Box<dyn ProxyDatabaseTrait>>,\n    ) -> Result<DatabaseConnection, DbErr> {\n        match db_type {\n            DbBackend::MySql => {\n                return crate::ProxyDatabaseConnector::connect(\n                    DbBackend::MySql,\n                    proxy_func_arc.to_owned(),\n                );\n            }\n            DbBackend::Postgres => {\n                return crate::ProxyDatabaseConnector::connect(\n                    DbBackend::Postgres,\n                    proxy_func_arc.to_owned(),\n                );\n            }\n            DbBackend::Sqlite => {\n                return crate::ProxyDatabaseConnector::connect(\n                    DbBackend::Sqlite,\n                    proxy_func_arc.to_owned(),\n                );\n            }\n        }\n    }\n}\n\nimpl<T> From<T> for ConnectOptions\nwhere\n    T: Into<String>,\n{\n    fn from(s: T) -> ConnectOptions {\n        ConnectOptions::new(s.into())\n    }\n}\n\nimpl ConnectOptions {\n    /// Create new [ConnectOptions] for a [Database] by passing in a URI string\n    pub fn new<T>(url: T) -> Self\n    where\n        T: Into<String>,\n    {\n        Self {\n            url: url.into(),\n            max_connections: None,\n            min_connections: None,\n            connect_timeout: None,\n            idle_timeout: None,\n            acquire_timeout: None,\n            max_lifetime: None,\n            sqlx_logging: true,\n            sqlx_logging_level: log::LevelFilter::Info,\n            sqlx_slow_statements_logging_level: log::LevelFilter::Off,\n            sqlx_slow_statements_logging_threshold: Duration::from_secs(1),\n            sqlcipher_key: None,\n            schema_search_path: None,\n            application_name: None,\n            statement_timeout: None,\n            test_before_acquire: true,\n            connect_lazy: false,\n            after_connect: None,\n            #[cfg(feature = \"sqlx-mysql\")]\n            mysql_opts_fn: None,\n            #[cfg(feature = \"sqlx-postgres\")]\n            pg_opts_fn: None,\n            #[cfg(feature = \"sqlx-sqlite\")]\n            sqlite_opts_fn: None,\n        }\n    }\n\n    /// Get the database URL of the pool\n    pub fn get_url(&self) -> &str {\n        &self.url\n    }\n\n    /// Set the maximum number of connections of the pool\n    pub fn max_connections(&mut self, value: u32) -> &mut Self {\n        self.max_connections = Some(value);\n        self\n    }\n\n    /// Get the maximum number of connections of the pool, if set\n    pub fn get_max_connections(&self) -> Option<u32> {\n        self.max_connections\n    }\n\n    /// Set the minimum number of connections of the pool\n    pub fn min_connections(&mut self, value: u32) -> &mut Self {\n        self.min_connections = Some(value);\n        self\n    }\n\n    /// Get the minimum number of connections of the pool, if set\n    pub fn get_min_connections(&self) -> Option<u32> {\n        self.min_connections\n    }\n\n    /// Set the timeout duration when acquiring a connection\n    pub fn connect_timeout(&mut self, value: Duration) -> &mut Self {\n        self.connect_timeout = Some(value);\n        self\n    }\n\n    /// Get the timeout duration when acquiring a connection, if set\n    pub fn get_connect_timeout(&self) -> Option<Duration> {\n        self.connect_timeout\n    }\n\n    /// Set the idle duration before closing a connection.\n    pub fn idle_timeout<T>(&mut self, value: T) -> &mut Self\n    where\n        T: Into<Option<Duration>>,\n    {\n        self.idle_timeout = Some(value.into());\n        self\n    }\n\n    /// Get the idle duration before closing a connection, if set\n    pub fn get_idle_timeout(&self) -> Option<Option<Duration>> {\n        self.idle_timeout\n    }\n\n    /// Set the maximum amount of time to spend waiting for acquiring a connection\n    pub fn acquire_timeout(&mut self, value: Duration) -> &mut Self {\n        self.acquire_timeout = Some(value);\n        self\n    }\n\n    /// Get the maximum amount of time to spend waiting for acquiring a connection\n    pub fn get_acquire_timeout(&self) -> Option<Duration> {\n        self.acquire_timeout\n    }\n\n    /// Set the maximum lifetime of individual connections.\n    pub fn max_lifetime<T>(&mut self, lifetime: T) -> &mut Self\n    where\n        T: Into<Option<Duration>>,\n    {\n        self.max_lifetime = Some(lifetime.into());\n        self\n    }\n\n    /// Get the maximum lifetime of individual connections, if set\n    pub fn get_max_lifetime(&self) -> Option<Option<Duration>> {\n        self.max_lifetime\n    }\n\n    /// Enable SQLx statement logging (default true)\n    pub fn sqlx_logging(&mut self, value: bool) -> &mut Self {\n        self.sqlx_logging = value;\n        self\n    }\n\n    /// Get whether SQLx statement logging is enabled\n    pub fn get_sqlx_logging(&self) -> bool {\n        self.sqlx_logging\n    }\n\n    /// Set SQLx statement logging level (default INFO).\n    /// (ignored if `sqlx_logging` is `false`)\n    pub fn sqlx_logging_level(&mut self, level: log::LevelFilter) -> &mut Self {\n        self.sqlx_logging_level = level;\n        self\n    }\n\n    /// Set SQLx slow statements logging level and duration threshold (default `LevelFilter::Off`).\n    /// (ignored if `sqlx_logging` is `false`)\n    pub fn sqlx_slow_statements_logging_settings(\n        &mut self,\n        level: log::LevelFilter,\n        duration: Duration,\n    ) -> &mut Self {\n        self.sqlx_slow_statements_logging_level = level;\n        self.sqlx_slow_statements_logging_threshold = duration;\n        self\n    }\n\n    /// Get the level of SQLx statement logging\n    pub fn get_sqlx_logging_level(&self) -> log::LevelFilter {\n        self.sqlx_logging_level\n    }\n\n    /// Get the SQLx slow statements logging settings\n    pub fn get_sqlx_slow_statements_logging_settings(&self) -> (log::LevelFilter, Duration) {\n        (\n            self.sqlx_slow_statements_logging_level,\n            self.sqlx_slow_statements_logging_threshold,\n        )\n    }\n\n    /// set key for sqlcipher\n    pub fn sqlcipher_key<T>(&mut self, value: T) -> &mut Self\n    where\n        T: Into<Cow<'static, str>>,\n    {\n        self.sqlcipher_key = Some(value.into());\n        self\n    }\n\n    /// Set schema search path (PostgreSQL only)\n    pub fn set_schema_search_path<T>(&mut self, schema_search_path: T) -> &mut Self\n    where\n        T: Into<String>,\n    {\n        self.schema_search_path = Some(schema_search_path.into());\n        self\n    }\n\n    /// Set application name (PostgreSQL only)\n    pub fn set_application_name<T>(&mut self, application_name: T) -> &mut Self\n    where\n        T: Into<String>,\n    {\n        self.application_name = Some(application_name.into());\n        self\n    }\n\n    /// Set the statement timeout (PostgreSQL only).\n    ///\n    /// This sets the PostgreSQL `statement_timeout` parameter via the connection options,\n    /// causing the server to abort any statement that exceeds the specified duration.\n    /// The timeout is applied at connection time and does not require an extra roundtrip.\n    ///\n    /// Has no effect on MySQL or SQLite connections.\n    pub fn statement_timeout(&mut self, value: Duration) -> &mut Self {\n        self.statement_timeout = Some(value);\n        self\n    }\n\n    /// Get the statement timeout, if set\n    pub fn get_statement_timeout(&self) -> Option<Duration> {\n        self.statement_timeout\n    }\n\n    /// If true, the connection will be pinged upon acquiring from the pool (default true).\n    pub fn test_before_acquire(&mut self, value: bool) -> &mut Self {\n        self.test_before_acquire = value;\n        self\n    }\n\n    /// If set to `true`, the db connection pool will be created using SQLx's\n    /// [connect_lazy](https://docs.rs/sqlx/latest/sqlx/struct.Pool.html#method.connect_lazy) method.\n    pub fn connect_lazy(&mut self, value: bool) -> &mut Self {\n        self.connect_lazy = value;\n        self\n    }\n\n    /// Get whether DB connections will be established when the pool is created or only as needed.\n    pub fn get_connect_lazy(&self) -> bool {\n        self.connect_lazy\n    }\n\n    /// Set a callback function that will be called after a new connection is established.\n    pub fn after_connect<F>(&mut self, f: F) -> &mut Self\n    where\n        F: Fn(DatabaseConnection) -> BoxFuture<'static, Result<(), DbErr>> + 'static,\n    {\n        self.after_connect = Some(Arc::new(f));\n\n        self\n    }\n\n    #[cfg(feature = \"sqlx-mysql\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"sqlx-mysql\")))]\n    /// Apply a function to modify the underlying [`MySqlConnectOptions`] before\n    /// creating the connection pool.\n    pub fn map_sqlx_mysql_opts<F>(&mut self, f: F) -> &mut Self\n    where\n        F: Fn(MySqlConnectOptions) -> MySqlConnectOptions + 'static,\n    {\n        self.mysql_opts_fn = Some(Arc::new(f));\n        self\n    }\n\n    #[cfg(feature = \"sqlx-postgres\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"sqlx-postgres\")))]\n    /// Apply a function to modify the underlying [`PgConnectOptions`] before\n    /// creating the connection pool.\n    pub fn map_sqlx_postgres_opts<F>(&mut self, f: F) -> &mut Self\n    where\n        F: Fn(PgConnectOptions) -> PgConnectOptions + 'static,\n    {\n        self.pg_opts_fn = Some(Arc::new(f));\n        self\n    }\n\n    #[cfg(feature = \"sqlx-sqlite\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"sqlx-sqlite\")))]\n    /// Apply a function to modify the underlying [`SqliteConnectOptions`] before\n    /// creating the connection pool.\n    pub fn map_sqlx_sqlite_opts<F>(&mut self, f: F) -> &mut Self\n    where\n        F: Fn(SqliteConnectOptions) -> SqliteConnectOptions + 'static,\n    {\n        self.sqlite_opts_fn = Some(Arc::new(f));\n        self\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/proxy.rs",
    "content": "use crate::{ExecResult, ExecResultHolder, QueryResult, QueryResultRow, Statement, error::*};\n\nuse sea_query::{Value, ValueType};\nuse std::{collections::BTreeMap, fmt::Debug};\n\n/// Defines the [ProxyDatabaseTrait] to save the functions\npub trait ProxyDatabaseTrait: Debug {\n    /// Execute a query in the [ProxyDatabase], and return the query results\n    fn query(&self, statement: Statement) -> Result<Vec<ProxyRow>, DbErr>;\n\n    /// Execute a command in the [ProxyDatabase], and report the number of rows affected\n    fn execute(&self, statement: Statement) -> Result<ProxyExecResult, DbErr>;\n\n    /// Begin a transaction in the [ProxyDatabase]\n    fn begin(&self) {}\n\n    /// Commit a transaction in the [ProxyDatabase]\n    fn commit(&self) {}\n\n    /// Rollback a transaction in the [ProxyDatabase]\n    fn rollback(&self) {}\n\n    /// Start rollback a transaction in the [ProxyDatabase]\n    fn start_rollback(&self) {}\n\n    /// Ping the [ProxyDatabase], it should return an error if the database is not available\n    fn ping(&self) -> Result<(), DbErr> {\n        Ok(())\n    }\n}\n\n/// Defines the results obtained from a [ProxyDatabase]\n#[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize)]\npub struct ProxyExecResult {\n    /// The last inserted id on auto-increment\n    pub last_insert_id: u64,\n    /// The number of rows affected by the database operation\n    pub rows_affected: u64,\n}\n\nimpl ProxyExecResult {\n    /// Create a new [ProxyExecResult] from the last inserted id and the number of rows affected\n    pub fn new(last_insert_id: u64, rows_affected: u64) -> Self {\n        Self {\n            last_insert_id,\n            rows_affected,\n        }\n    }\n}\n\nimpl Default for ExecResultHolder {\n    fn default() -> Self {\n        Self::Proxy(ProxyExecResult::default())\n    }\n}\n\nimpl From<ProxyExecResult> for ExecResult {\n    fn from(result: ProxyExecResult) -> Self {\n        Self {\n            result: ExecResultHolder::Proxy(result),\n        }\n    }\n}\n\nimpl From<ExecResult> for ProxyExecResult {\n    fn from(result: ExecResult) -> Self {\n        match result.result {\n            #[cfg(feature = \"sqlx-mysql\")]\n            ExecResultHolder::SqlxMySql(result) => Self {\n                last_insert_id: result.last_insert_id(),\n                rows_affected: result.rows_affected(),\n            },\n            #[cfg(feature = \"sqlx-postgres\")]\n            ExecResultHolder::SqlxPostgres(result) => Self {\n                last_insert_id: 0,\n                rows_affected: result.rows_affected(),\n            },\n            #[cfg(feature = \"sqlx-sqlite\")]\n            ExecResultHolder::SqlxSqlite(result) => Self {\n                last_insert_id: result.last_insert_rowid() as u64,\n                rows_affected: result.rows_affected(),\n            },\n            #[cfg(feature = \"mock\")]\n            ExecResultHolder::Mock(result) => Self {\n                last_insert_id: result.last_insert_id,\n                rows_affected: result.rows_affected,\n            },\n            ExecResultHolder::Proxy(result) => result,\n        }\n    }\n}\n\n/// Defines the structure of a Row for the [ProxyDatabase]\n/// which is just a [BTreeMap]<[String], [Value]>\n#[derive(Clone, Debug, Default)]\npub struct ProxyRow {\n    /// The values of the single row\n    pub values: BTreeMap<String, Value>,\n}\n\nimpl ProxyRow {\n    /// Create a new [ProxyRow] from a [BTreeMap]<[String], [Value]>\n    pub fn new(values: BTreeMap<String, Value>) -> Self {\n        Self { values }\n    }\n}\n\nimpl From<BTreeMap<String, Value>> for ProxyRow {\n    fn from(values: BTreeMap<String, Value>) -> Self {\n        Self { values }\n    }\n}\n\nimpl From<ProxyRow> for BTreeMap<String, Value> {\n    fn from(row: ProxyRow) -> Self {\n        row.values\n    }\n}\n\nimpl From<ProxyRow> for Vec<(String, Value)> {\n    fn from(row: ProxyRow) -> Self {\n        row.values.into_iter().collect()\n    }\n}\n\nimpl From<ProxyRow> for QueryResult {\n    fn from(row: ProxyRow) -> Self {\n        QueryResult {\n            row: QueryResultRow::Proxy(row),\n        }\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl From<ProxyRow> for serde_json::Value {\n    fn from(val: ProxyRow) -> serde_json::Value {\n        val.values\n            .into_iter()\n            .map(|(k, v)| (k, sea_query::sea_value_to_json_value(&v)))\n            .collect()\n    }\n}\n\n/// Convert [QueryResult] to [ProxyRow]\npub fn from_query_result_to_proxy_row(result: &QueryResult) -> ProxyRow {\n    match &result.row {\n        #[cfg(feature = \"sqlx-mysql\")]\n        QueryResultRow::SqlxMySql(row) => crate::from_sqlx_mysql_row_to_proxy_row(row),\n        #[cfg(feature = \"sqlx-postgres\")]\n        QueryResultRow::SqlxPostgres(row) => crate::from_sqlx_postgres_row_to_proxy_row(row),\n        #[cfg(feature = \"sqlx-sqlite\")]\n        QueryResultRow::SqlxSqlite(row) => crate::from_sqlx_sqlite_row_to_proxy_row(row),\n        #[cfg(feature = \"mock\")]\n        QueryResultRow::Mock(row) => ProxyRow {\n            values: row.values.clone(),\n        },\n        QueryResultRow::Proxy(row) => row.to_owned(),\n    }\n}\n\nimpl ProxyRow {\n    /// Get a value from the [ProxyRow]\n    pub fn try_get<T, I: crate::ColIdx>(&self, index: I) -> Result<T, DbErr>\n    where\n        T: ValueType,\n    {\n        if let Some(index) = index.as_str() {\n            T::try_from(\n                self.values\n                    .get(index)\n                    .ok_or_else(|| query_err(format!(\"No column for ColIdx {index:?}\")))?\n                    .clone(),\n            )\n            .map_err(type_err)\n        } else if let Some(index) = index.as_usize() {\n            let (_, value) = self\n                .values\n                .iter()\n                .nth(*index)\n                .ok_or_else(|| query_err(format!(\"Column at index {index} not found\")))?;\n            T::try_from(value.clone()).map_err(type_err)\n        } else {\n            unreachable!(\"Missing ColIdx implementation for ProxyRow\");\n        }\n    }\n\n    /// An iterator over the keys and values of a proxy row\n    pub fn into_column_value_tuples(self) -> impl Iterator<Item = (String, Value)> {\n        self.values.into_iter()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        Database, DbBackend, DbErr, ProxyDatabaseTrait, ProxyExecResult, ProxyRow, Statement,\n        entity::*, tests_cfg::*,\n    };\n    use std::sync::Arc;\n\n    #[derive(Debug)]\n    struct ProxyDb {}\n\n    impl ProxyDatabaseTrait for ProxyDb {\n        fn query(&self, statement: Statement) -> Result<Vec<ProxyRow>, DbErr> {\n            println!(\"SQL query: {}\", statement.sql);\n            Ok(vec![].into())\n        }\n\n        fn execute(&self, statement: Statement) -> Result<ProxyExecResult, DbErr> {\n            println!(\"SQL execute: {}\", statement.sql);\n            Ok(ProxyExecResult {\n                last_insert_id: 1,\n                rows_affected: 1,\n            })\n        }\n    }\n\n    #[test]\n    fn create_proxy_conn() {\n        let _db =\n            Database::connect_proxy(DbBackend::MySql, Arc::new(Box::new(ProxyDb {}))).unwrap();\n    }\n\n    #[test]\n    fn select_rows() {\n        let db = Database::connect_proxy(DbBackend::MySql, Arc::new(Box::new(ProxyDb {}))).unwrap();\n\n        let _ = cake::Entity::find().all(&db);\n    }\n\n    #[test]\n    fn insert_one_row() {\n        let db = Database::connect_proxy(DbBackend::MySql, Arc::new(Box::new(ProxyDb {}))).unwrap();\n\n        let item = cake::ActiveModel {\n            id: NotSet,\n            name: Set(\"Alice\".to_string()),\n        };\n\n        cake::Entity::insert(item).exec(&db).unwrap();\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/restricted_connection.rs",
    "content": "use crate::{\n    AccessMode, ConnectionTrait, DatabaseConnection, DatabaseTransaction, DbBackend, DbErr,\n    ExecResult, IsolationLevel, QueryResult, Statement, StatementBuilder, TransactionError,\n    TransactionSession, TransactionTrait,\n};\nuse crate::{\n    TransactionOptions,\n    rbac::{\n        PermissionRequest, RbacEngine, RbacError, RbacPermissionsByResources,\n        RbacResourcesAndPermissions, RbacRoleHierarchyList, RbacRolesAndRanks,\n        RbacUserRolePermissions, ResourceRequest,\n        entity::{role::RoleId, user::UserId},\n    },\n};\nuse std::{\n    pin::Pin,\n    sync::{Arc, RwLock},\n};\nuse tracing::instrument;\n\n/// Wrapper of [`DatabaseConnection`] that performs authorization on all executed\n/// queries for the current user. Note that raw SQL [`Statement`] is not allowed\n/// currently.\n#[derive(Debug, Clone)]\n#[cfg_attr(docsrs, doc(cfg(feature = \"rbac\")))]\npub struct RestrictedConnection {\n    pub(crate) user_id: UserId,\n    pub(crate) conn: DatabaseConnection,\n}\n\n/// Wrapper of [`DatabaseTransaction`] that performs authorization on all executed\n/// queries for the current user. Note that raw SQL [`Statement`] is not allowed\n/// currently.\n#[derive(Debug)]\npub struct RestrictedTransaction {\n    user_id: UserId,\n    conn: DatabaseTransaction,\n    rbac: RbacEngineMount,\n}\n\n#[derive(Debug, Default, Clone)]\npub(crate) struct RbacEngineMount {\n    inner: Arc<RwLock<Option<RbacEngine>>>,\n}\n\nimpl ConnectionTrait for RestrictedConnection {\n    fn get_database_backend(&self) -> DbBackend {\n        self.conn.get_database_backend()\n    }\n\n    fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {stmt}\"\n        )))\n    }\n\n    fn execute<S: StatementBuilder>(&self, stmt: &S) -> Result<ExecResult, DbErr> {\n        self.user_can_run(stmt)?;\n        self.conn.execute(stmt)\n    }\n\n    fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {sql}\"\n        )))\n    }\n\n    fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {stmt}\"\n        )))\n    }\n\n    fn query_one<S: StatementBuilder>(&self, stmt: &S) -> Result<Option<QueryResult>, DbErr> {\n        self.user_can_run(stmt)?;\n        self.conn.query_one(stmt)\n    }\n\n    fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {stmt}\"\n        )))\n    }\n\n    fn query_all<S: StatementBuilder>(&self, stmt: &S) -> Result<Vec<QueryResult>, DbErr> {\n        self.user_can_run(stmt)?;\n        self.conn.query_all(stmt)\n    }\n}\n\nimpl ConnectionTrait for RestrictedTransaction {\n    fn get_database_backend(&self) -> DbBackend {\n        self.conn.get_database_backend()\n    }\n\n    fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {stmt}\"\n        )))\n    }\n\n    fn execute<S: StatementBuilder>(&self, stmt: &S) -> Result<ExecResult, DbErr> {\n        self.user_can_run(stmt)?;\n        self.conn.execute(stmt)\n    }\n\n    fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {sql}\"\n        )))\n    }\n\n    fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {stmt}\"\n        )))\n    }\n\n    fn query_one<S: StatementBuilder>(&self, stmt: &S) -> Result<Option<QueryResult>, DbErr> {\n        self.user_can_run(stmt)?;\n        self.conn.query_one(stmt)\n    }\n\n    fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {stmt}\"\n        )))\n    }\n\n    fn query_all<S: StatementBuilder>(&self, stmt: &S) -> Result<Vec<QueryResult>, DbErr> {\n        self.user_can_run(stmt)?;\n        self.conn.query_all(stmt)\n    }\n}\n\nimpl RestrictedConnection {\n    /// Get the [`RbacUserId`] bounded to this connection.\n    pub fn user_id(&self) -> UserId {\n        self.user_id\n    }\n\n    /// Returns `()` if the current user can execute / query the given SQL statement.\n    /// Returns `DbErr::AccessDenied` otherwise.\n    pub fn user_can_run<S: StatementBuilder>(&self, stmt: &S) -> Result<(), DbErr> {\n        self.conn.rbac.user_can_run(self.user_id, stmt)\n    }\n\n    /// Returns true if the current user can perform action on resource\n    pub fn user_can<P, R>(&self, permission: P, resource: R) -> Result<bool, DbErr>\n    where\n        P: Into<PermissionRequest>,\n        R: Into<ResourceRequest>,\n    {\n        self.conn.rbac.user_can(self.user_id, permission, resource)\n    }\n\n    /// Get current user's role and associated permissions.\n    /// This includes permissions \"inherited\" from child roles.\n    pub fn current_user_role_permissions(&self) -> Result<RbacUserRolePermissions, DbErr> {\n        self.conn.rbac.user_role_permissions(self.user_id)\n    }\n\n    /// Get a list of all roles and their ranks.\n    /// Rank is defined as (1 + number of child roles).\n    pub fn roles_and_ranks(&self) -> Result<RbacRolesAndRanks, DbErr> {\n        self.conn.rbac.roles_and_ranks()\n    }\n\n    /// Get two lists of all resources and permissions, excluding wildcards.\n    pub fn resources_and_permissions(&self) -> Result<RbacResourcesAndPermissions, DbErr> {\n        self.conn.rbac.resources_and_permissions()\n    }\n\n    /// Get a list of edges walking the role hierarchy tree\n    pub fn role_hierarchy_edges(&self, role_id: RoleId) -> Result<RbacRoleHierarchyList, DbErr> {\n        self.conn.rbac.role_hierarchy_edges(role_id)\n    }\n\n    /// Get a list of permissions for the specific role, grouped by resources.\n    /// This does not include permissions of child roles.\n    pub fn role_permissions_by_resources(\n        &self,\n        role_id: RoleId,\n    ) -> Result<RbacPermissionsByResources, DbErr> {\n        self.conn.rbac.role_permissions_by_resources(role_id)\n    }\n}\n\nimpl RestrictedTransaction {\n    /// Get the [`RbacUserId`] bounded to this connection.\n    pub fn user_id(&self) -> UserId {\n        self.user_id\n    }\n\n    /// Returns `()` if the current user can execute / query the given SQL statement.\n    /// Returns `DbErr::AccessDenied` otherwise.\n    pub fn user_can_run<S: StatementBuilder>(&self, stmt: &S) -> Result<(), DbErr> {\n        self.rbac.user_can_run(self.user_id, stmt)\n    }\n\n    /// Returns true if the current user can perform action on resource\n    pub fn user_can<P, R>(&self, permission: P, resource: R) -> Result<bool, DbErr>\n    where\n        P: Into<PermissionRequest>,\n        R: Into<ResourceRequest>,\n    {\n        self.rbac.user_can(self.user_id, permission, resource)\n    }\n}\n\nimpl TransactionTrait for RestrictedConnection {\n    type Transaction = RestrictedTransaction;\n\n    #[instrument(level = \"trace\")]\n    fn begin(&self) -> Result<RestrictedTransaction, DbErr> {\n        Ok(RestrictedTransaction {\n            user_id: self.user_id,\n            conn: self.conn.begin()?,\n            rbac: self.conn.rbac.clone(),\n        })\n    }\n\n    #[instrument(level = \"trace\")]\n    fn begin_with_config(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<RestrictedTransaction, DbErr> {\n        Ok(RestrictedTransaction {\n            user_id: self.user_id,\n            conn: self.conn.begin_with_config(isolation_level, access_mode)?,\n            rbac: self.conn.rbac.clone(),\n        })\n    }\n\n    #[instrument(level = \"trace\")]\n    fn begin_with_options(\n        &self,\n        options: TransactionOptions,\n    ) -> Result<RestrictedTransaction, DbErr> {\n        Ok(RestrictedTransaction {\n            user_id: self.user_id,\n            conn: self.conn.begin_with_options(options)?,\n            rbac: self.conn.rbac.clone(),\n        })\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(callback))]\n    fn transaction<F, T, E>(&self, callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(&'c RestrictedTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        let transaction = self.begin().map_err(TransactionError::Connection)?;\n        transaction.run(callback)\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(callback))]\n    fn transaction_with_config<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(&'c RestrictedTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        let transaction = self\n            .begin_with_config(isolation_level, access_mode)\n            .map_err(TransactionError::Connection)?;\n        transaction.run(callback)\n    }\n}\n\nimpl TransactionTrait for RestrictedTransaction {\n    type Transaction = RestrictedTransaction;\n\n    #[instrument(level = \"trace\")]\n    fn begin(&self) -> Result<RestrictedTransaction, DbErr> {\n        Ok(RestrictedTransaction {\n            user_id: self.user_id,\n            conn: self.conn.begin()?,\n            rbac: self.rbac.clone(),\n        })\n    }\n\n    #[instrument(level = \"trace\")]\n    fn begin_with_config(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<RestrictedTransaction, DbErr> {\n        Ok(RestrictedTransaction {\n            user_id: self.user_id,\n            conn: self.conn.begin_with_config(isolation_level, access_mode)?,\n            rbac: self.rbac.clone(),\n        })\n    }\n\n    #[instrument(level = \"trace\")]\n    fn begin_with_options(\n        &self,\n        options: TransactionOptions,\n    ) -> Result<RestrictedTransaction, DbErr> {\n        Ok(RestrictedTransaction {\n            user_id: self.user_id,\n            conn: self.conn.begin_with_options(options)?,\n            rbac: self.rbac.clone(),\n        })\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(callback))]\n    fn transaction<F, T, E>(&self, callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(&'c RestrictedTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        let transaction = self.begin().map_err(TransactionError::Connection)?;\n        transaction.run(callback)\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(callback))]\n    fn transaction_with_config<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(&'c RestrictedTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        let transaction = self\n            .begin_with_config(isolation_level, access_mode)\n            .map_err(TransactionError::Connection)?;\n        transaction.run(callback)\n    }\n}\n\nimpl TransactionSession for RestrictedTransaction {\n    fn commit(self) -> Result<(), DbErr> {\n        self.commit()\n    }\n\n    fn rollback(self) -> Result<(), DbErr> {\n        self.rollback()\n    }\n}\n\nimpl RestrictedTransaction {\n    /// Runs a transaction to completion passing through the result.\n    /// Rolling back the transaction on encountering an error.\n    #[instrument(level = \"trace\", skip(callback))]\n    fn run<F, T, E>(self, callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'b> FnOnce(&'b RestrictedTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        let res = callback(&self).map_err(TransactionError::Transaction);\n        if res.is_ok() {\n            self.commit().map_err(TransactionError::Connection)?;\n        } else {\n            self.rollback().map_err(TransactionError::Connection)?;\n        }\n        res\n    }\n\n    /// Commit a transaction\n    #[instrument(level = \"trace\")]\n    pub fn commit(self) -> Result<(), DbErr> {\n        self.conn.commit()\n    }\n\n    /// Rolls back a transaction explicitly\n    #[instrument(level = \"trace\")]\n    pub fn rollback(self) -> Result<(), DbErr> {\n        self.conn.rollback()\n    }\n}\n\nimpl RbacEngineMount {\n    pub fn is_some(&self) -> bool {\n        let engine = self.inner.read().expect(\"RBAC Engine died\");\n        engine.is_some()\n    }\n\n    pub fn replace(&self, engine: RbacEngine) {\n        let mut inner = self.inner.write().expect(\"RBAC Engine died\");\n        *inner = Some(engine);\n    }\n\n    pub fn user_can<P, R>(&self, user_id: UserId, permission: P, resource: R) -> Result<bool, DbErr>\n    where\n        P: Into<PermissionRequest>,\n        R: Into<ResourceRequest>,\n    {\n        let permission = permission.into();\n        let resource = resource.into();\n        // There is nothing we can do if RwLock is poisoned.\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        // Constructor of this struct should ensure engine is not None.\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        engine\n            .user_can(user_id, permission, resource)\n            .map_err(map_err)\n    }\n\n    pub fn user_can_run<S: StatementBuilder>(\n        &self,\n        user_id: UserId,\n        stmt: &S,\n    ) -> Result<(), DbErr> {\n        let audit = match stmt.audit() {\n            Ok(audit) => audit,\n            Err(err) => return Err(DbErr::RbacError(err.to_string())),\n        };\n        // There is nothing we can do if RwLock is poisoned.\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        // Constructor of this struct should ensure engine is not None.\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        for request in audit.requests {\n            let permission = || PermissionRequest {\n                action: request.access_type.as_str().to_owned(),\n            };\n            let resource = || ResourceRequest {\n                schema: request.schema_table.0.as_ref().map(|s| s.1.to_string()),\n                table: request.schema_table.1.to_string(),\n            };\n            if !engine\n                .user_can(user_id, permission(), resource())\n                .map_err(map_err)?\n            {\n                return Err(DbErr::AccessDenied {\n                    permission: permission().action.to_owned(),\n                    resource: resource().to_string(),\n                });\n            }\n        }\n        Ok(())\n    }\n\n    pub fn user_role_permissions(&self, user_id: UserId) -> Result<RbacUserRolePermissions, DbErr> {\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        engine\n            .get_user_role_permissions(user_id)\n            .map_err(|err| DbErr::RbacError(err.to_string()))\n    }\n\n    pub fn roles_and_ranks(&self) -> Result<RbacRolesAndRanks, DbErr> {\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        engine\n            .get_roles_and_ranks()\n            .map_err(|err| DbErr::RbacError(err.to_string()))\n    }\n\n    pub fn resources_and_permissions(&self) -> Result<RbacResourcesAndPermissions, DbErr> {\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        Ok(engine.list_resources_and_permissions())\n    }\n\n    pub fn role_hierarchy_edges(&self, role_id: RoleId) -> Result<RbacRoleHierarchyList, DbErr> {\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        Ok(engine.list_role_hierarchy_edges(role_id))\n    }\n\n    pub fn role_permissions_by_resources(\n        &self,\n        role_id: RoleId,\n    ) -> Result<RbacPermissionsByResources, DbErr> {\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        engine\n            .list_role_permissions_by_resources(role_id)\n            .map_err(|err| DbErr::RbacError(err.to_string()))\n    }\n}\n\nfn map_err(err: RbacError) -> DbErr {\n    DbErr::RbacError(err.to_string())\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/sea_schema_rusqlite.rs",
    "content": "use crate::{\n    ConnectionTrait, DatabaseConnection, DatabaseTransaction, DbErr, QueryResult, QueryResultRow,\n    RuntimeErr, Statement, driver::rusqlite::RusqliteRow as OurRusqliteRow,\n};\nuse sea_query::SelectStatement;\nuse sea_schema::rusqlite_types::{RusqliteError, RusqliteRow};\nuse std::sync::Arc;\n\nimpl sea_schema::Connection for DatabaseConnection {\n    fn query_all(&self, select: SelectStatement) -> Result<Vec<RusqliteRow>, RusqliteError> {\n        map_result(ConnectionTrait::query_all(self, &select))\n    }\n\n    fn query_all_raw(&self, sql: String) -> Result<Vec<RusqliteRow>, RusqliteError> {\n        map_result(ConnectionTrait::query_all_raw(\n            self,\n            Statement::from_string(self.get_database_backend(), sql),\n        ))\n    }\n}\n\nimpl sea_schema::Connection for DatabaseTransaction {\n    fn query_all(&self, select: SelectStatement) -> Result<Vec<RusqliteRow>, RusqliteError> {\n        map_result(ConnectionTrait::query_all(self, &select))\n    }\n\n    fn query_all_raw(&self, sql: String) -> Result<Vec<RusqliteRow>, RusqliteError> {\n        map_result(ConnectionTrait::query_all_raw(\n            self,\n            Statement::from_string(self.get_database_backend(), sql),\n        ))\n    }\n}\n\nfn map_result(result: Result<Vec<QueryResult>, DbErr>) -> Result<Vec<RusqliteRow>, RusqliteError> {\n    match result {\n        Ok(rows) => Ok(rows\n            .into_iter()\n            .filter_map(|r| match r.row {\n                #[cfg(feature = \"rusqlite\")]\n                QueryResultRow::Rusqlite(OurRusqliteRow { values, .. }) => {\n                    Some(RusqliteRow { values })\n                }\n                #[allow(unreachable_patterns)]\n                _ => None,\n            })\n            .collect()),\n        Err(err) => Err(match err {\n            DbErr::Conn(RuntimeErr::Rusqlite(err)) => {\n                Arc::into_inner(err).expect(\"Should only have one owner\")\n            }\n            DbErr::Exec(RuntimeErr::Rusqlite(err)) => {\n                Arc::into_inner(err).expect(\"Should only have one owner\")\n            }\n            DbErr::Query(RuntimeErr::Rusqlite(err)) => {\n                Arc::into_inner(err).expect(\"Should only have one owner\")\n            }\n            _ => RusqliteError::InvalidParameterName(err.to_string()),\n        }),\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/sea_schema_shim.rs",
    "content": "use crate::{\n    ConnectionTrait, DatabaseConnection, DatabaseTransaction, DbErr, QueryResult, QueryResultRow,\n    RuntimeErr, Statement,\n};\nuse sea_query::SelectStatement;\nuse sea_schema::sqlx_types::SqlxRow;\nuse sqlx::Error as SqlxError;\nuse std::sync::Arc;\n\nimpl sea_schema::Connection for DatabaseConnection {\n    fn query_all(&self, select: SelectStatement) -> Result<Vec<SqlxRow>, SqlxError> {\n        map_result(ConnectionTrait::query_all(self, &select))\n    }\n\n    fn query_all_raw(&self, sql: String) -> Result<Vec<SqlxRow>, SqlxError> {\n        map_result(ConnectionTrait::query_all_raw(\n            self,\n            Statement::from_string(self.get_database_backend(), sql),\n        ))\n    }\n}\n\nimpl sea_schema::Connection for DatabaseTransaction {\n    fn query_all(&self, select: SelectStatement) -> Result<Vec<SqlxRow>, SqlxError> {\n        map_result(ConnectionTrait::query_all(self, &select))\n    }\n\n    fn query_all_raw(&self, sql: String) -> Result<Vec<SqlxRow>, SqlxError> {\n        map_result(ConnectionTrait::query_all_raw(\n            self,\n            Statement::from_string(self.get_database_backend(), sql),\n        ))\n    }\n}\n\nimpl sea_schema::Connection for crate::DatabaseExecutor<'_> {\n    fn query_all(&self, select: SelectStatement) -> Result<Vec<SqlxRow>, SqlxError> {\n        match self {\n            crate::DatabaseExecutor::Connection(conn) => {\n                <DatabaseConnection as sea_schema::Connection>::query_all(conn, select)\n            }\n            crate::DatabaseExecutor::Transaction(txn) => {\n                <DatabaseTransaction as sea_schema::Connection>::query_all(txn, select)\n            }\n            crate::DatabaseExecutor::OwnedTransaction(txn) => {\n                <DatabaseTransaction as sea_schema::Connection>::query_all(txn, select)\n            }\n        }\n    }\n\n    fn query_all_raw(&self, sql: String) -> Result<Vec<SqlxRow>, SqlxError> {\n        match self {\n            crate::DatabaseExecutor::Connection(conn) => {\n                <DatabaseConnection as sea_schema::Connection>::query_all_raw(conn, sql)\n            }\n            crate::DatabaseExecutor::Transaction(txn) => {\n                <DatabaseTransaction as sea_schema::Connection>::query_all_raw(txn, sql)\n            }\n            crate::DatabaseExecutor::OwnedTransaction(txn) => {\n                <DatabaseTransaction as sea_schema::Connection>::query_all_raw(txn, sql)\n            }\n        }\n    }\n}\n\nfn map_result(result: Result<Vec<QueryResult>, DbErr>) -> Result<Vec<SqlxRow>, SqlxError> {\n    match result {\n        Ok(rows) => Ok(rows\n            .into_iter()\n            .filter_map(|r| match r.row {\n                #[cfg(feature = \"sqlx-mysql\")]\n                QueryResultRow::SqlxMySql(r) => Some(SqlxRow::MySql(r)),\n                #[cfg(feature = \"sqlx-postgres\")]\n                QueryResultRow::SqlxPostgres(r) => Some(SqlxRow::Postgres(r)),\n                #[cfg(feature = \"sqlx-sqlite\")]\n                QueryResultRow::SqlxSqlite(r) => Some(SqlxRow::Sqlite(r)),\n                #[allow(unreachable_patterns)]\n                _ => None,\n            })\n            .collect()),\n        Err(err) => Err(match err {\n            DbErr::Conn(RuntimeErr::SqlxError(err)) => {\n                Arc::into_inner(err).expect(\"Should only have one owner\")\n            }\n            DbErr::Exec(RuntimeErr::SqlxError(err)) => {\n                Arc::into_inner(err).expect(\"Should only have one owner\")\n            }\n            DbErr::Query(RuntimeErr::SqlxError(err)) => {\n                Arc::into_inner(err).expect(\"Should only have one owner\")\n            }\n            _ => SqlxError::AnyDriverError(Box::new(err)),\n        }),\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/statement.rs",
    "content": "use crate::DbBackend;\n#[cfg(feature = \"rbac\")]\npub use sea_query::audit::{AuditTrait, Error as AuditError, QueryAccessAudit};\nuse sea_query::{MysqlQueryBuilder, PostgresQueryBuilder, SqliteQueryBuilder, inject_parameters};\npub use sea_query::{Value, Values};\nuse std::fmt;\n\n/// Defines an SQL statement\n#[derive(Debug, Clone, PartialEq)]\npub struct Statement {\n    /// The SQL query\n    pub sql: String,\n    /// The values for the SQL statement's parameters\n    pub values: Option<Values>,\n    /// The database backend this statement is constructed for.\n    /// The SQL dialect and values should be valid for the DbBackend.\n    pub db_backend: DbBackend,\n}\n\n/// Any type that can build a [Statement]\npub trait StatementBuilder {\n    /// Method to build a [Statement]\n    fn build(&self, db_backend: &DbBackend) -> Statement;\n\n    #[cfg(feature = \"rbac\")]\n    /// Method to audit access request of query\n    fn audit(&self) -> Result<QueryAccessAudit, AuditError>;\n}\n\nimpl Statement {\n    /// Create a [Statement] from a [crate::DatabaseBackend] and a raw SQL statement\n    pub fn from_string<T>(db_backend: DbBackend, stmt: T) -> Statement\n    where\n        T: Into<String>,\n    {\n        Statement {\n            sql: stmt.into(),\n            values: None,\n            db_backend,\n        }\n    }\n\n    /// Create a SQL statement from a [crate::DatabaseBackend], a\n    /// raw SQL statement and param values\n    pub fn from_sql_and_values<I, T>(db_backend: DbBackend, sql: T, values: I) -> Self\n    where\n        I: IntoIterator<Item = Value>,\n        T: Into<String>,\n    {\n        Self::from_string_values_tuple(db_backend, (sql, Values(values.into_iter().collect())))\n    }\n\n    pub(crate) fn from_string_values_tuple<T>(db_backend: DbBackend, stmt: (T, Values)) -> Statement\n    where\n        T: Into<String>,\n    {\n        Statement {\n            sql: stmt.0.into(),\n            values: Some(stmt.1),\n            db_backend,\n        }\n    }\n}\n\nimpl fmt::Display for Statement {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match &self.values {\n            Some(values) => {\n                let string = match self.db_backend {\n                    DbBackend::MySql => inject_parameters(&self.sql, &values.0, &MysqlQueryBuilder),\n                    DbBackend::Postgres => {\n                        inject_parameters(&self.sql, &values.0, &PostgresQueryBuilder)\n                    }\n                    DbBackend::Sqlite => {\n                        inject_parameters(&self.sql, &values.0, &SqliteQueryBuilder)\n                    }\n                };\n                write!(f, \"{}\", &string)\n            }\n            None => {\n                write!(f, \"{}\", &self.sql)\n            }\n        }\n    }\n}\n\nmacro_rules! build_any_stmt {\n    ($stmt: expr, $db_backend: expr) => {\n        match $db_backend {\n            DbBackend::MySql => $stmt.build(MysqlQueryBuilder),\n            DbBackend::Postgres => $stmt.build(PostgresQueryBuilder),\n            DbBackend::Sqlite => $stmt.build(SqliteQueryBuilder),\n        }\n    };\n}\n\nmacro_rules! build_postgres_stmt {\n    ($stmt: expr, $db_backend: expr) => {\n        match $db_backend {\n            DbBackend::Postgres => $stmt.to_string(PostgresQueryBuilder),\n            DbBackend::MySql | DbBackend::Sqlite => unimplemented!(),\n        }\n    };\n}\n\nmacro_rules! build_query_stmt {\n    ($stmt: ty) => {\n        impl StatementBuilder for $stmt {\n            fn build(&self, db_backend: &DbBackend) -> Statement {\n                let stmt = build_any_stmt!(self, db_backend);\n                Statement::from_string_values_tuple(*db_backend, stmt)\n            }\n\n            #[cfg(feature = \"rbac\")]\n            fn audit(&self) -> Result<QueryAccessAudit, AuditError> {\n                AuditTrait::audit(self)\n            }\n        }\n    };\n}\n\nbuild_query_stmt!(sea_query::InsertStatement);\nbuild_query_stmt!(sea_query::SelectStatement);\nbuild_query_stmt!(sea_query::UpdateStatement);\nbuild_query_stmt!(sea_query::DeleteStatement);\nbuild_query_stmt!(sea_query::WithQuery);\n\nmacro_rules! build_schema_stmt {\n    ($stmt: ty) => {\n        impl StatementBuilder for $stmt {\n            fn build(&self, db_backend: &DbBackend) -> Statement {\n                let stmt = build_any_stmt!(self, db_backend);\n                Statement::from_string(*db_backend, stmt)\n            }\n\n            #[cfg(feature = \"rbac\")]\n            fn audit(&self) -> Result<QueryAccessAudit, AuditError> {\n                todo!(\"Audit not supported for {} yet\", stringify!($stmt))\n            }\n        }\n    };\n}\n\nbuild_schema_stmt!(sea_query::TableCreateStatement);\nbuild_schema_stmt!(sea_query::TableDropStatement);\nbuild_schema_stmt!(sea_query::TableAlterStatement);\nbuild_schema_stmt!(sea_query::TableRenameStatement);\nbuild_schema_stmt!(sea_query::TableTruncateStatement);\nbuild_schema_stmt!(sea_query::IndexCreateStatement);\nbuild_schema_stmt!(sea_query::IndexDropStatement);\nbuild_schema_stmt!(sea_query::ForeignKeyCreateStatement);\nbuild_schema_stmt!(sea_query::ForeignKeyDropStatement);\n\nmacro_rules! build_type_stmt {\n    ($stmt: ty) => {\n        impl StatementBuilder for $stmt {\n            fn build(&self, db_backend: &DbBackend) -> Statement {\n                let stmt = build_postgres_stmt!(self, db_backend);\n                Statement::from_string(*db_backend, stmt)\n            }\n\n            #[cfg(feature = \"rbac\")]\n            fn audit(&self) -> Result<QueryAccessAudit, AuditError> {\n                Err(AuditError::UnsupportedQuery)\n            }\n        }\n    };\n}\n\nbuild_type_stmt!(sea_query::extension::postgres::TypeAlterStatement);\nbuild_type_stmt!(sea_query::extension::postgres::TypeCreateStatement);\nbuild_type_stmt!(sea_query::extension::postgres::TypeDropStatement);\n"
  },
  {
    "path": "sea-orm-sync/src/database/stream/metric.rs",
    "content": "use std::time::Duration;\n\nuse crate::{DbErr, QueryResult, Statement};\n\n#[cfg(not(feature = \"sync\"))]\ntype PinBoxStream<'a> = Pin<Box<dyn Stream<Item = Result<QueryResult, DbErr>> + 'a>>;\n#[cfg(feature = \"sync\")]\ntype PinBoxStream<'a> = Box<dyn Iterator<Item = Result<QueryResult, DbErr>> + 'a>;\n\npub(crate) struct MetricStream<'a> {\n    metric_callback: &'a Option<crate::metric::Callback>,\n    stmt: &'a Statement,\n    elapsed: Option<Duration>,\n    stream: PinBoxStream<'a>,\n}\n\nimpl<'a> MetricStream<'a> {\n    #[allow(dead_code)]\n    pub(crate) fn new<S>(\n        metric_callback: &'a Option<crate::metric::Callback>,\n        stmt: &'a Statement,\n        elapsed: Option<Duration>,\n        stream: S,\n    ) -> Self\n    where\n        S: Iterator<Item = Result<QueryResult, DbErr>> + 'a,\n    {\n        MetricStream {\n            metric_callback,\n            stmt,\n            elapsed,\n            stream: Box::new(stream),\n        }\n    }\n}\n\n#[cfg(not(feature = \"sync\"))]\nimpl Stream for MetricStream<'_> {\n    type Item = Result<QueryResult, DbErr>;\n\n    fn poll_next(\n        self: Pin<&mut Self>,\n        cx: &mut std::task::Context<'_>,\n    ) -> Poll<Option<Self::Item>> {\n        let this = self.get_mut();\n        let _start = this\n            .metric_callback\n            .is_some()\n            .then(std::time::SystemTime::now);\n        let res = Pin::new(&mut this.stream).poll_next(cx);\n        if let (Some(_start), Some(elapsed)) = (_start, &mut this.elapsed) {\n            *elapsed += _start.elapsed().unwrap_or_default();\n        }\n        res\n    }\n}\n\n#[cfg(feature = \"sync\")]\nimpl Iterator for MetricStream<'_> {\n    type Item = Result<QueryResult, DbErr>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let _start = self\n            .metric_callback\n            .is_some()\n            .then(std::time::SystemTime::now);\n        let res = self.stream.next();\n        if let (Some(_start), Some(elapsed)) = (_start, &mut self.elapsed) {\n            *elapsed += _start.elapsed().unwrap_or_default();\n        }\n        res\n    }\n}\n\nimpl Drop for MetricStream<'_> {\n    fn drop(&mut self) {\n        if let (Some(callback), Some(elapsed)) = (self.metric_callback.as_deref(), self.elapsed) {\n            let info = crate::metric::Info {\n                elapsed,\n                statement: self.stmt,\n                failed: false,\n            };\n            callback(&info);\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/stream/mod.rs",
    "content": "mod metric;\n\nmod query;\nmod transaction;\n\npub use query::*;\npub use transaction::*;\n"
  },
  {
    "path": "sea-orm-sync/src/database/stream/query.rs",
    "content": "#![allow(missing_docs, unreachable_code, unused_variables)]\n\nuse tracing::instrument;\n\n#[cfg(feature = \"sqlx-dep\")]\nuse futures_util::TryStreamExt;\n\n#[cfg(feature = \"sqlx-dep\")]\nuse sqlx::Executor;\n\nuse super::metric::MetricStream;\n#[cfg(feature = \"sqlx-dep\")]\nuse crate::driver::*;\nuse crate::{DbErr, InnerConnection, QueryResult, Statement};\n\n/// Creates a stream from a [QueryResult]\n#[ouroboros::self_referencing]\npub struct QueryStream {\n    stmt: Statement,\n    conn: InnerConnection,\n    metric_callback: Option<crate::metric::Callback>,\n    #[borrows(mut conn, stmt, metric_callback)]\n    #[not_covariant]\n    stream: MetricStream<'this>,\n}\n\nimpl std::fmt::Debug for QueryStream {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"QueryStream\")\n    }\n}\n\nimpl QueryStream {\n    #[allow(dead_code)]\n    #[instrument(level = \"trace\", skip(metric_callback))]\n    pub(crate) fn build(\n        stmt: Statement,\n        conn: InnerConnection,\n        metric_callback: Option<crate::metric::Callback>,\n    ) -> QueryStream {\n        QueryStreamBuilder {\n            stmt,\n            conn,\n            metric_callback,\n            stream_builder: |conn, stmt, _metric_callback| match conn {\n                #[cfg(feature = \"sqlx-mysql\")]\n                InnerConnection::MySql(c) => {\n                    let query = crate::driver::sqlx_mysql::sqlx_query(stmt);\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c\n                        .fetch(query)\n                        .map_ok(Into::into)\n                        .map_err(sqlx_error_to_query_err);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"sqlx-postgres\")]\n                InnerConnection::Postgres(c) => {\n                    let query = crate::driver::sqlx_postgres::sqlx_query(stmt);\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c\n                        .fetch(query)\n                        .map_ok(Into::into)\n                        .map_err(sqlx_error_to_query_err);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"sqlx-sqlite\")]\n                InnerConnection::Sqlite(c) => {\n                    let query = crate::driver::sqlx_sqlite::sqlx_query(stmt);\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c\n                        .fetch(query)\n                        .map_ok(Into::into)\n                        .map_err(sqlx_error_to_query_err);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"rusqlite\")]\n                InnerConnection::Rusqlite(conn) => {\n                    use itertools::Either;\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = match conn.stream(stmt) {\n                        Ok(rows) => Either::Left(rows.into_iter().map(Ok)),\n                        Err(err) => Either::Right(std::iter::once(Err(err))),\n                    };\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"mock\")]\n                InnerConnection::Mock(c) => {\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c.fetch(stmt);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"proxy\")]\n                InnerConnection::Proxy(c) => {\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = futures_util::stream::once({\n                        Err(DbErr::BackendNotSupported {\n                            db: \"Proxy\",\n                            ctx: \"QueryStream\",\n                        })\n                    });\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[allow(unreachable_patterns)]\n                _ => unreachable!(),\n            },\n        }\n        .build()\n    }\n}\n\n#[cfg(not(feature = \"sync\"))]\nimpl Stream for QueryStream {\n    type Item = Result<QueryResult, DbErr>;\n\n    fn poll_next(\n        self: Pin<&mut Self>,\n        cx: &mut std::task::Context<'_>,\n    ) -> Poll<Option<Self::Item>> {\n        let this = self.get_mut();\n        this.with_stream_mut(|stream| Pin::new(stream).poll_next(cx))\n    }\n}\n\n#[cfg(feature = \"sync\")]\nimpl Iterator for QueryStream {\n    type Item = Result<QueryResult, DbErr>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.with_stream_mut(|stream| stream.next())\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/stream/transaction.rs",
    "content": "#![allow(missing_docs)]\n\nuse std::ops::DerefMut;\nuse tracing::instrument;\n\n#[cfg(feature = \"sqlx-dep\")]\nuse futures_util::TryStreamExt;\n\nuse std::sync::MutexGuard;\n\n#[cfg(feature = \"sqlx-dep\")]\nuse sqlx::Executor;\n\nuse super::metric::MetricStream;\n#[cfg(feature = \"sqlx-dep\")]\nuse crate::driver::*;\nuse crate::{DbErr, InnerConnection, QueryResult, Statement};\n\n/// `TransactionStream` cannot be used in a `transaction` closure as it does not impl `Send`.\n/// It seems to be a Rust limitation right now, and solution to work around this deemed to be extremely hard.\n#[ouroboros::self_referencing]\npub struct TransactionStream<'a> {\n    stmt: Statement,\n    conn: MutexGuard<'a, InnerConnection>,\n    metric_callback: Option<crate::metric::Callback>,\n    #[borrows(mut conn, stmt, metric_callback)]\n    #[not_covariant]\n    stream: MetricStream<'this>,\n}\n\nimpl std::fmt::Debug for TransactionStream<'_> {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"TransactionStream\")\n    }\n}\n\nimpl TransactionStream<'_> {\n    #[instrument(level = \"trace\", skip(metric_callback))]\n    #[allow(unused_variables)]\n    pub(crate) fn build(\n        conn: MutexGuard<'_, InnerConnection>,\n        stmt: Statement,\n        metric_callback: Option<crate::metric::Callback>,\n    ) -> TransactionStream<'_> {\n        TransactionStreamBuilder {\n            stmt,\n            conn,\n            metric_callback,\n            stream_builder: |conn, stmt, _metric_callback| match conn.deref_mut() {\n                #[cfg(feature = \"sqlx-mysql\")]\n                InnerConnection::MySql(c) => {\n                    let query = crate::driver::sqlx_mysql::sqlx_query(stmt);\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c\n                        .fetch(query)\n                        .map_ok(Into::into)\n                        .map_err(sqlx_error_to_query_err);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"sqlx-postgres\")]\n                InnerConnection::Postgres(c) => {\n                    let query = crate::driver::sqlx_postgres::sqlx_query(stmt);\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c\n                        .fetch(query)\n                        .map_ok(Into::into)\n                        .map_err(sqlx_error_to_query_err);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"sqlx-sqlite\")]\n                InnerConnection::Sqlite(c) => {\n                    let query = crate::driver::sqlx_sqlite::sqlx_query(stmt);\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c\n                        .fetch(query)\n                        .map_ok(Into::into)\n                        .map_err(sqlx_error_to_query_err);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"mock\")]\n                InnerConnection::Mock(c) => {\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c.fetch(stmt);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"proxy\")]\n                InnerConnection::Proxy(c) => {\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = futures_util::stream::once({\n                        Err(DbErr::BackendNotSupported {\n                            db: \"Proxy\",\n                            ctx: \"TransactionStream\",\n                        })\n                    });\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[allow(unreachable_patterns)]\n                _ => unreachable!(),\n            },\n        }\n        .build()\n    }\n}\n\n#[cfg(not(feature = \"sync\"))]\nimpl Stream for TransactionStream<'_> {\n    type Item = Result<QueryResult, DbErr>;\n\n    fn poll_next(\n        self: Pin<&mut Self>,\n        cx: &mut std::task::Context<'_>,\n    ) -> Poll<Option<Self::Item>> {\n        let this = self.get_mut();\n        this.with_stream_mut(|stream| Pin::new(stream).poll_next(cx))\n    }\n}\n\n#[cfg(feature = \"sync\")]\nimpl Iterator for TransactionStream<'_> {\n    type Item = Result<QueryResult, DbErr>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.with_stream_mut(|stream| stream.next())\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/tracing_spans.rs",
    "content": "//! Tracing support for database operations.\n//!\n//! This module provides utilities for instrumenting database operations\n//! with tracing spans. Enable the `tracing-spans` feature to automatically\n//! generate spans for all database operations.\n//!\n//! # Example\n//!\n//! ```toml\n//! [dependencies]\n//! sea-orm = { version = \"2.0\", features = [\"tracing-spans\"] }\n//! ```\n//!\n//! ```ignore\n//! use sea_orm::Database;\n//!\n//! // Set up a tracing subscriber\n//! tracing_subscriber::fmt()\n//!     .with_max_level(tracing::Level::INFO)\n//!     .init();\n//!\n//! // All database operations will now generate tracing spans\n//! let db = Database::connect(\"sqlite::memory:\")?;\n//! let cakes = Cake::find().all(&db)?;  // Generates a span\n//! ```\n\n#[cfg(feature = \"tracing-spans\")]\nmod inner {\n    use crate::DbBackend;\n\n    /// Database operation type, following OpenTelemetry conventions.\n    #[derive(Debug, Clone, Copy, PartialEq, Eq)]\n    pub(crate) enum DbOperation {\n        /// SELECT query\n        Select,\n        /// INSERT statement\n        Insert,\n        /// UPDATE statement\n        Update,\n        /// DELETE statement\n        Delete,\n        /// Other/unknown SQL execution\n        Execute,\n    }\n\n    impl DbOperation {\n        /// Parse the operation type from an SQL query string.\n        ///\n        /// This function is allocation-free and uses case-insensitive comparison.\n        pub fn from_sql(sql: &str) -> Self {\n            let first_word = sql.trim_start().split_whitespace().next().unwrap_or(\"\");\n            if first_word.eq_ignore_ascii_case(\"SELECT\") {\n                DbOperation::Select\n            } else if first_word.eq_ignore_ascii_case(\"INSERT\") {\n                DbOperation::Insert\n            } else if first_word.eq_ignore_ascii_case(\"UPDATE\") {\n                DbOperation::Update\n            } else if first_word.eq_ignore_ascii_case(\"DELETE\") {\n                DbOperation::Delete\n            } else {\n                DbOperation::Execute\n            }\n        }\n    }\n\n    impl std::fmt::Display for DbOperation {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            match self {\n                DbOperation::Select => write!(f, \"SELECT\"),\n                DbOperation::Insert => write!(f, \"INSERT\"),\n                DbOperation::Update => write!(f, \"UPDATE\"),\n                DbOperation::Delete => write!(f, \"DELETE\"),\n                DbOperation::Execute => write!(f, \"EXECUTE\"),\n            }\n        }\n    }\n\n    /// Get the OpenTelemetry system name from DbBackend.\n    pub(crate) fn db_system_name(backend: DbBackend) -> &'static str {\n        match backend {\n            DbBackend::Postgres => \"postgresql\",\n            DbBackend::MySql => \"mysql\",\n            DbBackend::Sqlite => \"sqlite\",\n        }\n    }\n\n    /// Record query result on a span (success/failure status and error message).\n    pub(crate) fn record_query_result<T, E: std::fmt::Display>(\n        span: &tracing::Span,\n        result: &Result<T, E>,\n    ) {\n        match result {\n            Ok(_) => {\n                span.record(\"otel.status_code\", \"OK\");\n            }\n            Err(e) => {\n                span.record(\"otel.status_code\", \"ERROR\");\n                span.record(\"exception.message\", tracing::field::display(e));\n            }\n        }\n    }\n}\n\n#[cfg(feature = \"tracing-spans\")]\npub(crate) use inner::*;\n\n/// Create a tracing span for database operations.\n///\n/// Arguments:\n/// - `$name`: Span name (e.g., \"sea_orm.execute\", \"sea_orm.query_one\")\n/// - `$backend`: DbBackend value\n/// - `$sql`: SQL statement string (used for operation parsing)\n///\n/// Note: `db.statement` is set to Empty. Call `span.record(\"db.statement\", sql)`\n/// separately if the query is parameterized (safe to log).\n#[cfg(feature = \"tracing-spans\")]\nmacro_rules! db_span {\n    ($name:expr, $backend:expr, $sql:expr) => {{\n        let sql: &str = $sql;\n        let op = $crate::database::tracing_spans::DbOperation::from_sql(sql);\n        ::tracing::info_span!(\n            $name,\n            otel.kind = \"client\",\n            db.system = $crate::database::tracing_spans::db_system_name($backend),\n            db.operation = %op,\n            db.statement = ::tracing::field::Empty,\n            otel.status_code = ::tracing::field::Empty,\n            exception.message = ::tracing::field::Empty,\n        )\n    }};\n}\n\n#[cfg(feature = \"tracing-spans\")]\npub(crate) use db_span;\n\n/// Execute a future and wrap it in a tracing span when `tracing-spans` is enabled.\n///\n/// When the feature is disabled, this macro simply awaits the future with zero overhead.\n///\n/// # Arguments\n/// - `$name`: span name (e.g., \"sea_orm.execute\")\n/// - `$backend`: DbBackend\n/// - `$sql`: &str used for db.operation parsing\n/// - `record_stmt`: whether to record `db.statement`\n/// - `$fut`: the future to execute\nmacro_rules! with_db_span {\n    ($name:expr, $backend:expr, $sql:expr, record_stmt = $record_stmt:expr, $fut:expr) => {{\n        #[cfg(all(feature = \"tracing-spans\", not(feature = \"sync\")))]\n        {\n            let span = $crate::database::tracing_spans::db_span!($name, $backend, $sql);\n            if $record_stmt {\n                span.record(\"db.statement\", $sql);\n            }\n            let result = ::tracing::Instrument::instrument($fut, span.clone());\n            $crate::database::tracing_spans::record_query_result(&span, &result);\n            result\n        }\n        #[cfg(all(feature = \"tracing-spans\", feature = \"sync\"))]\n        {\n            let span = $crate::database::tracing_spans::db_span!($name, $backend, $sql);\n            if $record_stmt {\n                span.record(\"db.statement\", $sql);\n            }\n            span.in_scope($fut)\n        }\n        #[cfg(not(feature = \"tracing-spans\"))]\n        {\n            $fut\n        }\n    }};\n}\n\npub(crate) use with_db_span;\n\n#[cfg(feature = \"tracing-spans\")]\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_db_operation_from_sql() {\n        assert_eq!(\n            DbOperation::from_sql(\"SELECT * FROM users\"),\n            DbOperation::Select\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"  SELECT * FROM users\"),\n            DbOperation::Select\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"select * from users\"),\n            DbOperation::Select\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"INSERT INTO users\"),\n            DbOperation::Insert\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"UPDATE users SET\"),\n            DbOperation::Update\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"DELETE FROM users\"),\n            DbOperation::Delete\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"CREATE TABLE users\"),\n            DbOperation::Execute\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"DROP TABLE users\"),\n            DbOperation::Execute\n        );\n    }\n\n    #[test]\n    fn test_db_system_name() {\n        assert_eq!(db_system_name(DbBackend::Postgres), \"postgresql\");\n        assert_eq!(db_system_name(DbBackend::MySql), \"mysql\");\n        assert_eq!(db_system_name(DbBackend::Sqlite), \"sqlite\");\n    }\n\n    #[test]\n    fn test_db_operation_display() {\n        assert_eq!(DbOperation::Select.to_string(), \"SELECT\");\n        assert_eq!(DbOperation::Insert.to_string(), \"INSERT\");\n        assert_eq!(DbOperation::Update.to_string(), \"UPDATE\");\n        assert_eq!(DbOperation::Delete.to_string(), \"DELETE\");\n        assert_eq!(DbOperation::Execute.to_string(), \"EXECUTE\");\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/database/transaction.rs",
    "content": "#![allow(unused_assignments)]\nuse std::sync::Arc;\n\n#[cfg(feature = \"sqlx-dep\")]\nuse sqlx::TransactionManager;\nuse std::sync::Mutex;\nuse tracing::instrument;\n\nuse crate::{\n    AccessMode, ConnectionTrait, DbBackend, DbErr, ExecResult, InnerConnection, IsolationLevel,\n    QueryResult, SqliteTransactionMode, Statement, StreamTrait, TransactionOptions,\n    TransactionSession, TransactionStream, TransactionTrait, debug_print, error::*,\n};\n#[cfg(feature = \"sqlx-dep\")]\nuse crate::{sqlx_error_to_exec_err, sqlx_error_to_query_err};\n\n/// Defines a database transaction, whether it is an open transaction and the type of\n/// backend to use.\n/// Under the hood, a Transaction is just a wrapper for a connection where\n/// START TRANSACTION has been executed.\npub struct DatabaseTransaction {\n    conn: Arc<Mutex<InnerConnection>>,\n    backend: DbBackend,\n    open: bool,\n    metric_callback: Option<crate::metric::Callback>,\n}\n\nimpl std::fmt::Debug for DatabaseTransaction {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"DatabaseTransaction\")\n    }\n}\n\nimpl DatabaseTransaction {\n    #[instrument(level = \"trace\", skip(metric_callback))]\n    pub(crate) fn begin(\n        conn: Arc<Mutex<InnerConnection>>,\n        backend: DbBackend,\n        metric_callback: Option<crate::metric::Callback>,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n        sqlite_transaction_mode: Option<SqliteTransactionMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        let res = DatabaseTransaction {\n            conn,\n            backend,\n            open: true,\n            metric_callback,\n        };\n\n        let begin_result: Result<(), DbErr> = super::tracing_spans::with_db_span!(\n            \"sea_orm.begin\",\n            backend,\n            \"BEGIN\",\n            record_stmt = false,\n            {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *res.conn.lock();\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *res.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(c) => {\n                        // in MySQL SET TRANSACTION operations must be executed before transaction start\n                        crate::driver::sqlx_mysql::set_transaction_config(\n                            c,\n                            isolation_level,\n                            access_mode,\n                        )?;\n                        <sqlx::MySql as sqlx::Database>::TransactionManager::begin(c, None)\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(c) => {\n                        <sqlx::Postgres as sqlx::Database>::TransactionManager::begin(c, None)\n                            .map_err(sqlx_error_to_query_err)?;\n                        // in PostgreSQL SET TRANSACTION operations must be executed inside transaction\n                        crate::driver::sqlx_postgres::set_transaction_config(\n                            c,\n                            isolation_level,\n                            access_mode,\n                        )\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(c) => {\n                        crate::driver::sqlx_sqlite::set_transaction_config(\n                            c,\n                            isolation_level,\n                            access_mode,\n                        )?;\n                        let depth = <sqlx::Sqlite as sqlx::Database>::TransactionManager::get_transaction_depth(c);\n                        let statement = if depth == 0 {\n                            sqlite_transaction_mode.map(|mode| {\n                                std::borrow::Cow::from(format!(\"BEGIN {}\", mode.sqlite_keyword()))\n                            })\n                        } else {\n                            // Nested transaction uses SAVEPOINT; the mode only applies to the top-level BEGIN\n                            None\n                        };\n                        <sqlx::Sqlite as sqlx::Database>::TransactionManager::begin(c, statement)\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(c) => c.begin(sqlite_transaction_mode),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(c) => {\n                        c.begin();\n                        Ok(())\n                    }\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(c) => {\n                        c.begin();\n                        Ok(())\n                    }\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        );\n\n        begin_result?;\n        Ok(res)\n    }\n\n    /// Runs a transaction to completion passing through the result.\n    /// Rolling back the transaction on encountering an error.\n    #[instrument(level = \"trace\", skip(callback))]\n    pub(crate) fn run<F, T, E>(self, callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'b> FnOnce(&'b DatabaseTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        let res = callback(&self).map_err(TransactionError::Transaction);\n        if res.is_ok() {\n            self.commit().map_err(TransactionError::Connection)?;\n        } else {\n            self.rollback().map_err(TransactionError::Connection)?;\n        }\n        res\n    }\n\n    /// Commit a transaction\n    #[instrument(level = \"trace\")]\n    #[allow(unreachable_code, unused_mut)]\n    pub fn commit(mut self) -> Result<(), DbErr> {\n        let result: Result<(), DbErr> = super::tracing_spans::with_db_span!(\n            \"sea_orm.commit\",\n            self.backend,\n            \"COMMIT\",\n            record_stmt = false,\n            {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *self.conn.lock();\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(c) => {\n                        <sqlx::MySql as sqlx::Database>::TransactionManager::commit(c)\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(c) => {\n                        <sqlx::Postgres as sqlx::Database>::TransactionManager::commit(c)\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(c) => {\n                        <sqlx::Sqlite as sqlx::Database>::TransactionManager::commit(c)\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(c) => c.commit(),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(c) => {\n                        c.commit();\n                        Ok(())\n                    }\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(c) => {\n                        c.commit();\n                        Ok(())\n                    }\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        );\n\n        result?;\n        self.open = false; // read by start_rollback\n        Ok(())\n    }\n\n    /// Rolls back a transaction explicitly\n    #[instrument(level = \"trace\")]\n    #[allow(unreachable_code, unused_mut)]\n    pub fn rollback(mut self) -> Result<(), DbErr> {\n        let result: Result<(), DbErr> = super::tracing_spans::with_db_span!(\n            \"sea_orm.rollback\",\n            self.backend,\n            \"ROLLBACK\",\n            record_stmt = false,\n            {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *self.conn.lock();\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(c) => {\n                        <sqlx::MySql as sqlx::Database>::TransactionManager::rollback(c)\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(c) => {\n                        <sqlx::Postgres as sqlx::Database>::TransactionManager::rollback(c)\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(c) => {\n                        <sqlx::Sqlite as sqlx::Database>::TransactionManager::rollback(c)\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(c) => c.rollback(),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(c) => {\n                        c.rollback();\n                        Ok(())\n                    }\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(c) => {\n                        c.rollback();\n                        Ok(())\n                    }\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        );\n\n        result?;\n        self.open = false; // read by start_rollback\n        Ok(())\n    }\n\n    // the rollback is queued and will be performed on next operation, like returning the connection to the pool\n    #[instrument(level = \"trace\")]\n    fn start_rollback(&mut self) -> Result<(), DbErr> {\n        if self.open {\n            if let Some(mut conn) = self.conn.try_lock().ok() {\n                match &mut *conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(c) => {\n                        <sqlx::MySql as sqlx::Database>::TransactionManager::start_rollback(c);\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(c) => {\n                        <sqlx::Postgres as sqlx::Database>::TransactionManager::start_rollback(c);\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(c) => {\n                        <sqlx::Sqlite as sqlx::Database>::TransactionManager::start_rollback(c);\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(c) => {\n                        c.start_rollback()?;\n                    }\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(c) => {\n                        c.rollback();\n                    }\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(c) => {\n                        c.start_rollback();\n                    }\n                    #[allow(unreachable_patterns)]\n                    _ => return Err(conn_err(\"Disconnected\")),\n                }\n            } else {\n                //this should never happen\n                return Err(conn_err(\"Dropping a locked Transaction\"));\n            }\n        }\n        Ok(())\n    }\n}\n\nimpl TransactionSession for DatabaseTransaction {\n    fn commit(self) -> Result<(), DbErr> {\n        self.commit()\n    }\n\n    fn rollback(self) -> Result<(), DbErr> {\n        self.rollback()\n    }\n}\n\nimpl Drop for DatabaseTransaction {\n    fn drop(&mut self) {\n        self.start_rollback().expect(\"Fail to rollback transaction\");\n    }\n}\n\nimpl ConnectionTrait for DatabaseTransaction {\n    fn get_database_backend(&self) -> DbBackend {\n        // this way we don't need to lock just to know the backend\n        self.backend\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.execute\",\n            self.backend,\n            stmt.sql.as_str(),\n            record_stmt = true,\n            {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *self.conn.lock();\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(conn) => {\n                        let query = crate::driver::sqlx_mysql::sqlx_query(&stmt);\n                        let conn: &mut sqlx::MySqlConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            query.execute(conn).map(Into::into)\n                        })\n                        .map_err(sqlx_error_to_exec_err)\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(conn) => {\n                        let query = crate::driver::sqlx_postgres::sqlx_query(&stmt);\n                        let conn: &mut sqlx::PgConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            query.execute(conn).map(Into::into)\n                        })\n                        .map_err(sqlx_error_to_exec_err)\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(conn) => {\n                        let query = crate::driver::sqlx_sqlite::sqlx_query(&stmt);\n                        let conn: &mut sqlx::SqliteConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            query.execute(conn).map(Into::into)\n                        })\n                        .map_err(sqlx_error_to_exec_err)\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(conn) => conn.execute(stmt, &self.metric_callback),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(conn) => conn.execute(stmt),\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(conn) => conn.execute(stmt),\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", sql);\n\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.execute_unprepared\",\n            self.backend,\n            sql,\n            record_stmt = false,\n            {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *self.conn.lock();\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(conn) => {\n                        let conn: &mut sqlx::MySqlConnection = &mut *conn;\n                        sqlx::Executor::execute(conn, sql)\n                            .map(Into::into)\n                            .map_err(sqlx_error_to_exec_err)\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(conn) => {\n                        let conn: &mut sqlx::PgConnection = &mut *conn;\n                        sqlx::Executor::execute(conn, sql)\n                            .map(Into::into)\n                            .map_err(sqlx_error_to_exec_err)\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(conn) => {\n                        let conn: &mut sqlx::SqliteConnection = &mut *conn;\n                        sqlx::Executor::execute(conn, sql)\n                            .map(Into::into)\n                            .map_err(sqlx_error_to_exec_err)\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(conn) => conn.execute_unprepared(sql),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(conn) => {\n                        let db_backend = conn.get_database_backend();\n                        let stmt = Statement::from_string(db_backend, sql);\n                        conn.execute(stmt)\n                    }\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(conn) => {\n                        let db_backend = conn.get_database_backend();\n                        let stmt = Statement::from_string(db_backend, sql);\n                        conn.execute(stmt)\n                    }\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.query_one\",\n            self.backend,\n            stmt.sql.as_str(),\n            record_stmt = true,\n            {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *self.conn.lock();\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(conn) => {\n                        let query = crate::driver::sqlx_mysql::sqlx_query(&stmt);\n                        let conn: &mut sqlx::MySqlConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            crate::sqlx_map_err_ignore_not_found(\n                                query.fetch_one(conn).map(|row| Some(row.into())),\n                            )\n                        })\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(conn) => {\n                        let query = crate::driver::sqlx_postgres::sqlx_query(&stmt);\n                        let conn: &mut sqlx::PgConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            crate::sqlx_map_err_ignore_not_found(\n                                query.fetch_one(conn).map(|row| Some(row.into())),\n                            )\n                        })\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(conn) => {\n                        let query = crate::driver::sqlx_sqlite::sqlx_query(&stmt);\n                        let conn: &mut sqlx::SqliteConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            crate::sqlx_map_err_ignore_not_found(\n                                query.fetch_one(conn).map(|row| Some(row.into())),\n                            )\n                        })\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(conn) => conn.query_one(stmt, &self.metric_callback),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(conn) => conn.query_one(stmt),\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(conn) => conn.query_one(stmt),\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.query_all\",\n            self.backend,\n            stmt.sql.as_str(),\n            record_stmt = true,\n            {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *self.conn.lock();\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(conn) => {\n                        let query = crate::driver::sqlx_mysql::sqlx_query(&stmt);\n                        let conn: &mut sqlx::MySqlConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            query\n                                .fetch_all(conn)\n                                .map(|rows| rows.into_iter().map(|r| r.into()).collect())\n                                .map_err(sqlx_error_to_query_err)\n                        })\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(conn) => {\n                        let query = crate::driver::sqlx_postgres::sqlx_query(&stmt);\n                        let conn: &mut sqlx::PgConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            query\n                                .fetch_all(conn)\n                                .map(|rows| rows.into_iter().map(|r| r.into()).collect())\n                                .map_err(sqlx_error_to_query_err)\n                        })\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(conn) => {\n                        let query = crate::driver::sqlx_sqlite::sqlx_query(&stmt);\n                        let conn: &mut sqlx::SqliteConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            query\n                                .fetch_all(conn)\n                                .map(|rows| rows.into_iter().map(|r| r.into()).collect())\n                                .map_err(sqlx_error_to_query_err)\n                        })\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(conn) => conn.query_all(stmt, &self.metric_callback),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(conn) => conn.query_all(stmt),\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(conn) => conn.query_all(stmt),\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n}\n\nimpl StreamTrait for DatabaseTransaction {\n    type Stream<'a> = TransactionStream<'a>;\n\n    fn get_database_backend(&self) -> DbBackend {\n        self.backend\n    }\n\n    #[instrument(level = \"trace\")]\n    fn stream_raw<'a>(&'a self, stmt: Statement) -> Result<Self::Stream<'a>, DbErr> {\n        ({\n            #[cfg(not(feature = \"sync\"))]\n            let conn = self.conn.lock();\n            #[cfg(feature = \"sync\")]\n            let conn = self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n            Ok(crate::TransactionStream::build(\n                conn,\n                stmt,\n                self.metric_callback.clone(),\n            ))\n        })\n    }\n}\n\nimpl TransactionTrait for DatabaseTransaction {\n    type Transaction = DatabaseTransaction;\n\n    #[instrument(level = \"trace\")]\n    fn begin(&self) -> Result<DatabaseTransaction, DbErr> {\n        DatabaseTransaction::begin(\n            Arc::clone(&self.conn),\n            self.backend,\n            self.metric_callback.clone(),\n            None,\n            None,\n            None,\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    fn begin_with_config(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        DatabaseTransaction::begin(\n            Arc::clone(&self.conn),\n            self.backend,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n            None,\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    fn begin_with_options(\n        &self,\n        options: TransactionOptions,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        DatabaseTransaction::begin(\n            Arc::clone(&self.conn),\n            self.backend,\n            self.metric_callback.clone(),\n            options.isolation_level,\n            options.access_mode,\n            options.sqlite_transaction_mode,\n        )\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back.\n    /// Otherwise, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(_callback))]\n    fn transaction<F, T, E>(&self, _callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(&'c DatabaseTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        let transaction = self.begin().map_err(TransactionError::Connection)?;\n        transaction.run(_callback)\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back.\n    /// Otherwise, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(_callback))]\n    fn transaction_with_config<F, T, E>(\n        &self,\n        _callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(&'c DatabaseTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        let transaction = self\n            .begin_with_config(isolation_level, access_mode)\n            .map_err(TransactionError::Connection)?;\n        transaction.run(_callback)\n    }\n}\n\n/// Defines errors for handling transaction failures\n#[derive(Debug)]\npub enum TransactionError<E> {\n    /// A Database connection error\n    Connection(DbErr),\n    /// An error occurring when doing database transactions\n    Transaction(E),\n}\n\nimpl<E> std::fmt::Display for TransactionError<E>\nwhere\n    E: std::fmt::Display + std::fmt::Debug,\n{\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            TransactionError::Connection(e) => std::fmt::Display::fmt(e, f),\n            TransactionError::Transaction(e) => std::fmt::Display::fmt(e, f),\n        }\n    }\n}\n\nimpl<E> std::error::Error for TransactionError<E> where E: std::fmt::Display + std::fmt::Debug {}\n\nimpl<E> From<DbErr> for TransactionError<E>\nwhere\n    E: std::fmt::Display + std::fmt::Debug,\n{\n    fn from(e: DbErr) -> Self {\n        Self::Connection(e)\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/docs.rs",
    "content": "//! 1. Async\n//!\n//!     Relying on [SQLx](https://github.com/launchbadge/sqlx), SeaORM is a new library with support from day 1.\n//!\n//! ```\n//! # use sea_orm::{error::*, tests_cfg::*, *};\n//! #\n//! # #[cfg(all(feature = \"mock\", not(feature = \"sync\")))]\n//! # pub fn main() -> Result<(), DbErr> {\n//! #\n//! # let db = MockDatabase::new(DbBackend::Postgres)\n//! #     .append_query_results([\n//! #         [cake::Model {\n//! #             id: 1,\n//! #             name: \"New York Cheese\".to_owned(),\n//! #         }\n//! #         .into_mock_row()],\n//! #         [fruit::Model {\n//! #             id: 1,\n//! #             name: \"Apple\".to_owned(),\n//! #             cake_id: Some(1),\n//! #         }\n//! #         .into_mock_row()],\n//! #     ])\n//! #     .into_connection();\n//! #\n//! // execute multiple queries in parallel\n//! let cakes_and_fruits: (Vec<cake::Model>, Vec<fruit::Model>) =\n//!     futures_util::future::try_join(Cake::find().all(&db), Fruit::find().all(&db))?;\n//! # assert_eq!(\n//! #     cakes_and_fruits,\n//! #     (\n//! #         vec![cake::Model {\n//! #             id: 1,\n//! #             name: \"New York Cheese\".to_owned(),\n//! #         }],\n//! #         vec![fruit::Model {\n//! #             id: 1,\n//! #             name: \"Apple\".to_owned(),\n//! #             cake_id: Some(1),\n//! #         }]\n//! #     )\n//! # );\n//! # assert_eq!(\n//! #     db.into_transaction_log(),\n//! #     [\n//! #         Transaction::from_sql_and_values(\n//! #             DbBackend::Postgres,\n//! #             r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n//! #             []\n//! #         ),\n//! #         Transaction::from_sql_and_values(\n//! #             DbBackend::Postgres,\n//! #             r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\"\"#,\n//! #             []\n//! #         ),\n//! #     ]\n//! # );\n//! # Ok(())\n//! # }\n//! # #[cfg(all(feature = \"mock\", feature = \"sync\"))]\n//! # fn main() {}\n//! ```\n//!\n//! 2. Dynamic\n//!\n//!     Built upon [SeaQuery](https://github.com/SeaQL/sea-query), SeaORM allows you to build complex queries without 'fighting the ORM'.\n//!\n//! ```\n//! # use sea_query::Query;\n//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};\n//! # fn function(db: DbConn) -> Result<(), DbErr> {\n//! // build subquery with ease\n//! let cakes_with_filling: Vec<cake::Model> = cake::Entity::find()\n//!     .filter(\n//!         Condition::any().add(\n//!             cake::Column::Id.in_subquery(\n//!                 Query::select()\n//!                     .column(cake_filling::Column::CakeId)\n//!                     .from(cake_filling::Entity)\n//!                     .to_owned(),\n//!             ),\n//!         ),\n//!     )\n//!     .all(&db)\n//!     ?;\n//!\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! 3. Testable\n//!\n//!     Use mock connections to write unit tests for your logic.\n//!\n//! ```\n//! # use sea_orm::{error::*, entity::*, query::*, tests_cfg::*, DbConn, MockDatabase, Transaction, DbBackend};\n//! # fn function(db: DbConn) -> Result<(), DbErr> {\n//! // Setup mock connection\n//! let db = MockDatabase::new(DbBackend::Postgres)\n//!     .append_query_results([\n//!         [\n//!             cake::Model {\n//!                 id: 1,\n//!                 name: \"New York Cheese\".to_owned(),\n//!             },\n//!         ],\n//!     ])\n//!     .into_connection();\n//!\n//! // Perform your application logic\n//! assert_eq!(\n//!     cake::Entity::find().one(&db)?,\n//!     Some(cake::Model {\n//!         id: 1,\n//!         name: \"New York Cheese\".to_owned(),\n//!     })\n//! );\n//!\n//! // Compare it against the expected transaction log\n//! assert_eq!(\n//!     db.into_transaction_log(),\n//!     [\n//!         Transaction::from_sql_and_values(\n//!             DbBackend::Postgres,\n//!             r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" LIMIT $1\"#,\n//!             [1u64.into()]\n//!         ),\n//!     ]\n//! );\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! 4. Service Oriented\n//!\n//!     Quickly build services that join, filter, sort and paginate data in APIs.\n//!\n//! ```ignore\n//! #[get(\"/?<page>&<posts_per_page>\")]\n//! fn list(\n//!     conn: Connection<Db>,\n//!     page: Option<usize>,\n//!     per_page: Option<usize>,\n//! ) -> Template {\n//!     // Set page number and items per page\n//!     let page = page.unwrap_or(1);\n//!     let per_page = per_page.unwrap_or(10);\n//!\n//!     // Setup paginator\n//!     let paginator = Post::find()\n//!         .order_by_asc(post::Column::Id)\n//!         .paginate(&conn, per_page);\n//!     let num_pages = paginator.num_pages().unwrap();\n//!\n//!     // Fetch paginated posts\n//!     let posts = paginator\n//!         .fetch_page(page - 1)\n//!         \n//!         .expect(\"could not retrieve posts\");\n//!\n//!     Template::render(\n//!         \"index\",\n//!         context! {\n//!             page: page,\n//!             per_page: per_page,\n//!             posts: posts,\n//!             num_pages: num_pages,\n//!         },\n//!     )\n//! }\n//! ```\n"
  },
  {
    "path": "sea-orm-sync/src/driver/mock.rs",
    "content": "use crate::{\n    DatabaseConnection, DatabaseConnectionType, DbBackend, ExecResult, MockDatabase, QueryResult,\n    Statement, Transaction, debug_print, error::*,\n};\nuse std::{\n    fmt::Debug,\n    pin::Pin,\n    sync::{\n        Arc, Mutex,\n        atomic::{AtomicUsize, Ordering},\n    },\n};\nuse tracing::instrument;\n\n#[cfg(not(feature = \"sync\"))]\ntype PinBoxStream = Pin<Box<dyn Stream<Item = Result<QueryResult, DbErr>>>>;\n#[cfg(feature = \"sync\")]\ntype PinBoxStream = Box<dyn Iterator<Item = Result<QueryResult, DbErr>>>;\n\n/// Defines a database driver for the [MockDatabase]\n#[derive(Debug)]\npub struct MockDatabaseConnector;\n\n/// Defines a connection for the [MockDatabase]\n#[derive(Debug)]\npub struct MockDatabaseConnection {\n    execute_counter: AtomicUsize,\n    query_counter: AtomicUsize,\n    mocker: Mutex<Box<dyn MockDatabaseTrait>>,\n}\n\n/// A Trait for any type wanting to perform operations on the [MockDatabase]\npub trait MockDatabaseTrait: Debug {\n    /// Execute a statement in the [MockDatabase]\n    fn execute(&mut self, counter: usize, stmt: Statement) -> Result<ExecResult, DbErr>;\n\n    /// Execute a SQL query in the [MockDatabase]\n    fn query(&mut self, counter: usize, stmt: Statement) -> Result<Vec<QueryResult>, DbErr>;\n\n    /// Create a transaction that can be committed atomically\n    fn begin(&mut self);\n\n    /// Commit a successful transaction atomically into the [MockDatabase]\n    fn commit(&mut self);\n\n    /// Roll back a transaction since errors were encountered\n    fn rollback(&mut self);\n\n    /// Get all logs from a [MockDatabase] and return a [Transaction]\n    fn drain_transaction_log(&mut self) -> Vec<Transaction>;\n\n    /// Get the backend being used in the [MockDatabase]\n    fn get_database_backend(&self) -> DbBackend;\n\n    /// Ping the [MockDatabase]\n    fn ping(&self) -> Result<(), DbErr>;\n}\n\nimpl MockDatabaseConnector {\n    /// Check if the database URI given and the [DatabaseBackend](crate::DatabaseBackend) selected are the same\n    #[allow(unused_variables)]\n    pub fn accepts(string: &str) -> bool {\n        #[cfg(feature = \"sqlx-mysql\")]\n        if DbBackend::MySql.is_prefix_of(string) {\n            return true;\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        if DbBackend::Postgres.is_prefix_of(string) {\n            return true;\n        }\n        #[cfg(feature = \"sqlx-sqlite\")]\n        if DbBackend::Sqlite.is_prefix_of(string) {\n            return true;\n        }\n        #[cfg(feature = \"rusqlite\")]\n        if DbBackend::Sqlite.is_prefix_of(string) {\n            return true;\n        }\n        false\n    }\n\n    /// Connect to the [MockDatabase]\n    #[allow(unused_variables)]\n    #[instrument(level = \"trace\")]\n    pub fn connect(string: &str) -> Result<DatabaseConnection, DbErr> {\n        macro_rules! connect_mock_db {\n            ( $syntax: expr ) => {\n                Ok(DatabaseConnectionType::MockDatabaseConnection(Arc::new(\n                    MockDatabaseConnection::new(MockDatabase::new($syntax)),\n                ))\n                .into())\n            };\n        }\n\n        #[cfg(feature = \"sqlx-mysql\")]\n        if crate::SqlxMySqlConnector::accepts(string) {\n            return connect_mock_db!(DbBackend::MySql);\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        if crate::SqlxPostgresConnector::accepts(string) {\n            return connect_mock_db!(DbBackend::Postgres);\n        }\n        #[cfg(feature = \"sqlx-sqlite\")]\n        if crate::SqlxSqliteConnector::accepts(string) {\n            return connect_mock_db!(DbBackend::Sqlite);\n        }\n        #[cfg(feature = \"rusqlite\")]\n        if crate::driver::rusqlite::RusqliteConnector::accepts(string) {\n            return connect_mock_db!(DbBackend::Sqlite);\n        }\n        connect_mock_db!(DbBackend::Postgres)\n    }\n}\n\nimpl MockDatabaseConnection {\n    /// Create a connection to the [MockDatabase]\n    pub fn new<M>(m: M) -> Self\n    where\n        M: MockDatabaseTrait,\n        M: 'static,\n    {\n        Self {\n            execute_counter: AtomicUsize::new(0),\n            query_counter: AtomicUsize::new(0),\n            mocker: Mutex::new(Box::new(m)),\n        }\n    }\n\n    pub(crate) fn get_mocker_mutex(&self) -> &Mutex<Box<dyn MockDatabaseTrait>> {\n        &self.mocker\n    }\n\n    /// Get the [DatabaseBackend](crate::DatabaseBackend) being used by the [MockDatabase]\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the lock cannot be acquired.\n    pub fn get_database_backend(&self) -> DbBackend {\n        self.mocker\n            .lock()\n            .expect(\"Fail to acquire mocker\")\n            .get_database_backend()\n    }\n\n    /// Execute the SQL statement in the [MockDatabase]\n    #[instrument(level = \"trace\")]\n    pub fn execute(&self, statement: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", statement);\n        let counter = self.execute_counter.fetch_add(1, Ordering::SeqCst);\n        self.mocker\n            .lock()\n            .map_err(exec_err)?\n            .execute(counter, statement)\n    }\n\n    /// Return one [QueryResult] if the query was successful\n    #[instrument(level = \"trace\")]\n    pub fn query_one(&self, statement: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", statement);\n        let counter = self.query_counter.fetch_add(1, Ordering::SeqCst);\n        let result = self\n            .mocker\n            .lock()\n            .map_err(query_err)?\n            .query(counter, statement)?;\n        Ok(result.into_iter().next())\n    }\n\n    /// Return all [QueryResult]s if the query was successful\n    #[instrument(level = \"trace\")]\n    pub fn query_all(&self, statement: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug_print!(\"{}\", statement);\n        let counter = self.query_counter.fetch_add(1, Ordering::SeqCst);\n        self.mocker\n            .lock()\n            .map_err(query_err)?\n            .query(counter, statement)\n    }\n\n    /// Return [QueryResult]s  from a multi-query operation\n    #[instrument(level = \"trace\")]\n    pub fn fetch(&self, statement: &Statement) -> PinBoxStream {\n        #[cfg(not(feature = \"sync\"))]\n        {\n            match self.query_all(statement.clone()) {\n                Ok(v) => Box::new(futures_util::stream::iter(v.into_iter().map(Ok))),\n                Err(e) => Box::new(futures_util::stream::iter(Some(Err(e)).into_iter())),\n            }\n        }\n        #[cfg(feature = \"sync\")]\n        {\n            match self.query_all(statement.clone()) {\n                Ok(v) => Box::new(v.into_iter().map(Ok)),\n                Err(e) => Box::new(Some(Err(e)).into_iter()),\n            }\n        }\n    }\n\n    /// Create a statement block  of SQL statements that execute together.\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the lock cannot be acquired.\n    #[instrument(level = \"trace\")]\n    pub fn begin(&self) {\n        self.mocker\n            .lock()\n            .expect(\"Failed to acquire mocker\")\n            .begin()\n    }\n\n    /// Commit a transaction atomically to the database\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the lock cannot be acquired.\n    #[instrument(level = \"trace\")]\n    pub fn commit(&self) {\n        self.mocker\n            .lock()\n            .expect(\"Failed to acquire mocker\")\n            .commit()\n    }\n\n    /// Roll back a faulty transaction\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the lock cannot be acquired.\n    #[instrument(level = \"trace\")]\n    pub fn rollback(&self) {\n        self.mocker\n            .lock()\n            .expect(\"Failed to acquire mocker\")\n            .rollback()\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub fn ping(&self) -> Result<(), DbErr> {\n        self.mocker.lock().map_err(query_err)?.ping()\n    }\n}\n\nimpl\n    From<(\n        Arc<crate::MockDatabaseConnection>,\n        Statement,\n        Option<crate::metric::Callback>,\n    )> for crate::QueryStream\n{\n    fn from(\n        (conn, stmt, metric_callback): (\n            Arc<crate::MockDatabaseConnection>,\n            Statement,\n            Option<crate::metric::Callback>,\n        ),\n    ) -> Self {\n        crate::QueryStream::build(stmt, crate::InnerConnection::Mock(conn), metric_callback)\n    }\n}\n\nimpl crate::DatabaseTransaction {\n    pub(crate) fn new_mock(\n        inner: Arc<crate::MockDatabaseConnection>,\n        metric_callback: Option<crate::metric::Callback>,\n    ) -> Result<crate::DatabaseTransaction, DbErr> {\n        use std::sync::Mutex;\n        let backend = inner.get_database_backend();\n        Self::begin(\n            Arc::new(Mutex::new(crate::InnerConnection::Mock(inner))),\n            backend,\n            metric_callback,\n            None,\n            None,\n            None,\n        )\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/driver/mod.rs",
    "content": "#[cfg(feature = \"mock\")]\nmod mock;\n#[cfg(feature = \"proxy\")]\nmod proxy;\n#[cfg(feature = \"rusqlite\")]\npub(crate) mod rusqlite;\n#[cfg(any(feature = \"sqlx-sqlite\", feature = \"rusqlite\"))]\nmod sqlite;\n#[cfg(feature = \"sqlx-dep\")]\nmod sqlx_common;\n#[cfg(feature = \"sqlx-mysql\")]\npub(crate) mod sqlx_mysql;\n#[cfg(feature = \"sqlx-postgres\")]\npub(crate) mod sqlx_postgres;\n#[cfg(feature = \"sqlx-sqlite\")]\npub(crate) mod sqlx_sqlite;\n\n#[cfg(feature = \"mock\")]\npub use mock::*;\n#[cfg(feature = \"proxy\")]\npub use proxy::*;\n#[cfg(feature = \"sqlx-dep\")]\npub(crate) use sqlx_common::*;\n#[cfg(feature = \"sqlx-mysql\")]\npub use sqlx_mysql::*;\n#[cfg(feature = \"sqlx-postgres\")]\npub use sqlx_postgres::*;\n#[cfg(feature = \"sqlx-sqlite\")]\npub use sqlx_sqlite::*;\n"
  },
  {
    "path": "sea-orm-sync/src/driver/proxy.rs",
    "content": "use crate::{\n    DatabaseConnection, DatabaseConnectionType, DbBackend, ExecResult, ProxyDatabaseTrait,\n    QueryResult, Statement, debug_print, error::*,\n};\nuse std::{fmt::Debug, sync::Arc};\nuse tracing::instrument;\n\n/// Defines a database driver for the [ProxyDatabase]\n#[derive(Debug)]\npub struct ProxyDatabaseConnector;\n\n/// Defines a connection for the [ProxyDatabase]\n#[derive(Debug)]\npub struct ProxyDatabaseConnection {\n    db_backend: DbBackend,\n    proxy: Arc<Box<dyn ProxyDatabaseTrait>>,\n}\n\nimpl ProxyDatabaseConnector {\n    /// Check if the database URI given and the [DatabaseBackend](crate::DatabaseBackend) selected are the same\n    #[allow(unused_variables)]\n    pub fn accepts(string: &str) -> bool {\n        // As this is a proxy database, it accepts any URI\n        true\n    }\n\n    /// Connect to the [ProxyDatabase]\n    #[allow(unused_variables)]\n    #[instrument(level = \"trace\")]\n    pub fn connect(\n        db_type: DbBackend,\n        func: Arc<Box<dyn ProxyDatabaseTrait>>,\n    ) -> Result<DatabaseConnection, DbErr> {\n        Ok(\n            DatabaseConnectionType::ProxyDatabaseConnection(Arc::new(\n                ProxyDatabaseConnection::new(db_type, func),\n            ))\n            .into(),\n        )\n    }\n}\n\nimpl ProxyDatabaseConnection {\n    /// Create a connection to the [ProxyDatabase]\n    pub fn new(db_backend: DbBackend, funcs: Arc<Box<dyn ProxyDatabaseTrait>>) -> Self {\n        Self {\n            db_backend,\n            proxy: funcs.to_owned(),\n        }\n    }\n\n    /// Get the [DatabaseBackend](crate::DatabaseBackend) being used by the [ProxyDatabase]\n    pub fn get_database_backend(&self) -> DbBackend {\n        self.db_backend\n    }\n\n    /// Execute the SQL statement in the [ProxyDatabase]\n    #[instrument(level = \"trace\")]\n    pub fn execute(&self, statement: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", statement);\n        Ok(self.proxy.execute(statement)?.into())\n    }\n\n    /// Return one [QueryResult] if the query was successful\n    #[instrument(level = \"trace\")]\n    pub fn query_one(&self, statement: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", statement);\n        let result = self.proxy.query(statement)?;\n\n        if let Some(first) = result.first() {\n            return Ok(Some(QueryResult {\n                row: crate::QueryResultRow::Proxy(first.to_owned()),\n            }));\n        } else {\n            return Ok(None);\n        }\n    }\n\n    /// Return all [QueryResult]s if the query was successful\n    #[instrument(level = \"trace\")]\n    pub fn query_all(&self, statement: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug_print!(\"{}\", statement);\n        let result = self.proxy.query(statement)?;\n\n        Ok(result\n            .into_iter()\n            .map(|row| QueryResult {\n                row: crate::QueryResultRow::Proxy(row),\n            })\n            .collect())\n    }\n\n    /// Create a statement block  of SQL statements that execute together.\n    #[instrument(level = \"trace\")]\n    pub fn begin(&self) {\n        self.proxy.begin()\n    }\n\n    /// Commit a transaction atomically to the database\n    #[instrument(level = \"trace\")]\n    pub fn commit(&self) {\n        self.proxy.commit()\n    }\n\n    /// Roll back a faulty transaction\n    #[instrument(level = \"trace\")]\n    pub fn rollback(&self) {\n        self.proxy.rollback()\n    }\n\n    /// Start rollback a transaction\n    #[instrument(level = \"trace\")]\n    pub fn start_rollback(&self) {\n        self.proxy.start_rollback()\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub fn ping(&self) -> Result<(), DbErr> {\n        self.proxy.ping()\n    }\n}\n\nimpl\n    From<(\n        Arc<crate::ProxyDatabaseConnection>,\n        Statement,\n        Option<crate::metric::Callback>,\n    )> for crate::QueryStream\n{\n    fn from(\n        (conn, stmt, metric_callback): (\n            Arc<crate::ProxyDatabaseConnection>,\n            Statement,\n            Option<crate::metric::Callback>,\n        ),\n    ) -> Self {\n        crate::QueryStream::build(stmt, crate::InnerConnection::Proxy(conn), metric_callback)\n    }\n}\n\nimpl crate::DatabaseTransaction {\n    pub(crate) fn new_proxy(\n        inner: Arc<crate::ProxyDatabaseConnection>,\n        metric_callback: Option<crate::metric::Callback>,\n    ) -> Result<crate::DatabaseTransaction, DbErr> {\n        use std::sync::Mutex;\n        let backend = inner.get_database_backend();\n        Self::begin(\n            Arc::new(Mutex::new(crate::InnerConnection::Proxy(inner))),\n            backend,\n            metric_callback,\n            None,\n            None,\n            None,\n        )\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/driver/rusqlite.rs",
    "content": "use std::{\n    ops::Deref,\n    sync::{Arc, Mutex, MutexGuard, TryLockError},\n    time::{Duration, Instant},\n};\nuse tracing::{debug, instrument, warn};\n\npub use OwnedRow as RusqliteRow;\nuse rusqlite::{\n    CachedStatement, OpenFlags, Row,\n    types::{FromSql, FromSqlError, Value},\n};\npub use rusqlite::{\n    Connection as RusqliteConnection, Error as RusqliteError, types::Value as RusqliteOwnedValue,\n};\nuse sea_query_rusqlite::{RusqliteValue, RusqliteValues, rusqlite};\n\nuse crate::{\n    AccessMode, ColIdx, ConnectOptions, DatabaseConnection, DatabaseConnectionType,\n    DatabaseTransaction, InnerConnection, IsolationLevel, QueryStream, SqliteTransactionMode,\n    Statement, TransactionError, error::*, executor::*,\n};\n\n/// A helper class to connect to Rusqlite\n#[derive(Debug)]\npub struct RusqliteConnector;\n\nconst DEFAULT_ACQUIRE_TIMEOUT: Duration = Duration::from_secs(60);\n\n/// A shared SQLite connection for synchronous contexts.\n///\n/// Unlike sqlx's connection pool, which maintains multiple connections that can\n/// be checked out concurrently by different tasks, this holds a single\n/// [`RusqliteConnection`] behind an `Arc<Mutex<State>>`. All callers contend on\n/// the same mutex; [`acquire`](Self::acquire) spins with `try_lock` until the\n/// mutex is available or the `acquire_timeout` deadline expires.\n///\n/// The connection can also be *loaned* out (via [`State::Loaned`]) for the\n/// duration of a transaction or streaming query, during which `acquire` will\n/// keep retrying until the loan is returned.\n#[derive(Clone)]\npub struct RusqliteSharedConnection {\n    pub(crate) conn: Arc<Mutex<State>>,\n    acquire_timeout: Duration,\n    metric_callback: Option<crate::metric::Callback>,\n}\n\n/// A loaned connection that supports nested transactions.\n///\n/// Created by [`RusqliteSharedConnection::loan`], which moves the underlying\n/// [`RusqliteConnection`] out of the shared mutex (leaving it in\n/// [`State::Loaned`]) so that a transaction or streaming query can hold it\n/// without blocking other callers on the mutex itself - they will still wait\n/// via `acquire`, but the mutex is not held for the entire duration.\n///\n/// On [`Drop`], the connection is returned to the shared mutex so that\n/// subsequent callers can acquire it again.\n///\n/// ## Transaction semantics\n///\n/// Nested transactions follow the same model as sqlx's SQLite driver:\n///\n/// | Depth | `begin`            | `commit`              | `rollback`              |\n/// |-------|--------------------|-----------------------|-------------------------|\n/// | 0     | `BEGIN`            | -                     | -                       |\n/// | 1     | `SAVEPOINT sp1`    | `COMMIT`              | `ROLLBACK`              |\n/// | 2     | `SAVEPOINT sp2`    | `RELEASE SAVEPOINT sp1` | `ROLLBACK TO sp1`     |\n/// | *n*   | `SAVEPOINT sp`*n*  | `RELEASE SAVEPOINT sp`*n-1* | `ROLLBACK TO sp`*n-1* |\n///\n/// ## Comparison with rusqlite's native `Transaction`\n///\n/// rusqlite's [`rusqlite::Transaction`] borrows `&mut Connection` for its\n/// entire lifetime. This makes it difficult to pass around, store in structs,\n/// or nest - each nested [`rusqlite::Savepoint`] borrows `&mut Transaction`,\n/// creating a tower of coupled lifetimes that the borrow checker enforces\n/// strictly.\n///\n/// Here, the connection is *moved* (loaned) into this struct as owned state,\n/// and nesting is tracked with a simple `transaction_depth` counter. This\n/// means transactions and savepoints can be started, committed, or rolled back\n/// through the same flat API without lifetime gymnastics. The connection is\n/// returned to the shared pool on [`Drop`], rather than relying on the borrow\n/// ending.\npub struct RusqliteInnerConnection {\n    conn: State,\n    loan: Arc<Mutex<State>>,\n    transaction_depth: u32,\n}\n\n#[derive(Debug)]\npub struct RusqliteExecResult {\n    pub(crate) rows_affected: u64,\n    pub(crate) last_insert_rowid: i64,\n}\n\n#[derive(Debug)]\npub struct OwnedRow {\n    pub columns: Vec<Arc<str>>,\n    pub values: Vec<Value>,\n}\n\n#[derive(Debug, Default)]\npub enum State {\n    Idle(RusqliteConnection),\n    Loaned,\n    #[default]\n    Disconnected,\n}\n\nimpl OwnedRow {\n    pub fn columns(&self) -> &[Arc<str>] {\n        &self.columns\n    }\n\n    pub fn from_row(columns: Vec<Arc<str>>, row: &Row) -> OwnedRow {\n        let mut values = Vec::new();\n\n        for i in 0..columns.len() {\n            let v: Value = row.get_unwrap(i);\n            values.push(v);\n        }\n\n        OwnedRow { columns, values }\n    }\n\n    pub fn try_get<T: FromSql, I: ColIdx>(&self, idx: I) -> Result<T, TryGetError> {\n        let (idx, col, value) = if let Some(idx) = idx.as_usize() {\n            (*idx, None, &self.values[*idx])\n        } else if let Some(name) = idx.as_str() {\n            if let Some(idx) = self.columns.iter().position(|c| c.deref() == name) {\n                (idx, Some(name), &self.values[idx])\n            } else {\n                return Err(TryGetError::Null(format!(\n                    \"column `{name}` does not exist in row\"\n                )));\n            }\n        } else {\n            unreachable!(\"ColIdx must be either usize or str\")\n        };\n        FromSql::column_result(value.into())\n            .map_err(|err| match err {\n                FromSqlError::OutOfRange(i) => RusqliteError::IntegralValueOutOfRange(idx, i),\n                FromSqlError::Other(err) => {\n                    RusqliteError::FromSqlConversionFailure(idx, value.data_type(), err)\n                }\n                FromSqlError::InvalidBlobSize { .. } => {\n                    RusqliteError::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))\n                }\n                // FromSqlError::InvalidType\n                _ => RusqliteError::InvalidColumnType(\n                    idx,\n                    col.map(|c| c.to_owned()).unwrap_or_default(),\n                    value.data_type(),\n                ),\n            })\n            .map_err(|err| TryGetError::DbErr(query_err(err)))\n    }\n}\n\nimpl std::fmt::Debug for RusqliteSharedConnection {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"RusqliteSharedConnection {{ conn: {:?} }}\", self.conn)\n    }\n}\n\nimpl std::fmt::Debug for RusqliteInnerConnection {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"RusqliteInnerConnection {{ conn: {:?} }}\", self.conn)\n    }\n}\n\nimpl From<RusqliteConnection> for RusqliteSharedConnection {\n    fn from(conn: RusqliteConnection) -> Self {\n        RusqliteSharedConnection {\n            conn: Arc::new(Mutex::new(State::Idle(conn))),\n            acquire_timeout: DEFAULT_ACQUIRE_TIMEOUT,\n            metric_callback: None,\n        }\n    }\n}\n\nimpl From<RusqliteSharedConnection> for DatabaseConnection {\n    fn from(conn: RusqliteSharedConnection) -> Self {\n        DatabaseConnectionType::RusqliteSharedConnection(conn).into()\n    }\n}\n\nimpl RusqliteConnector {\n    #[cfg(feature = \"mock\")]\n    /// Check if the URI provided corresponds to `sqlite:` for a SQLite database\n    pub fn accepts(string: &str) -> bool {\n        string.starts_with(\"sqlite:\")\n    }\n\n    /// Add configuration options for the SQLite database\n    #[instrument(level = \"trace\")]\n    pub fn connect(options: ConnectOptions) -> Result<DatabaseConnection, DbErr> {\n        let acquire_timeout = options.acquire_timeout.unwrap_or(DEFAULT_ACQUIRE_TIMEOUT);\n        // TODO handle disable_statement_logging\n        let after_conn = options.after_connect;\n\n        let raw = options\n            .url\n            .trim_start_matches(\"sqlite://\")\n            .trim_start_matches(\"sqlite:\");\n\n        let (path, mode) = match raw.find('?') {\n            Some(q) => {\n                let query = &raw[q + 1..];\n                let mut mode = None;\n                for kv in query.split('&') {\n                    if let Some(val) = kv.strip_prefix(\"mode=\") {\n                        mode = Some(val);\n                    } else if !kv.is_empty() {\n                        return Err(DbErr::Conn(RuntimeErr::Internal(format!(\n                            \"unsupported SQLite connection parameter: {kv}\"\n                        ))));\n                    }\n                }\n                (&raw[..q], mode)\n            }\n            None => (raw, None),\n        };\n\n        let conn = match mode {\n            None | Some(\"rwc\") => RusqliteConnection::open(path),\n            Some(\"ro\") => RusqliteConnection::open_with_flags(\n                path,\n                OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_NO_MUTEX,\n            ),\n            Some(\"rw\") => RusqliteConnection::open_with_flags(\n                path,\n                OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_NO_MUTEX,\n            ),\n            Some(other) => {\n                return Err(DbErr::Conn(RuntimeErr::Internal(format!(\n                    \"unknown SQLite mode: {other}\"\n                ))));\n            }\n        }\n        .map_err(conn_err)?;\n\n        let conn = RusqliteSharedConnection {\n            conn: Arc::new(Mutex::new(State::Idle(conn))),\n            acquire_timeout,\n            metric_callback: None,\n        };\n\n        #[cfg(feature = \"sqlite-use-returning-for-3_35\")]\n        {\n            let version = get_version(&conn)?;\n            super::sqlite::ensure_returning_version(&version)?;\n        }\n\n        // SQLx also enables this by default\n        conn.execute_unprepared(\"PRAGMA foreign_keys = ON\")?;\n        let conn: DatabaseConnection = conn.into();\n\n        if let Some(cb) = after_conn {\n            cb(conn.clone())?;\n        }\n\n        Ok(conn)\n    }\n}\n\n// impl RusqliteConnector {\n//     /// Convert a Rusqlite connection to a [DatabaseConnection]\n//     pub fn from_rusqlite_connection(conn: RusqliteConnection) -> DatabaseConnection {\n//         let conn: RusqliteSharedConnection = conn.into();\n//         conn.into()\n//     }\n// }\n\nimpl RusqliteSharedConnection {\n    pub fn acquire(&self) -> Result<MutexGuard<'_, State>, DbErr> {\n        let deadline = Instant::now() + self.acquire_timeout;\n        loop {\n            match self.conn.try_lock() {\n                Ok(state) => match *state {\n                    State::Idle(_) => return Ok(state),\n                    State::Loaned => (), // borrowed for streaming or transaction\n                    State::Disconnected => {\n                        return Err(DbErr::ConnectionAcquire(ConnAcquireErr::ConnectionClosed));\n                    }\n                },\n                Err(TryLockError::WouldBlock) => (),\n                Err(TryLockError::Poisoned(_)) => {\n                    return Err(DbErr::ConnectionAcquire(ConnAcquireErr::ConnectionClosed));\n                }\n            }\n            if Instant::now() >= deadline {\n                return Err(DbErr::ConnectionAcquire(ConnAcquireErr::Timeout));\n            }\n            std::thread::yield_now();\n        }\n    }\n\n    fn loan(&self) -> Result<RusqliteInnerConnection, DbErr> {\n        let conn = {\n            let mut conn = self.acquire()?;\n            conn.loan()\n        };\n        Ok(RusqliteInnerConnection {\n            conn: State::Idle(conn),\n            loan: self.conn.clone(),\n            transaction_depth: 0,\n        })\n    }\n\n    /// Execute a [Statement] on a SQLite backend\n    #[instrument(level = \"trace\")]\n    pub fn execute(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(&stmt);\n        let conn = self.acquire()?;\n        let conn = conn.conn();\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match conn.execute(&stmt.sql, &*values.as_params()) {\n                Ok(rows_affected) => Ok(RusqliteExecResult {\n                    rows_affected: rows_affected as u64,\n                    last_insert_rowid: conn.last_insert_rowid(),\n                }\n                .into()),\n                Err(err) => Err(exec_err(err)),\n            }\n        })\n    }\n\n    /// Execute an unprepared SQL statement on a SQLite backend\n    #[instrument(level = \"trace\")]\n    pub fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        debug!(\"{}\", sql);\n\n        let conn = self.acquire()?;\n        let conn = conn.conn();\n        match conn.execute_batch(sql) {\n            Ok(()) => Ok(RusqliteExecResult {\n                rows_affected: conn.changes(),\n                last_insert_rowid: conn.last_insert_rowid(),\n            }\n            .into()),\n            Err(err) => Err(exec_err(err)),\n        }\n    }\n\n    /// Get one result from a SQL query. Returns [Option::None] if no match was found\n    #[instrument(level = \"trace\")]\n    pub fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(&stmt);\n        let conn = self.acquire()?;\n        let conn = conn.conn();\n        let mut sql = conn.prepare_cached(&stmt.sql).map_err(query_err)?;\n        let columns: Vec<Arc<str>> = column_names(&sql);\n\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match sql.query(&*values.as_params()) {\n                Ok(mut rows) => {\n                    let mut out = None;\n                    if let Some(row) = rows.next().map_err(query_err)? {\n                        out = Some(OwnedRow::from_row(columns.clone(), row).into());\n                    }\n                    Ok(out)\n                }\n                Err(err) => Err(query_err(err)),\n            }\n        })\n    }\n\n    /// Get the results of a query returning them as a Vec<[QueryResult]>\n    #[instrument(level = \"trace\")]\n    pub fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(&stmt);\n        let conn = self.acquire()?;\n        let conn = conn.conn();\n        let mut sql = conn.prepare_cached(&stmt.sql).map_err(query_err)?;\n        let columns: Vec<Arc<str>> = column_names(&sql);\n\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match sql.query(&*values.as_params()) {\n                Ok(mut rows) => {\n                    let mut out = Vec::new();\n                    while let Some(row) = rows.next().map_err(query_err)? {\n                        out.push(OwnedRow::from_row(columns.clone(), row).into());\n                    }\n                    Ok(out)\n                }\n                Err(err) => Err(query_err(err)),\n            }\n        })\n    }\n\n    /// Stream the results of executing a SQL query\n    #[instrument(level = \"trace\")]\n    pub fn stream(&self, stmt: Statement) -> Result<QueryStream, DbErr> {\n        debug!(\"{}\", stmt);\n\n        Ok(QueryStream::build(\n            stmt,\n            InnerConnection::Rusqlite(self.loan()?),\n            self.metric_callback.clone(),\n        ))\n    }\n\n    /// Bundle a set of SQL statements that execute together.\n    #[instrument(level = \"trace\")]\n    pub fn begin(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n        sqlite_transaction_mode: Option<SqliteTransactionMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        let conn = self.loan()?;\n        DatabaseTransaction::begin(\n            Arc::new(Mutex::new(InnerConnection::Rusqlite(conn))),\n            crate::DbBackend::Sqlite,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n            sqlite_transaction_mode,\n        )\n    }\n\n    /// Create a SQLite transaction\n    #[instrument(level = \"trace\", skip(callback))]\n    pub fn transaction<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'b> FnOnce(&'b DatabaseTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        self.begin(isolation_level, access_mode, None)\n            .map_err(|e| TransactionError::Connection(e))?\n            .run(callback)\n    }\n\n    pub(crate) fn set_metric_callback<F>(&mut self, callback: F)\n    where\n        F: Fn(&crate::metric::Info<'_>) + 'static,\n    {\n        self.metric_callback = Some(Arc::new(callback));\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub fn ping(&self) -> Result<(), DbErr> {\n        let conn = self.acquire()?;\n        let conn = conn.conn();\n        let mut stmt = conn.prepare(\"SELECT 1\").map_err(conn_err)?;\n        match stmt.query([]) {\n            Ok(_) => Ok(()),\n            Err(err) => Err(conn_err(err)),\n        }\n    }\n\n    /// Explicitly close the SQLite connection.\n    /// See [`Self::close_by_ref`] for usage with references.\n    pub fn close(self) -> Result<(), DbErr> {\n        self.close_by_ref()\n    }\n\n    /// Explicitly close the SQLite connection\n    pub fn close_by_ref(&self) -> Result<(), DbErr> {\n        let mut conn = self.acquire()?;\n        *conn = State::Disconnected;\n        Ok(())\n    }\n}\n\nimpl RusqliteInnerConnection {\n    #[instrument(level = \"trace\", skip(metric_callback))]\n    pub fn execute(\n        &self,\n        stmt: Statement,\n        metric_callback: &Option<crate::metric::Callback>,\n    ) -> Result<ExecResult, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(&stmt);\n        let conn = self.conn.conn();\n        crate::metric::metric!(metric_callback, &stmt, {\n            match conn.execute(&stmt.sql, &*values.as_params()) {\n                Ok(rows_affected) => Ok(RusqliteExecResult {\n                    rows_affected: rows_affected as u64,\n                    last_insert_rowid: conn.last_insert_rowid(),\n                }\n                .into()),\n                Err(err) => Err(exec_err(err)),\n            }\n        })\n    }\n\n    #[instrument(level = \"trace\")]\n    pub(crate) fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        debug!(\"{}\", sql);\n\n        let conn = self.conn.conn();\n        match conn.execute_batch(sql) {\n            Ok(()) => Ok(RusqliteExecResult {\n                rows_affected: conn.changes(),\n                last_insert_rowid: conn.last_insert_rowid(),\n            }\n            .into()),\n            Err(err) => Err(exec_err(err)),\n        }\n    }\n\n    #[instrument(level = \"trace\", skip(metric_callback))]\n    pub fn query_one(\n        &self,\n        stmt: Statement,\n        metric_callback: &Option<crate::metric::Callback>,\n    ) -> Result<Option<QueryResult>, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(&stmt);\n        let conn = self.conn.conn();\n        let mut sql = conn.prepare_cached(&stmt.sql).map_err(query_err)?;\n        let columns: Vec<Arc<str>> = column_names(&sql);\n\n        crate::metric::metric!(metric_callback, &stmt, {\n            match sql.query(&*values.as_params()) {\n                Ok(mut rows) => {\n                    let mut out = None;\n                    if let Some(row) = rows.next().map_err(query_err)? {\n                        out = Some(OwnedRow::from_row(columns.clone(), row).into());\n                    }\n                    Ok(out)\n                }\n                Err(err) => Err(query_err(err)),\n            }\n        })\n    }\n\n    #[instrument(level = \"trace\", skip(metric_callback))]\n    pub fn query_all(\n        &self,\n        stmt: Statement,\n        metric_callback: &Option<crate::metric::Callback>,\n    ) -> Result<Vec<QueryResult>, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(&stmt);\n        let conn = self.conn.conn();\n        let mut sql = conn.prepare_cached(&stmt.sql).map_err(query_err)?;\n        let columns: Vec<Arc<str>> = column_names(&sql);\n\n        crate::metric::metric!(metric_callback, &stmt, {\n            match sql.query(&*values.as_params()) {\n                Ok(mut rows) => {\n                    let mut out = Vec::new();\n                    while let Some(row) = rows.next().map_err(query_err)? {\n                        out.push(OwnedRow::from_row(columns.clone(), row).into());\n                    }\n                    Ok(out)\n                }\n                Err(err) => Err(query_err(err)),\n            }\n        })\n    }\n\n    #[instrument(level = \"trace\")]\n    pub(crate) fn stream(&self, stmt: &Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(stmt);\n        let conn = self.conn.conn();\n        let mut sql = conn.prepare_cached(&stmt.sql).map_err(query_err)?;\n        let columns: Vec<Arc<str>> = column_names(&sql);\n\n        let rows = match sql.query(&*values.as_params()) {\n            Ok(mut rows) => {\n                let mut out = Vec::new();\n                while let Some(row) = rows.next().map_err(query_err)? {\n                    out.push(OwnedRow::from_row(columns.clone(), row).into());\n                }\n                out\n            }\n            Err(err) => return Err(query_err(err)),\n        };\n\n        Ok(rows)\n    }\n\n    #[instrument(level = \"trace\")]\n    pub(crate) fn begin(\n        &mut self,\n        sqlite_transaction_mode: Option<SqliteTransactionMode>,\n    ) -> Result<(), DbErr> {\n        if self.transaction_depth == 0 {\n            match sqlite_transaction_mode {\n                Some(mode) => {\n                    self.execute_unprepared(&format!(\"BEGIN {}\", mode.sqlite_keyword()))?\n                }\n                None => self.execute_unprepared(\"BEGIN\")?,\n            };\n        } else {\n            self.execute_unprepared(&format!(\"SAVEPOINT sp{}\", self.transaction_depth))?;\n        }\n        self.transaction_depth += 1;\n        Ok(())\n    }\n\n    #[instrument(level = \"trace\")]\n    pub(crate) fn commit(&mut self) -> Result<(), DbErr> {\n        if self.transaction_depth == 1 {\n            self.execute_unprepared(\"COMMIT\")?;\n        } else {\n            self.execute_unprepared(&format!(\n                \"RELEASE SAVEPOINT sp{}\",\n                self.transaction_depth - 1\n            ))?;\n        }\n        self.transaction_depth -= 1;\n        Ok(())\n    }\n\n    #[instrument(level = \"trace\")]\n    pub(crate) fn rollback(&mut self) -> Result<(), DbErr> {\n        if self.transaction_depth == 1 {\n            self.execute_unprepared(\"ROLLBACK\")?;\n        } else {\n            self.execute_unprepared(&format!(\"ROLLBACK TO sp{}\", self.transaction_depth - 1))?;\n        }\n        self.transaction_depth -= 1;\n        Ok(())\n    }\n\n    #[instrument(level = \"trace\")]\n    pub(crate) fn start_rollback(&mut self) -> Result<(), DbErr> {\n        if self.transaction_depth > 0 {\n            self.rollback()?;\n        }\n        Ok(())\n    }\n}\n\nimpl Drop for RusqliteInnerConnection {\n    fn drop(&mut self) {\n        let mut loan = self.loan.lock().unwrap();\n        loan.return_(self.conn.loan());\n    }\n}\n\nimpl State {\n    fn conn(&self) -> &RusqliteConnection {\n        match self {\n            State::Idle(conn) => conn,\n            _ => panic!(\"No connection\"),\n        }\n    }\n\n    fn loan(&mut self) -> RusqliteConnection {\n        let mut conn = State::Loaned;\n        std::mem::swap(&mut conn, self);\n        match conn {\n            State::Idle(conn) => conn,\n            _ => panic!(\"No connection\"),\n        }\n    }\n\n    fn return_(&mut self, conn: RusqliteConnection) {\n        *self = State::Idle(conn);\n    }\n}\n\nimpl From<OwnedRow> for QueryResult {\n    fn from(row: OwnedRow) -> QueryResult {\n        QueryResult {\n            row: QueryResultRow::Rusqlite(row),\n        }\n    }\n}\n\nimpl From<RusqliteExecResult> for ExecResult {\n    fn from(result: RusqliteExecResult) -> ExecResult {\n        ExecResult {\n            result: ExecResultHolder::Rusqlite(result),\n        }\n    }\n}\n\npub(crate) fn sql_values(stmt: &Statement) -> RusqliteValues {\n    let values = match &stmt.values {\n        Some(values) => values.iter().cloned().map(RusqliteValue).collect(),\n        None => Vec::new(),\n    };\n    RusqliteValues(values)\n}\n\nfn column_names(sql: &CachedStatement) -> Vec<Arc<str>> {\n    sql.column_names()\n        .into_iter()\n        .map(|r| Arc::from(r))\n        .collect()\n}\n\n#[cfg(feature = \"sqlite-use-returning-for-3_35\")]\nfn get_version(conn: &RusqliteSharedConnection) -> Result<String, DbErr> {\n    let stmt = Statement {\n        sql: \"SELECT sqlite_version()\".to_string(),\n        values: None,\n        db_backend: crate::DbBackend::Sqlite,\n    };\n    conn.query_one(stmt)?\n        .ok_or_else(|| {\n            DbErr::Conn(RuntimeErr::Internal(\n                \"Error reading SQLite version\".to_string(),\n            ))\n        })?\n        .try_get_by(0)\n}\n\nfn conn_err(err: RusqliteError) -> DbErr {\n    DbErr::Conn(RuntimeErr::Rusqlite(err.into()))\n}\n\nfn exec_err(err: RusqliteError) -> DbErr {\n    DbErr::Exec(RuntimeErr::Rusqlite(err.into()))\n}\n\nfn query_err(err: RusqliteError) -> DbErr {\n    DbErr::Query(RuntimeErr::Rusqlite(err.into()))\n}\n"
  },
  {
    "path": "sea-orm-sync/src/driver/sqlite.rs",
    "content": "use crate::error::{DbErr, RuntimeErr};\n\n#[cfg(feature = \"sqlite-use-returning-for-3_35\")]\npub fn ensure_returning_version(version: &str) -> Result<(), DbErr> {\n    let mut parts = version.trim().split('.').map(|part| {\n        part.parse::<u32>().map_err(|_| {\n            DbErr::Conn(RuntimeErr::Internal(\n                \"Error parsing SQLite version\".to_string(),\n            ))\n        })\n    });\n\n    let mut extract_next = || {\n        parts.next().transpose().and_then(|part| {\n            part.ok_or_else(|| {\n                DbErr::Conn(RuntimeErr::Internal(\"SQLite version too short\".to_string()))\n            })\n        })\n    };\n\n    let major = extract_next()?;\n    let minor = extract_next()?;\n\n    if major > 3 || (major == 3 && minor >= 35) {\n        Ok(())\n    } else {\n        Err(DbErr::BackendNotSupported {\n            db: \"SQLite\",\n            ctx: \"SQLite version does not support returning\",\n        })\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[cfg(feature = \"sqlite-use-returning-for-3_35\")]\n    #[test]\n    fn test_ensure_returning_version() {\n        assert!(ensure_returning_version(\"\").is_err());\n        assert!(ensure_returning_version(\".\").is_err());\n        assert!(ensure_returning_version(\".a\").is_err());\n        assert!(ensure_returning_version(\".4.9\").is_err());\n        assert!(ensure_returning_version(\"a\").is_err());\n        assert!(ensure_returning_version(\"1.\").is_err());\n        assert!(ensure_returning_version(\"1.a\").is_err());\n\n        assert!(ensure_returning_version(\"1.1\").is_err());\n        assert!(ensure_returning_version(\"1.0.\").is_err());\n        assert!(ensure_returning_version(\"1.0.0\").is_err());\n        assert!(ensure_returning_version(\"2.0.0\").is_err());\n        assert!(ensure_returning_version(\"3.34.0\").is_err());\n        assert!(ensure_returning_version(\"3.34.999\").is_err());\n\n        // valid version\n        assert!(ensure_returning_version(\"3.35.0\").is_ok());\n        assert!(ensure_returning_version(\"3.35.1\").is_ok());\n        assert!(ensure_returning_version(\"3.36.0\").is_ok());\n        assert!(ensure_returning_version(\"4.0.0\").is_ok());\n        assert!(ensure_returning_version(\"99.0.0\").is_ok());\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/driver/sqlx_common.rs",
    "content": "use crate::{ConnAcquireErr, ConnectOptions, DbErr, RuntimeErr};\n\n/// Converts an [sqlx::error] execution error to a [DbErr]\npub fn sqlx_error_to_exec_err(err: sqlx::Error) -> DbErr {\n    DbErr::Exec(RuntimeErr::SqlxError(err.into()))\n}\n\n/// Converts an [sqlx::error] query error to a [DbErr]\npub fn sqlx_error_to_query_err(err: sqlx::Error) -> DbErr {\n    DbErr::Query(RuntimeErr::SqlxError(err.into()))\n}\n\n/// Converts an [sqlx::error] connection error to a [DbErr]\npub fn sqlx_error_to_conn_err(err: sqlx::Error) -> DbErr {\n    DbErr::Conn(RuntimeErr::SqlxError(err.into()))\n}\n\n/// Converts an [sqlx::error] error to a [DbErr]\npub fn sqlx_map_err_ignore_not_found<T: std::fmt::Debug>(\n    err: Result<Option<T>, sqlx::Error>,\n) -> Result<Option<T>, DbErr> {\n    if let Err(sqlx::Error::RowNotFound) = err {\n        Ok(None)\n    } else {\n        err.map_err(sqlx_error_to_query_err)\n    }\n}\n\n/// Converts an [sqlx::error] error to a [DbErr]\npub fn sqlx_conn_acquire_err(sqlx_err: sqlx::Error) -> DbErr {\n    match sqlx_err {\n        sqlx::Error::PoolTimedOut => DbErr::ConnectionAcquire(ConnAcquireErr::Timeout),\n        sqlx::Error::PoolClosed => DbErr::ConnectionAcquire(ConnAcquireErr::ConnectionClosed),\n        _ => DbErr::Conn(RuntimeErr::SqlxError(sqlx_err.into())),\n    }\n}\n\nimpl ConnectOptions {\n    /// Convert [ConnectOptions] into [sqlx::pool::PoolOptions]\n    pub fn sqlx_pool_options<DB>(self) -> sqlx::pool::PoolOptions<DB>\n    where\n        DB: sqlx::Database,\n    {\n        let mut opt = sqlx::pool::PoolOptions::new();\n        if let Some(max_connections) = self.max_connections {\n            opt = opt.max_connections(max_connections);\n        }\n        if let Some(min_connections) = self.min_connections {\n            opt = opt.min_connections(min_connections);\n        }\n        if let Some(connect_timeout) = self.connect_timeout {\n            opt = opt.acquire_timeout(connect_timeout);\n        }\n        if let Some(idle_timeout) = self.idle_timeout {\n            opt = opt.idle_timeout(idle_timeout);\n        }\n        if let Some(acquire_timeout) = self.acquire_timeout {\n            opt = opt.acquire_timeout(acquire_timeout);\n        }\n        if let Some(max_lifetime) = self.max_lifetime {\n            opt = opt.max_lifetime(max_lifetime);\n        }\n        opt = opt.test_before_acquire(self.test_before_acquire);\n        opt\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/driver/sqlx_mysql.rs",
    "content": "use log::LevelFilter;\nuse sea_query::Values;\nuse std::sync::Arc;\nuse std::sync::Mutex;\n\nuse sqlx::{\n    Connection, Executor, MySql, MySqlPool,\n    mysql::{MySqlConnectOptions, MySqlQueryResult, MySqlRow},\n    pool::PoolConnection,\n};\n\nuse sea_query_sqlx::SqlxValues;\nuse tracing::instrument;\n\nuse crate::{\n    AccessMode, ConnectOptions, DatabaseConnection, DatabaseConnectionType, DatabaseTransaction,\n    DbBackend, IsolationLevel, QueryStream, Statement, TransactionError, debug_print, error::*,\n    executor::*,\n};\n\nuse super::sqlx_common::*;\n\n/// Defines the [sqlx::mysql] connector\n#[derive(Debug)]\npub struct SqlxMySqlConnector;\n\n/// Defines a sqlx MySQL pool\n#[derive(Clone)]\npub struct SqlxMySqlPoolConnection {\n    pub(crate) pool: MySqlPool,\n    metric_callback: Option<crate::metric::Callback>,\n}\n\nimpl std::fmt::Debug for SqlxMySqlPoolConnection {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"SqlxMySqlPoolConnection {{ pool: {:?} }}\", self.pool)\n    }\n}\n\nimpl From<MySqlPool> for SqlxMySqlPoolConnection {\n    fn from(pool: MySqlPool) -> Self {\n        SqlxMySqlPoolConnection {\n            pool,\n            metric_callback: None,\n        }\n    }\n}\n\nimpl From<MySqlPool> for DatabaseConnection {\n    fn from(pool: MySqlPool) -> Self {\n        DatabaseConnectionType::SqlxMySqlPoolConnection(pool.into()).into()\n    }\n}\n\nimpl SqlxMySqlConnector {\n    /// Check if the URI provided corresponds to `mysql://` for a MySQL database\n    pub fn accepts(string: &str) -> bool {\n        string.starts_with(\"mysql://\") && string.parse::<MySqlConnectOptions>().is_ok()\n    }\n\n    /// Add configuration options for the MySQL database\n    #[instrument(level = \"trace\")]\n    pub fn connect(options: ConnectOptions) -> Result<DatabaseConnection, DbErr> {\n        let mut sqlx_opts = options\n            .url\n            .parse::<MySqlConnectOptions>()\n            .map_err(sqlx_error_to_conn_err)?;\n        use sqlx::ConnectOptions;\n        if !options.sqlx_logging {\n            sqlx_opts = sqlx_opts.disable_statement_logging();\n        } else {\n            sqlx_opts = sqlx_opts.log_statements(options.sqlx_logging_level);\n            if options.sqlx_slow_statements_logging_level != LevelFilter::Off {\n                sqlx_opts = sqlx_opts.log_slow_statements(\n                    options.sqlx_slow_statements_logging_level,\n                    options.sqlx_slow_statements_logging_threshold,\n                );\n            }\n        }\n\n        if let Some(f) = &options.mysql_opts_fn {\n            sqlx_opts = f(sqlx_opts);\n        }\n\n        let after_connect = options.after_connect.clone();\n\n        let pool = if options.connect_lazy {\n            options.sqlx_pool_options().connect_lazy_with(sqlx_opts)\n        } else {\n            options\n                .sqlx_pool_options()\n                .connect_with(sqlx_opts)\n                .map_err(sqlx_error_to_conn_err)?\n        };\n\n        let conn: DatabaseConnection =\n            DatabaseConnectionType::SqlxMySqlPoolConnection(SqlxMySqlPoolConnection {\n                pool,\n                metric_callback: None,\n            })\n            .into();\n\n        if let Some(cb) = after_connect {\n            cb(conn.clone())?;\n        }\n\n        Ok(conn)\n    }\n}\n\nimpl SqlxMySqlConnector {\n    /// Instantiate a sqlx pool connection to a [DatabaseConnection]\n    pub fn from_sqlx_mysql_pool(pool: MySqlPool) -> DatabaseConnection {\n        DatabaseConnectionType::SqlxMySqlPoolConnection(SqlxMySqlPoolConnection {\n            pool,\n            metric_callback: None,\n        })\n        .into()\n    }\n}\n\nimpl SqlxMySqlPoolConnection {\n    /// Execute a [Statement] on a MySQL backend\n    #[instrument(level = \"trace\")]\n    pub fn execute(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.execute(&mut *conn) {\n                Ok(res) => Ok(res.into()),\n                Err(err) => Err(sqlx_error_to_exec_err(err)),\n            }\n        })\n    }\n\n    /// Execute an unprepared SQL statement on a MySQL backend\n    #[instrument(level = \"trace\")]\n    pub fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", sql);\n\n        let conn = &mut self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        match conn.execute(sql) {\n            Ok(res) => Ok(res.into()),\n            Err(err) => Err(sqlx_error_to_exec_err(err)),\n        }\n    }\n\n    /// Get one result from a SQL query. Returns [Option::None] if no match was found\n    #[instrument(level = \"trace\")]\n    pub fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.fetch_one(&mut *conn) {\n                Ok(row) => Ok(Some(row.into())),\n                Err(err) => match err {\n                    sqlx::Error::RowNotFound => Ok(None),\n                    _ => Err(sqlx_error_to_query_err(err)),\n                },\n            }\n        })\n    }\n\n    /// Get the results of a query returning them as a Vec<[QueryResult]>\n    #[instrument(level = \"trace\")]\n    pub fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.fetch_all(&mut *conn) {\n                Ok(rows) => Ok(rows.into_iter().map(|r| r.into()).collect()),\n                Err(err) => Err(sqlx_error_to_query_err(err)),\n            }\n        })\n    }\n\n    /// Stream the results of executing a SQL query\n    #[instrument(level = \"trace\")]\n    pub fn stream(&self, stmt: Statement) -> Result<QueryStream, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        Ok(QueryStream::from((\n            conn,\n            stmt,\n            self.metric_callback.clone(),\n        )))\n    }\n\n    /// Bundle a set of SQL statements that execute together.\n    #[instrument(level = \"trace\")]\n    pub fn begin(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        let conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        DatabaseTransaction::new_mysql(\n            conn,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n        )\n    }\n\n    /// Create a MySQL transaction\n    #[instrument(level = \"trace\", skip(callback))]\n    pub fn transaction<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'b> FnOnce(&'b DatabaseTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        let conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        let transaction = DatabaseTransaction::new_mysql(\n            conn,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n        )\n        .map_err(|e| TransactionError::Connection(e))?;\n        transaction.run(callback)\n    }\n\n    pub(crate) fn set_metric_callback<F>(&mut self, callback: F)\n    where\n        F: Fn(&crate::metric::Info<'_>) + 'static,\n    {\n        self.metric_callback = Some(Arc::new(callback));\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub fn ping(&self) -> Result<(), DbErr> {\n        let conn = &mut self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        match conn.ping() {\n            Ok(_) => Ok(()),\n            Err(err) => Err(sqlx_error_to_conn_err(err)),\n        }\n    }\n\n    /// Explicitly close the MySQL connection.\n    /// See [`Self::close_by_ref`] for usage with references.\n    pub fn close(self) -> Result<(), DbErr> {\n        self.close_by_ref()\n    }\n\n    /// Explicitly close the MySQL connection\n    pub fn close_by_ref(&self) -> Result<(), DbErr> {\n        self.pool.close();\n        Ok(())\n    }\n}\n\nimpl From<MySqlRow> for QueryResult {\n    fn from(row: MySqlRow) -> QueryResult {\n        QueryResult {\n            row: QueryResultRow::SqlxMySql(row),\n        }\n    }\n}\n\nimpl From<MySqlQueryResult> for ExecResult {\n    fn from(result: MySqlQueryResult) -> ExecResult {\n        ExecResult {\n            result: ExecResultHolder::SqlxMySql(result),\n        }\n    }\n}\n\npub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, MySql, SqlxValues> {\n    let values = stmt\n        .values\n        .as_ref()\n        .map_or(Values(Vec::new()), |values| values.clone());\n    sqlx::query_with(&stmt.sql, SqlxValues(values))\n}\n\npub(crate) fn set_transaction_config(\n    conn: &mut PoolConnection<MySql>,\n    isolation_level: Option<IsolationLevel>,\n    access_mode: Option<AccessMode>,\n) -> Result<(), DbErr> {\n    let mut settings = Vec::new();\n\n    if let Some(isolation_level) = isolation_level {\n        settings.push(format!(\"ISOLATION LEVEL {isolation_level}\"));\n    }\n\n    if let Some(access_mode) = access_mode {\n        settings.push(access_mode.to_string());\n    }\n\n    if !settings.is_empty() {\n        let stmt = Statement {\n            sql: format!(\"SET TRANSACTION {}\", settings.join(\", \")),\n            values: None,\n            db_backend: DbBackend::MySql,\n        };\n        let query = sqlx_query(&stmt);\n        conn.execute(query).map_err(sqlx_error_to_exec_err)?;\n    }\n    Ok(())\n}\n\nimpl\n    From<(\n        PoolConnection<sqlx::MySql>,\n        Statement,\n        Option<crate::metric::Callback>,\n    )> for crate::QueryStream\n{\n    fn from(\n        (conn, stmt, metric_callback): (\n            PoolConnection<sqlx::MySql>,\n            Statement,\n            Option<crate::metric::Callback>,\n        ),\n    ) -> Self {\n        crate::QueryStream::build(stmt, crate::InnerConnection::MySql(conn), metric_callback)\n    }\n}\n\nimpl crate::DatabaseTransaction {\n    pub(crate) fn new_mysql(\n        inner: PoolConnection<sqlx::MySql>,\n        metric_callback: Option<crate::metric::Callback>,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<crate::DatabaseTransaction, DbErr> {\n        Self::begin(\n            Arc::new(Mutex::new(crate::InnerConnection::MySql(inner))),\n            crate::DbBackend::MySql,\n            metric_callback,\n            isolation_level,\n            access_mode,\n            None,\n        )\n    }\n}\n\n#[cfg(feature = \"proxy\")]\npub(crate) fn from_sqlx_mysql_row_to_proxy_row(row: &sqlx::mysql::MySqlRow) -> crate::ProxyRow {\n    // https://docs.rs/sqlx-mysql/0.7.2/src/sqlx_mysql/protocol/text/column.rs.html\n    // https://docs.rs/sqlx-mysql/0.7.2/sqlx_mysql/types/index.html\n    use sea_query::Value;\n    use sqlx::{Column, Row, TypeInfo};\n    crate::ProxyRow {\n        values: row\n            .columns()\n            .iter()\n            .map(|c| {\n                (\n                    c.name().to_string(),\n                    match c.type_info().name() {\n                        \"TINYINT(1)\" | \"BOOLEAN\" => {\n                            Value::Bool(row.try_get(c.ordinal()).expect(\"Failed to get boolean\"))\n                        }\n                        \"TINYINT UNSIGNED\" => Value::TinyUnsigned(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get unsigned tiny integer\"),\n                        ),\n                        \"SMALLINT UNSIGNED\" => Value::SmallUnsigned(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get unsigned small integer\"),\n                        ),\n                        \"INT UNSIGNED\" => Value::Unsigned(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get unsigned integer\"),\n                        ),\n                        \"MEDIUMINT UNSIGNED\" | \"BIGINT UNSIGNED\" => Value::BigUnsigned(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get unsigned big integer\"),\n                        ),\n                        \"TINYINT\" => Value::TinyInt(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get tiny integer\"),\n                        ),\n                        \"SMALLINT\" => Value::SmallInt(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get small integer\"),\n                        ),\n                        \"INT\" => {\n                            Value::Int(row.try_get(c.ordinal()).expect(\"Failed to get integer\"))\n                        }\n                        \"MEDIUMINT\" | \"BIGINT\" => Value::BigInt(\n                            row.try_get(c.ordinal()).expect(\"Failed to get big integer\"),\n                        ),\n                        \"FLOAT\" => {\n                            Value::Float(row.try_get(c.ordinal()).expect(\"Failed to get float\"))\n                        }\n                        \"DOUBLE\" => {\n                            Value::Double(row.try_get(c.ordinal()).expect(\"Failed to get double\"))\n                        }\n\n                        \"BIT\" | \"BINARY\" | \"VARBINARY\" | \"TINYBLOB\" | \"BLOB\" | \"MEDIUMBLOB\"\n                        | \"LONGBLOB\" => Value::Bytes(\n                            row.try_get::<Option<Vec<u8>>, _>(c.ordinal())\n                                .expect(\"Failed to get bytes\")\n                                .map(Box::new),\n                        ),\n\n                        \"CHAR\" | \"VARCHAR\" | \"TINYTEXT\" | \"TEXT\" | \"MEDIUMTEXT\" | \"LONGTEXT\" => {\n                            Value::String(\n                                row.try_get::<Option<String>, _>(c.ordinal())\n                                    .expect(\"Failed to get string\")\n                                    .map(Box::new),\n                            )\n                        }\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIMESTAMP\" => Value::ChronoDateTimeUtc(\n                            row.try_get::<Option<chrono::DateTime<chrono::Utc>>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamp\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIMESTAMP\" => Value::TimeDateTime(\n                            row.try_get::<Option<time::PrimitiveDateTime>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamp\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"DATE\" => Value::ChronoDate(\n                            row.try_get::<Option<chrono::NaiveDate>, _>(c.ordinal())\n                                .expect(\"Failed to get date\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"DATE\" => Value::TimeDate(\n                            row.try_get::<Option<time::Date>, _>(c.ordinal())\n                                .expect(\"Failed to get date\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIME\" => Value::ChronoTime(\n                            row.try_get::<Option<chrono::NaiveTime>, _>(c.ordinal())\n                                .expect(\"Failed to get time\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIME\" => Value::TimeTime(\n                            row.try_get::<Option<time::Time>, _>(c.ordinal())\n                                .expect(\"Failed to get time\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"DATETIME\" => Value::ChronoDateTime(\n                            row.try_get::<Option<chrono::NaiveDateTime>, _>(c.ordinal())\n                                .expect(\"Failed to get datetime\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"DATETIME\" => Value::TimeDateTime(\n                            row.try_get::<Option<time::PrimitiveDateTime>, _>(c.ordinal())\n                                .expect(\"Failed to get datetime\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"YEAR\" => Value::ChronoDate(\n                            row.try_get::<Option<chrono::NaiveDate>, _>(c.ordinal())\n                                .expect(\"Failed to get year\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"YEAR\" => Value::TimeDate(\n                            row.try_get::<Option<time::Date>, _>(c.ordinal())\n                                .expect(\"Failed to get year\")\n                                .map(Box::new),\n                        ),\n\n                        \"ENUM\" | \"SET\" | \"GEOMETRY\" => Value::String(\n                            row.try_get::<Option<String>, _>(c.ordinal())\n                                .expect(\"Failed to get serialized string\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-bigdecimal\")]\n                        \"DECIMAL\" => Value::BigDecimal(\n                            row.try_get::<Option<bigdecimal::BigDecimal>, _>(c.ordinal())\n                                .expect(\"Failed to get decimal\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-rust_decimal\",\n                            not(feature = \"with-bigdecimal\")\n                        ))]\n                        \"DECIMAL\" => Value::Decimal(\n                            row.try_get::<Option<rust_decimal::Decimal>, _>(c.ordinal())\n                                .expect(\"Failed to get decimal\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-json\")]\n                        \"JSON\" => Value::Json(\n                            row.try_get::<Option<serde_json::Value>, _>(c.ordinal())\n                                .expect(\"Failed to get json\")\n                                .map(Box::new),\n                        ),\n\n                        _ => unreachable!(\"Unknown column type: {}\", c.type_info().name()),\n                    },\n                )\n            })\n            .collect(),\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/driver/sqlx_postgres.rs",
    "content": "use log::LevelFilter;\nuse sea_query::Values;\nuse std::sync::Mutex;\nuse std::{fmt::Write, sync::Arc};\n\nuse sqlx::{\n    Connection, Executor, PgPool, Postgres,\n    pool::PoolConnection,\n    postgres::{PgConnectOptions, PgQueryResult, PgRow},\n};\n\nuse sea_query_sqlx::SqlxValues;\nuse tracing::instrument;\n\nuse crate::{\n    AccessMode, ConnectOptions, DatabaseConnection, DatabaseConnectionType, DatabaseTransaction,\n    IsolationLevel, QueryStream, Statement, TransactionError, debug_print, error::*, executor::*,\n};\n\nuse super::sqlx_common::*;\n\n/// Defines the [sqlx::postgres] connector\n#[derive(Debug)]\npub struct SqlxPostgresConnector;\n\n/// Defines a sqlx PostgreSQL pool\n#[derive(Clone)]\npub struct SqlxPostgresPoolConnection {\n    pub(crate) pool: PgPool,\n    metric_callback: Option<crate::metric::Callback>,\n}\n\nimpl std::fmt::Debug for SqlxPostgresPoolConnection {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"SqlxPostgresPoolConnection {{ pool: {:?} }}\", self.pool)\n    }\n}\n\nimpl From<PgPool> for SqlxPostgresPoolConnection {\n    fn from(pool: PgPool) -> Self {\n        SqlxPostgresPoolConnection {\n            pool,\n            metric_callback: None,\n        }\n    }\n}\n\nimpl From<PgPool> for DatabaseConnection {\n    fn from(pool: PgPool) -> Self {\n        DatabaseConnectionType::SqlxPostgresPoolConnection(pool.into()).into()\n    }\n}\n\nimpl SqlxPostgresConnector {\n    /// Check if the URI provided corresponds to `postgres://` for a PostgreSQL database\n    pub fn accepts(string: &str) -> bool {\n        string.starts_with(\"postgres://\") && string.parse::<PgConnectOptions>().is_ok()\n    }\n\n    /// Add configuration options for the PostgreSQL database\n    #[instrument(level = \"trace\")]\n    pub fn connect(options: ConnectOptions) -> Result<DatabaseConnection, DbErr> {\n        let mut sqlx_opts = options\n            .url\n            .parse::<PgConnectOptions>()\n            .map_err(sqlx_error_to_conn_err)?;\n        use sqlx::ConnectOptions;\n        if !options.sqlx_logging {\n            sqlx_opts = sqlx_opts.disable_statement_logging();\n        } else {\n            sqlx_opts = sqlx_opts.log_statements(options.sqlx_logging_level);\n            if options.sqlx_slow_statements_logging_level != LevelFilter::Off {\n                sqlx_opts = sqlx_opts.log_slow_statements(\n                    options.sqlx_slow_statements_logging_level,\n                    options.sqlx_slow_statements_logging_threshold,\n                );\n            }\n        }\n\n        if let Some(application_name) = &options.application_name {\n            sqlx_opts = sqlx_opts.application_name(application_name);\n        }\n\n        if let Some(timeout) = options.statement_timeout {\n            sqlx_opts = sqlx_opts.options([(\"statement_timeout\", timeout.as_millis().to_string())]);\n        }\n\n        if let Some(f) = &options.pg_opts_fn {\n            sqlx_opts = f(sqlx_opts);\n        }\n\n        let set_search_path_sql = options.schema_search_path.as_ref().map(|schema| {\n            let mut string = \"SET search_path = \".to_owned();\n            if schema.starts_with('\"') {\n                write!(&mut string, \"{schema}\").expect(\"Infallible\");\n            } else {\n                for (i, schema) in schema.split(',').enumerate() {\n                    if i > 0 {\n                        write!(&mut string, \",\").expect(\"Infallible\");\n                    }\n                    if schema.starts_with('\"') {\n                        write!(&mut string, \"{schema}\").expect(\"Infallible\");\n                    } else {\n                        write!(&mut string, \"\\\"{schema}\\\"\").expect(\"Infallible\");\n                    }\n                }\n            }\n            string\n        });\n\n        let lazy = options.connect_lazy;\n        let after_connect = options.after_connect.clone();\n        let mut pool_options = options.sqlx_pool_options();\n\n        if let Some(sql) = set_search_path_sql {\n            pool_options = pool_options.after_connect(move |conn, _| {\n                let sql = sql.clone();\n                ({ sqlx::Executor::execute(conn, sql.as_str()).map(|_| ()) })\n            });\n        }\n\n        let pool = if lazy {\n            pool_options.connect_lazy_with(sqlx_opts)\n        } else {\n            pool_options\n                .connect_with(sqlx_opts)\n                .map_err(sqlx_error_to_conn_err)?\n        };\n\n        let conn: DatabaseConnection =\n            DatabaseConnectionType::SqlxPostgresPoolConnection(SqlxPostgresPoolConnection {\n                pool,\n                metric_callback: None,\n            })\n            .into();\n\n        if let Some(cb) = after_connect {\n            cb(conn.clone())?;\n        }\n\n        Ok(conn)\n    }\n}\n\nimpl SqlxPostgresConnector {\n    /// Instantiate a sqlx pool connection to a [DatabaseConnection]\n    pub fn from_sqlx_postgres_pool(pool: PgPool) -> DatabaseConnection {\n        DatabaseConnectionType::SqlxPostgresPoolConnection(SqlxPostgresPoolConnection {\n            pool,\n            metric_callback: None,\n        })\n        .into()\n    }\n}\n\nimpl SqlxPostgresPoolConnection {\n    /// Execute a [Statement] on a PostgreSQL backend\n    #[instrument(level = \"trace\")]\n    pub fn execute(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.execute(&mut *conn) {\n                Ok(res) => Ok(res.into()),\n                Err(err) => Err(sqlx_error_to_exec_err(err)),\n            }\n        })\n    }\n\n    /// Execute an unprepared SQL statement on a PostgreSQL backend\n    #[instrument(level = \"trace\")]\n    pub fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", sql);\n\n        let conn = &mut self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        match conn.execute(sql) {\n            Ok(res) => Ok(res.into()),\n            Err(err) => Err(sqlx_error_to_exec_err(err)),\n        }\n    }\n\n    /// Get one result from a SQL query. Returns [Option::None] if no match was found\n    #[instrument(level = \"trace\")]\n    pub fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.fetch_one(&mut *conn) {\n                Ok(row) => Ok(Some(row.into())),\n                Err(err) => match err {\n                    sqlx::Error::RowNotFound => Ok(None),\n                    _ => Err(sqlx_error_to_query_err(err)),\n                },\n            }\n        })\n    }\n\n    /// Get the results of a query returning them as a Vec<[QueryResult]>\n    #[instrument(level = \"trace\")]\n    pub fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.fetch_all(&mut *conn) {\n                Ok(rows) => Ok(rows.into_iter().map(|r| r.into()).collect()),\n                Err(err) => Err(sqlx_error_to_query_err(err)),\n            }\n        })\n    }\n\n    /// Stream the results of executing a SQL query\n    #[instrument(level = \"trace\")]\n    pub fn stream(&self, stmt: Statement) -> Result<QueryStream, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        Ok(QueryStream::from((\n            conn,\n            stmt,\n            self.metric_callback.clone(),\n        )))\n    }\n\n    /// Bundle a set of SQL statements that execute together.\n    #[instrument(level = \"trace\")]\n    pub fn begin(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        let conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        DatabaseTransaction::new_postgres(\n            conn,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n        )\n    }\n\n    /// Create a PostgreSQL transaction\n    #[instrument(level = \"trace\", skip(callback))]\n    pub fn transaction<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'b> FnOnce(&'b DatabaseTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        let conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        let transaction = DatabaseTransaction::new_postgres(\n            conn,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n        )\n        .map_err(|e| TransactionError::Connection(e))?;\n        transaction.run(callback)\n    }\n\n    pub(crate) fn set_metric_callback<F>(&mut self, callback: F)\n    where\n        F: Fn(&crate::metric::Info<'_>) + 'static,\n    {\n        self.metric_callback = Some(Arc::new(callback));\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub fn ping(&self) -> Result<(), DbErr> {\n        let conn = &mut self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        match conn.ping() {\n            Ok(_) => Ok(()),\n            Err(err) => Err(sqlx_error_to_conn_err(err)),\n        }\n    }\n\n    /// Explicitly close the Postgres connection.\n    /// See [`Self::close_by_ref`] for usage with references.\n    pub fn close(self) -> Result<(), DbErr> {\n        self.close_by_ref()\n    }\n\n    /// Explicitly close the Postgres connection\n    pub fn close_by_ref(&self) -> Result<(), DbErr> {\n        self.pool.close();\n        Ok(())\n    }\n}\n\nimpl From<PgRow> for QueryResult {\n    fn from(row: PgRow) -> QueryResult {\n        QueryResult {\n            row: QueryResultRow::SqlxPostgres(row),\n        }\n    }\n}\n\nimpl From<PgQueryResult> for ExecResult {\n    fn from(result: PgQueryResult) -> ExecResult {\n        ExecResult {\n            result: ExecResultHolder::SqlxPostgres(result),\n        }\n    }\n}\n\npub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Postgres, SqlxValues> {\n    let values = stmt\n        .values\n        .as_ref()\n        .map_or(Values(Vec::new()), |values| values.clone());\n    sqlx::query_with(&stmt.sql, SqlxValues(values))\n}\n\npub(crate) fn set_transaction_config(\n    conn: &mut PoolConnection<Postgres>,\n    isolation_level: Option<IsolationLevel>,\n    access_mode: Option<AccessMode>,\n) -> Result<(), DbErr> {\n    let mut settings = Vec::new();\n\n    if let Some(isolation_level) = isolation_level {\n        settings.push(format!(\"ISOLATION LEVEL {isolation_level}\"));\n    }\n\n    if let Some(access_mode) = access_mode {\n        settings.push(access_mode.to_string());\n    }\n\n    if !settings.is_empty() {\n        let sql = format!(\"SET TRANSACTION {}\", settings.join(\" \"));\n        sqlx::query(&sql)\n            .execute(&mut **conn)\n            .map_err(sqlx_error_to_exec_err)?;\n    }\n    Ok(())\n}\n\nimpl\n    From<(\n        PoolConnection<sqlx::Postgres>,\n        Statement,\n        Option<crate::metric::Callback>,\n    )> for crate::QueryStream\n{\n    fn from(\n        (conn, stmt, metric_callback): (\n            PoolConnection<sqlx::Postgres>,\n            Statement,\n            Option<crate::metric::Callback>,\n        ),\n    ) -> Self {\n        crate::QueryStream::build(\n            stmt,\n            crate::InnerConnection::Postgres(conn),\n            metric_callback,\n        )\n    }\n}\n\nimpl crate::DatabaseTransaction {\n    pub(crate) fn new_postgres(\n        inner: PoolConnection<sqlx::Postgres>,\n        metric_callback: Option<crate::metric::Callback>,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<crate::DatabaseTransaction, DbErr> {\n        Self::begin(\n            Arc::new(Mutex::new(crate::InnerConnection::Postgres(inner))),\n            crate::DbBackend::Postgres,\n            metric_callback,\n            isolation_level,\n            access_mode,\n            None,\n        )\n    }\n}\n\n#[cfg(feature = \"proxy\")]\npub(crate) fn from_sqlx_postgres_row_to_proxy_row(row: &sqlx::postgres::PgRow) -> crate::ProxyRow {\n    // https://docs.rs/sqlx-postgres/0.7.2/src/sqlx_postgres/type_info.rs.html\n    // https://docs.rs/sqlx-postgres/0.7.2/sqlx_postgres/types/index.html\n    use sea_query::Value;\n    use sqlx::{Column, Row, TypeInfo};\n    crate::ProxyRow {\n        values: row\n            .columns()\n            .iter()\n            .map(|c| {\n                (\n                    c.name().to_string(),\n                    match c.type_info().name() {\n                        \"BOOL\" => {\n                            Value::Bool(row.try_get(c.ordinal()).expect(\"Failed to get boolean\"))\n                        }\n                        #[cfg(feature = \"postgres-array\")]\n                        \"BOOL[]\" => Value::Array(\n                            sea_query::ArrayType::Bool,\n                            row.try_get::<Option<Vec<bool>>, _>(c.ordinal())\n                                .expect(\"Failed to get boolean array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Bool(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"\\\"CHAR\\\"\" => Value::TinyInt(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get small integer\"),\n                        ),\n                        #[cfg(feature = \"postgres-array\")]\n                        \"\\\"CHAR\\\"[]\" => Value::Array(\n                            sea_query::ArrayType::TinyInt,\n                            row.try_get::<Option<Vec<i8>>, _>(c.ordinal())\n                                .expect(\"Failed to get small integer array\")\n                                .map(|vals: Vec<i8>| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::TinyInt(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"SMALLINT\" | \"SMALLSERIAL\" | \"INT2\" => Value::SmallInt(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get small integer\"),\n                        ),\n                        #[cfg(feature = \"postgres-array\")]\n                        \"SMALLINT[]\" | \"SMALLSERIAL[]\" | \"INT2[]\" => Value::Array(\n                            sea_query::ArrayType::SmallInt,\n                            row.try_get::<Option<Vec<i16>>, _>(c.ordinal())\n                                .expect(\"Failed to get small integer array\")\n                                .map(|vals: Vec<i16>| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::SmallInt(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"INT\" | \"SERIAL\" | \"INT4\" => {\n                            Value::Int(row.try_get(c.ordinal()).expect(\"Failed to get integer\"))\n                        }\n                        #[cfg(feature = \"postgres-array\")]\n                        \"INT[]\" | \"SERIAL[]\" | \"INT4[]\" => Value::Array(\n                            sea_query::ArrayType::Int,\n                            row.try_get::<Option<Vec<i32>>, _>(c.ordinal())\n                                .expect(\"Failed to get integer array\")\n                                .map(|vals: Vec<i32>| {\n                                    Box::new(\n                                        vals.into_iter().map(|val| Value::Int(Some(val))).collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"BIGINT\" | \"BIGSERIAL\" | \"INT8\" => Value::BigInt(\n                            row.try_get(c.ordinal()).expect(\"Failed to get big integer\"),\n                        ),\n                        #[cfg(feature = \"postgres-array\")]\n                        \"BIGINT[]\" | \"BIGSERIAL[]\" | \"INT8[]\" => Value::Array(\n                            sea_query::ArrayType::BigInt,\n                            row.try_get::<Option<Vec<i64>>, _>(c.ordinal())\n                                .expect(\"Failed to get big integer array\")\n                                .map(|vals: Vec<i64>| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::BigInt(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"FLOAT4\" | \"REAL\" => {\n                            Value::Float(row.try_get(c.ordinal()).expect(\"Failed to get float\"))\n                        }\n                        #[cfg(feature = \"postgres-array\")]\n                        \"FLOAT4[]\" | \"REAL[]\" => Value::Array(\n                            sea_query::ArrayType::Float,\n                            row.try_get::<Option<Vec<f32>>, _>(c.ordinal())\n                                .expect(\"Failed to get float array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Float(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"FLOAT8\" | \"DOUBLE PRECISION\" => {\n                            Value::Double(row.try_get(c.ordinal()).expect(\"Failed to get double\"))\n                        }\n                        #[cfg(feature = \"postgres-array\")]\n                        \"FLOAT8[]\" | \"DOUBLE PRECISION[]\" => Value::Array(\n                            sea_query::ArrayType::Double,\n                            row.try_get::<Option<Vec<f64>>, _>(c.ordinal())\n                                .expect(\"Failed to get double array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Double(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"VARCHAR\" | \"CHAR\" | \"TEXT\" | \"NAME\" => Value::String(\n                            row.try_get::<Option<String>, _>(c.ordinal())\n                                .expect(\"Failed to get string\"),\n                        ),\n                        #[cfg(feature = \"postgres-array\")]\n                        \"VARCHAR[]\" | \"CHAR[]\" | \"TEXT[]\" | \"NAME[]\" => Value::Array(\n                            sea_query::ArrayType::String,\n                            row.try_get::<Option<Vec<String>>, _>(c.ordinal())\n                                .expect(\"Failed to get string array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::String(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"BYTEA\" => Value::Bytes(\n                            row.try_get::<Option<Vec<u8>>, _>(c.ordinal())\n                                .expect(\"Failed to get bytes\"),\n                        ),\n                        #[cfg(feature = \"postgres-array\")]\n                        \"BYTEA[]\" => Value::Array(\n                            sea_query::ArrayType::Bytes,\n                            row.try_get::<Option<Vec<Vec<u8>>>, _>(c.ordinal())\n                                .expect(\"Failed to get bytes array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Bytes(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-bigdecimal\")]\n                        \"NUMERIC\" => Value::BigDecimal(\n                            row.try_get::<Option<bigdecimal::BigDecimal>, _>(c.ordinal())\n                                .expect(\"Failed to get numeric\"),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-rust_decimal\",\n                            not(feature = \"with-bigdecimal\")\n                        ))]\n                        \"NUMERIC\" => {\n                            Value::Decimal(row.try_get(c.ordinal()).expect(\"Failed to get numeric\"))\n                        }\n\n                        #[cfg(all(feature = \"with-bigdecimal\", feature = \"postgres-array\"))]\n                        \"NUMERIC[]\" => Value::Array(\n                            sea_query::ArrayType::BigDecimal,\n                            row.try_get::<Option<Vec<bigdecimal::BigDecimal>>, _>(c.ordinal())\n                                .expect(\"Failed to get numeric array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::BigDecimal(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-rust_decimal\",\n                            not(feature = \"with-bigdecimal\"),\n                            feature = \"postgres-array\"\n                        ))]\n                        \"NUMERIC[]\" => Value::Array(\n                            sea_query::ArrayType::Decimal,\n                            row.try_get::<Option<Vec<rust_decimal::Decimal>>, _>(c.ordinal())\n                                .expect(\"Failed to get numeric array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Decimal(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"OID\" => {\n                            Value::BigInt(row.try_get(c.ordinal()).expect(\"Failed to get oid\"))\n                        }\n                        #[cfg(feature = \"postgres-array\")]\n                        \"OID[]\" => Value::Array(\n                            sea_query::ArrayType::BigInt,\n                            row.try_get::<Option<Vec<i64>>, _>(c.ordinal())\n                                .expect(\"Failed to get oid array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::BigInt(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"JSON\" | \"JSONB\" => Value::Json(\n                            row.try_get::<Option<serde_json::Value>, _>(c.ordinal())\n                                .expect(\"Failed to get json\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(any(feature = \"json-array\", feature = \"postgres-array\"))]\n                        \"JSON[]\" | \"JSONB[]\" => Value::Array(\n                            sea_query::ArrayType::Json,\n                            row.try_get::<Option<Vec<serde_json::Value>>, _>(c.ordinal())\n                                .expect(\"Failed to get json array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Json(Some(Box::new(val))))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-ipnetwork\")]\n                        \"INET\" | \"CIDR\" => Value::IpNetwork(\n                            row.try_get::<Option<ipnetwork::IpNetwork>, _>(c.ordinal())\n                                .expect(\"Failed to get ip address\"),\n                        ),\n                        #[cfg(feature = \"with-ipnetwork\")]\n                        \"INET[]\" | \"CIDR[]\" => Value::Array(\n                            sea_query::ArrayType::IpNetwork,\n                            row.try_get::<Option<Vec<ipnetwork::IpNetwork>>, _>(c.ordinal())\n                                .expect(\"Failed to get ip address array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::IpNetwork(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-mac_address\")]\n                        \"MACADDR\" | \"MACADDR8\" => Value::MacAddress(\n                            row.try_get::<Option<mac_address::MacAddress>, _>(c.ordinal())\n                                .expect(\"Failed to get mac address\"),\n                        ),\n                        #[cfg(all(feature = \"with-mac_address\", feature = \"postgres-array\"))]\n                        \"MACADDR[]\" | \"MACADDR8[]\" => Value::Array(\n                            sea_query::ArrayType::MacAddress,\n                            row.try_get::<Option<Vec<mac_address::MacAddress>>, _>(c.ordinal())\n                                .expect(\"Failed to get mac address array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::MacAddress(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIMESTAMP\" => Value::ChronoDateTime(\n                            row.try_get::<Option<chrono::NaiveDateTime>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamp\"),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIMESTAMP\" => Value::TimeDateTime(\n                            row.try_get::<Option<time::PrimitiveDateTime>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamp\"),\n                        ),\n\n                        #[cfg(all(feature = \"with-chrono\", feature = \"postgres-array\"))]\n                        \"TIMESTAMP[]\" => Value::Array(\n                            sea_query::ArrayType::ChronoDateTime,\n                            row.try_get::<Option<Vec<chrono::NaiveDateTime>>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamp array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::ChronoDateTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-time\",\n                            not(feature = \"with-chrono\"),\n                            feature = \"postgres-array\"\n                        ))]\n                        \"TIMESTAMP[]\" => Value::Array(\n                            sea_query::ArrayType::TimeDateTime,\n                            row.try_get::<Option<Vec<time::PrimitiveDateTime>>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamp array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::TimeDateTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"DATE\" => Value::ChronoDate(\n                            row.try_get::<Option<chrono::NaiveDate>, _>(c.ordinal())\n                                .expect(\"Failed to get date\"),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"DATE\" => Value::TimeDate(\n                            row.try_get::<Option<time::Date>, _>(c.ordinal())\n                                .expect(\"Failed to get date\"),\n                        ),\n\n                        #[cfg(all(feature = \"with-chrono\", feature = \"postgres-array\"))]\n                        \"DATE[]\" => Value::Array(\n                            sea_query::ArrayType::ChronoDate,\n                            row.try_get::<Option<Vec<chrono::NaiveDate>>, _>(c.ordinal())\n                                .expect(\"Failed to get date array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::ChronoDate(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-time\",\n                            not(feature = \"with-chrono\"),\n                            feature = \"postgres-array\"\n                        ))]\n                        \"DATE[]\" => Value::Array(\n                            sea_query::ArrayType::TimeDate,\n                            row.try_get::<Option<Vec<time::Date>>, _>(c.ordinal())\n                                .expect(\"Failed to get date array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::TimeDate(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIME\" => Value::ChronoTime(\n                            row.try_get::<Option<chrono::NaiveTime>, _>(c.ordinal())\n                                .expect(\"Failed to get time\"),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIME\" => Value::TimeTime(\n                            row.try_get::<Option<time::Time>, _>(c.ordinal())\n                                .expect(\"Failed to get time\"),\n                        ),\n\n                        #[cfg(all(feature = \"with-chrono\", feature = \"postgres-array\"))]\n                        \"TIME[]\" => Value::Array(\n                            sea_query::ArrayType::ChronoTime,\n                            row.try_get::<Option<Vec<chrono::NaiveTime>>, _>(c.ordinal())\n                                .expect(\"Failed to get time array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::ChronoTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-time\",\n                            not(feature = \"with-chrono\"),\n                            feature = \"postgres-array\"\n                        ))]\n                        \"TIME[]\" => Value::Array(\n                            sea_query::ArrayType::TimeTime,\n                            row.try_get::<Option<Vec<time::Time>>, _>(c.ordinal())\n                                .expect(\"Failed to get time array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::TimeTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIMESTAMPTZ\" => Value::ChronoDateTimeUtc(\n                            row.try_get::<Option<chrono::DateTime<chrono::Utc>>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamptz\"),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIMESTAMPTZ\" => Value::TimeDateTime(\n                            row.try_get::<Option<time::PrimitiveDateTime>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamptz\"),\n                        ),\n\n                        #[cfg(all(feature = \"with-chrono\", feature = \"postgres-array\"))]\n                        \"TIMESTAMPTZ[]\" => Value::Array(\n                            sea_query::ArrayType::ChronoDateTimeUtc,\n                            row.try_get::<Option<Vec<chrono::DateTime<chrono::Utc>>>, _>(\n                                c.ordinal(),\n                            )\n                            .expect(\"Failed to get timestamptz array\")\n                            .map(|vals| {\n                                Box::new(\n                                    vals.into_iter()\n                                        .map(|val| Value::ChronoDateTimeUtc(Some(val)))\n                                        .collect(),\n                                )\n                            }),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-time\",\n                            not(feature = \"with-chrono\"),\n                            feature = \"postgres-array\"\n                        ))]\n                        \"TIMESTAMPTZ[]\" => Value::Array(\n                            sea_query::ArrayType::TimeDateTime,\n                            row.try_get::<Option<Vec<time::PrimitiveDateTime>>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamptz array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::TimeDateTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIMETZ\" => Value::ChronoTime(\n                            row.try_get::<Option<chrono::NaiveTime>, _>(c.ordinal())\n                                .expect(\"Failed to get timetz\"),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIMETZ\" => {\n                            Value::TimeTime(row.try_get(c.ordinal()).expect(\"Failed to get timetz\"))\n                        }\n\n                        #[cfg(all(feature = \"with-chrono\", feature = \"postgres-array\"))]\n                        \"TIMETZ[]\" => Value::Array(\n                            sea_query::ArrayType::ChronoTime,\n                            row.try_get::<Option<Vec<chrono::NaiveTime>>, _>(c.ordinal())\n                                .expect(\"Failed to get timetz array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::ChronoTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-time\",\n                            not(feature = \"with-chrono\"),\n                            feature = \"postgres-array\"\n                        ))]\n                        \"TIMETZ[]\" => Value::Array(\n                            sea_query::ArrayType::TimeTime,\n                            row.try_get::<Option<Vec<time::Time>>, _>(c.ordinal())\n                                .expect(\"Failed to get timetz array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::TimeTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-uuid\")]\n                        \"UUID\" => Value::Uuid(\n                            row.try_get::<Option<uuid::Uuid>, _>(c.ordinal())\n                                .expect(\"Failed to get uuid\"),\n                        ),\n\n                        #[cfg(all(feature = \"with-uuid\", feature = \"postgres-array\"))]\n                        \"UUID[]\" => Value::Array(\n                            sea_query::ArrayType::Uuid,\n                            row.try_get::<Option<Vec<uuid::Uuid>>, _>(c.ordinal())\n                                .expect(\"Failed to get uuid array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Uuid(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        _ => unreachable!(\"Unknown column type: {}\", c.type_info().name()),\n                    },\n                )\n            })\n            .collect(),\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/driver/sqlx_sqlite.rs",
    "content": "use log::LevelFilter;\nuse sea_query::Values;\nuse std::sync::Arc;\nuse std::sync::Mutex;\n\nuse sqlx::{\n    Connection, Executor, Sqlite, SqlitePool,\n    pool::PoolConnection,\n    sqlite::{SqliteConnectOptions, SqliteQueryResult, SqliteRow},\n};\n\nuse sea_query_sqlx::SqlxValues;\nuse tracing::{instrument, warn};\n\nuse crate::{\n    AccessMode, ConnectOptions, DatabaseConnection, DatabaseConnectionType, DatabaseTransaction,\n    IsolationLevel, QueryStream, SqliteTransactionMode, Statement, TransactionError, debug_print,\n    error::*, executor::*, sqlx_error_to_exec_err,\n};\n\nuse super::sqlx_common::*;\n\n/// Defines the [sqlx::sqlite] connector\n#[derive(Debug)]\npub struct SqlxSqliteConnector;\n\n/// Defines a sqlx SQLite pool\n#[derive(Clone)]\npub struct SqlxSqlitePoolConnection {\n    pub(crate) pool: SqlitePool,\n    metric_callback: Option<crate::metric::Callback>,\n}\n\nimpl std::fmt::Debug for SqlxSqlitePoolConnection {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"SqlxSqlitePoolConnection {{ pool: {:?} }}\", self.pool)\n    }\n}\n\nimpl From<SqlitePool> for SqlxSqlitePoolConnection {\n    fn from(pool: SqlitePool) -> Self {\n        SqlxSqlitePoolConnection {\n            pool,\n            metric_callback: None,\n        }\n    }\n}\n\nimpl From<SqlitePool> for DatabaseConnection {\n    fn from(pool: SqlitePool) -> Self {\n        DatabaseConnectionType::SqlxSqlitePoolConnection(pool.into()).into()\n    }\n}\n\nimpl SqlxSqliteConnector {\n    /// Check if the URI provided corresponds to `sqlite:` for a SQLite database\n    pub fn accepts(string: &str) -> bool {\n        string.starts_with(\"sqlite:\") && string.parse::<SqliteConnectOptions>().is_ok()\n    }\n\n    /// Add configuration options for the SQLite database\n    #[instrument(level = \"trace\")]\n    pub fn connect(options: ConnectOptions) -> Result<DatabaseConnection, DbErr> {\n        let mut options = options;\n        let mut sqlx_opts = options\n            .url\n            .parse::<SqliteConnectOptions>()\n            .map_err(sqlx_error_to_conn_err)?;\n        if let Some(sqlcipher_key) = &options.sqlcipher_key {\n            sqlx_opts = sqlx_opts.pragma(\"key\", sqlcipher_key.clone());\n        }\n        use sqlx::ConnectOptions;\n        if !options.sqlx_logging {\n            sqlx_opts = sqlx_opts.disable_statement_logging();\n        } else {\n            sqlx_opts = sqlx_opts.log_statements(options.sqlx_logging_level);\n            if options.sqlx_slow_statements_logging_level != LevelFilter::Off {\n                sqlx_opts = sqlx_opts.log_slow_statements(\n                    options.sqlx_slow_statements_logging_level,\n                    options.sqlx_slow_statements_logging_threshold,\n                );\n            }\n        }\n\n        if options.get_max_connections().is_none() {\n            options.max_connections(1);\n        }\n\n        if let Some(f) = &options.sqlite_opts_fn {\n            sqlx_opts = f(sqlx_opts);\n        }\n\n        let after_conn = options.after_connect.clone();\n\n        let pool = if options.connect_lazy {\n            options.sqlx_pool_options().connect_lazy_with(sqlx_opts)\n        } else {\n            options\n                .sqlx_pool_options()\n                .connect_with(sqlx_opts)\n                .map_err(sqlx_error_to_conn_err)?\n        };\n\n        let pool = SqlxSqlitePoolConnection {\n            pool,\n            metric_callback: None,\n        };\n\n        #[cfg(feature = \"sqlite-use-returning-for-3_35\")]\n        {\n            let version = get_version(&pool)?;\n            super::sqlite::ensure_returning_version(&version)?;\n        }\n\n        let conn: DatabaseConnection =\n            DatabaseConnectionType::SqlxSqlitePoolConnection(pool).into();\n\n        if let Some(cb) = after_conn {\n            cb(conn.clone())?;\n        }\n\n        Ok(conn)\n    }\n}\n\nimpl SqlxSqliteConnector {\n    /// Instantiate a sqlx pool connection to a [DatabaseConnection]\n    pub fn from_sqlx_sqlite_pool(pool: SqlitePool) -> DatabaseConnection {\n        DatabaseConnectionType::SqlxSqlitePoolConnection(SqlxSqlitePoolConnection {\n            pool,\n            metric_callback: None,\n        })\n        .into()\n    }\n}\n\nimpl SqlxSqlitePoolConnection {\n    /// Execute a [Statement] on a SQLite backend\n    #[instrument(level = \"trace\")]\n    pub fn execute(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.execute(&mut *conn) {\n                Ok(res) => Ok(res.into()),\n                Err(err) => Err(sqlx_error_to_exec_err(err)),\n            }\n        })\n    }\n\n    /// Execute an unprepared SQL statement on a SQLite backend\n    #[instrument(level = \"trace\")]\n    pub fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", sql);\n\n        let conn = &mut self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        match conn.execute(sql) {\n            Ok(res) => Ok(res.into()),\n            Err(err) => Err(sqlx_error_to_exec_err(err)),\n        }\n    }\n\n    /// Get one result from a SQL query. Returns [Option::None] if no match was found\n    #[instrument(level = \"trace\")]\n    pub fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.fetch_one(&mut *conn) {\n                Ok(row) => Ok(Some(row.into())),\n                Err(err) => match err {\n                    sqlx::Error::RowNotFound => Ok(None),\n                    _ => Err(sqlx_error_to_query_err(err)),\n                },\n            }\n        })\n    }\n\n    /// Get the results of a query returning them as a Vec<[QueryResult]>\n    #[instrument(level = \"trace\")]\n    pub fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.fetch_all(&mut *conn) {\n                Ok(rows) => Ok(rows.into_iter().map(|r| r.into()).collect()),\n                Err(err) => Err(sqlx_error_to_query_err(err)),\n            }\n        })\n    }\n\n    /// Stream the results of executing a SQL query\n    #[instrument(level = \"trace\")]\n    pub fn stream(&self, stmt: Statement) -> Result<QueryStream, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        Ok(QueryStream::from((\n            conn,\n            stmt,\n            self.metric_callback.clone(),\n        )))\n    }\n\n    /// Bundle a set of SQL statements that execute together.\n    #[instrument(level = \"trace\")]\n    pub fn begin(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n        sqlite_transaction_mode: Option<SqliteTransactionMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        let conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        DatabaseTransaction::new_sqlite(\n            conn,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n            sqlite_transaction_mode,\n        )\n    }\n\n    /// Create a SQLite transaction\n    #[instrument(level = \"trace\", skip(callback))]\n    pub fn transaction<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'b> FnOnce(&'b DatabaseTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        let conn = self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        let transaction = DatabaseTransaction::new_sqlite(\n            conn,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n            None,\n        )\n        .map_err(|e| TransactionError::Connection(e))?;\n        transaction.run(callback)\n    }\n\n    pub(crate) fn set_metric_callback<F>(&mut self, callback: F)\n    where\n        F: Fn(&crate::metric::Info<'_>) + 'static,\n    {\n        self.metric_callback = Some(Arc::new(callback));\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub fn ping(&self) -> Result<(), DbErr> {\n        let conn = &mut self.pool.acquire().map_err(sqlx_conn_acquire_err)?;\n        match conn.ping() {\n            Ok(_) => Ok(()),\n            Err(err) => Err(sqlx_error_to_conn_err(err)),\n        }\n    }\n\n    /// Explicitly close the SQLite connection.\n    /// See [`Self::close_by_ref`] for usage with references.\n    pub fn close(self) -> Result<(), DbErr> {\n        self.close_by_ref()\n    }\n\n    /// Explicitly close the SQLite connection\n    pub fn close_by_ref(&self) -> Result<(), DbErr> {\n        self.pool.close();\n        Ok(())\n    }\n}\n\nimpl From<SqliteRow> for QueryResult {\n    fn from(row: SqliteRow) -> QueryResult {\n        QueryResult {\n            row: QueryResultRow::SqlxSqlite(row),\n        }\n    }\n}\n\nimpl From<SqliteQueryResult> for ExecResult {\n    fn from(result: SqliteQueryResult) -> ExecResult {\n        ExecResult {\n            result: ExecResultHolder::SqlxSqlite(result),\n        }\n    }\n}\n\npub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Sqlite, SqlxValues> {\n    let values = stmt\n        .values\n        .as_ref()\n        .map_or(Values(Vec::new()), |values| values.clone());\n    sqlx::query_with(&stmt.sql, SqlxValues(values))\n}\n\npub(crate) fn set_transaction_config(\n    _conn: &mut PoolConnection<Sqlite>,\n    isolation_level: Option<IsolationLevel>,\n    access_mode: Option<AccessMode>,\n) -> Result<(), DbErr> {\n    if isolation_level.is_some() {\n        warn!(\"Setting isolation level in a SQLite transaction isn't supported\");\n    }\n    if access_mode.is_some() {\n        warn!(\"Setting access mode in a SQLite transaction isn't supported\");\n    }\n    Ok(())\n}\n\n#[cfg(feature = \"sqlite-use-returning-for-3_35\")]\nfn get_version(conn: &SqlxSqlitePoolConnection) -> Result<String, DbErr> {\n    let stmt = Statement {\n        sql: \"SELECT sqlite_version()\".to_string(),\n        values: None,\n        db_backend: crate::DbBackend::Sqlite,\n    };\n    conn.query_one(stmt)?\n        .ok_or_else(|| {\n            DbErr::Conn(RuntimeErr::Internal(\n                \"Error reading SQLite version\".to_string(),\n            ))\n        })?\n        .try_get_by(0)\n}\n\nimpl\n    From<(\n        PoolConnection<sqlx::Sqlite>,\n        Statement,\n        Option<crate::metric::Callback>,\n    )> for crate::QueryStream\n{\n    fn from(\n        (conn, stmt, metric_callback): (\n            PoolConnection<sqlx::Sqlite>,\n            Statement,\n            Option<crate::metric::Callback>,\n        ),\n    ) -> Self {\n        crate::QueryStream::build(stmt, crate::InnerConnection::Sqlite(conn), metric_callback)\n    }\n}\n\nimpl crate::DatabaseTransaction {\n    pub(crate) fn new_sqlite(\n        inner: PoolConnection<sqlx::Sqlite>,\n        metric_callback: Option<crate::metric::Callback>,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n        sqlite_transaction_mode: Option<SqliteTransactionMode>,\n    ) -> Result<crate::DatabaseTransaction, DbErr> {\n        Self::begin(\n            Arc::new(Mutex::new(crate::InnerConnection::Sqlite(inner))),\n            crate::DbBackend::Sqlite,\n            metric_callback,\n            isolation_level,\n            access_mode,\n            sqlite_transaction_mode,\n        )\n    }\n}\n\n#[cfg(feature = \"proxy\")]\npub(crate) fn from_sqlx_sqlite_row_to_proxy_row(row: &sqlx::sqlite::SqliteRow) -> crate::ProxyRow {\n    // https://docs.rs/sqlx-sqlite/0.7.2/src/sqlx_sqlite/type_info.rs.html\n    // https://docs.rs/sqlx-sqlite/0.7.2/sqlx_sqlite/types/index.html\n    use sea_query::Value;\n    use sqlx::{Column, Row, TypeInfo};\n    crate::ProxyRow {\n        values: row\n            .columns()\n            .iter()\n            .map(|c| {\n                (\n                    c.name().to_string(),\n                    match c.type_info().name() {\n                        \"BOOLEAN\" => {\n                            Value::Bool(row.try_get(c.ordinal()).expect(\"Failed to get boolean\"))\n                        }\n\n                        \"INTEGER\" => {\n                            Value::Int(row.try_get(c.ordinal()).expect(\"Failed to get integer\"))\n                        }\n\n                        \"BIGINT\" | \"INT8\" => Value::BigInt(\n                            row.try_get(c.ordinal()).expect(\"Failed to get big integer\"),\n                        ),\n\n                        \"REAL\" => {\n                            Value::Double(row.try_get(c.ordinal()).expect(\"Failed to get double\"))\n                        }\n\n                        \"TEXT\" => Value::String(\n                            row.try_get::<Option<String>, _>(c.ordinal())\n                                .expect(\"Failed to get string\")\n                                .map(Box::new),\n                        ),\n\n                        \"BLOB\" => Value::Bytes(\n                            row.try_get::<Option<Vec<u8>>, _>(c.ordinal())\n                                .expect(\"Failed to get bytes\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"DATETIME\" => {\n                            use chrono::{DateTime, Utc};\n\n                            Value::ChronoDateTimeUtc(\n                                row.try_get::<Option<DateTime<Utc>>, _>(c.ordinal())\n                                    .expect(\"Failed to get timestamp\")\n                                    .map(Box::new),\n                            )\n                        }\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"DATETIME\" => {\n                            use time::OffsetDateTime;\n                            Value::TimeDateTimeWithTimeZone(\n                                row.try_get::<Option<OffsetDateTime>, _>(c.ordinal())\n                                    .expect(\"Failed to get timestamp\")\n                                    .map(Box::new),\n                            )\n                        }\n                        #[cfg(feature = \"with-chrono\")]\n                        \"DATE\" => {\n                            use chrono::NaiveDate;\n                            Value::ChronoDate(\n                                row.try_get::<Option<NaiveDate>, _>(c.ordinal())\n                                    .expect(\"Failed to get date\")\n                                    .map(Box::new),\n                            )\n                        }\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"DATE\" => {\n                            use time::Date;\n                            Value::TimeDate(\n                                row.try_get::<Option<Date>, _>(c.ordinal())\n                                    .expect(\"Failed to get date\")\n                                    .map(Box::new),\n                            )\n                        }\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIME\" => {\n                            use chrono::NaiveTime;\n                            Value::ChronoTime(\n                                row.try_get::<Option<NaiveTime>, _>(c.ordinal())\n                                    .expect(\"Failed to get time\")\n                                    .map(Box::new),\n                            )\n                        }\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIME\" => {\n                            use time::Time;\n                            Value::TimeTime(\n                                row.try_get::<Option<Time>, _>(c.ordinal())\n                                    .expect(\"Failed to get time\")\n                                    .map(Box::new),\n                            )\n                        }\n\n                        _ => unreachable!(\"Unknown column type: {}\", c.type_info().name()),\n                    },\n                )\n            })\n            .collect(),\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/dynamic/entity.rs",
    "content": "use super::{FieldType, ModelType};\nuse crate::{ColumnDef, ColumnTrait, DbBackend, EntityTrait, Iterable, ModelTrait, Value};\nuse sea_query::{\n    ArrayType, BinOper, DynIden, Expr, ExprTrait, IntoColumnRef, IntoIden, IntoLikeExpr,\n    IntoTableRef, SelectStatement, SimpleExpr, TableRef,\n};\nuse std::sync::Arc;\n\n#[derive(Debug)]\npub struct Entity {\n    schema_name: Option<Arc<str>>,\n    table_name: Arc<str>,\n    columns: Vec<Column>,\n}\n\n#[derive(Debug)]\npub struct Column {\n    table_name: Arc<str>,\n    column_name: Arc<str>,\n    column_def: ColumnDef,\n    value_type: ArrayType,\n    enum_type_name: Option<Arc<str>>,\n}\n\nimpl Entity {\n    pub fn schema_name(&self) -> Option<&str> {\n        self.schema_name.as_deref()\n    }\n\n    pub fn table_name(&self) -> &str {\n        &self.table_name\n    }\n\n    pub fn table_ref(&self) -> TableRef {\n        match self.schema_name() {\n            Some(schema) => (schema.to_owned(), self.table_name().to_owned()).into_table_ref(),\n            None => self.table_name().to_owned().into_table_ref(),\n        }\n    }\n\n    pub fn iter_columns(&self) -> impl Iterator<Item = &Column> {\n        self.columns.iter()\n    }\n}\n\nimpl Entity {\n    pub fn from_entity<E: EntityTrait>(entity: E) -> Self {\n        Self {\n            schema_name: entity.schema_name().map(Arc::from),\n            table_name: Arc::from(entity.table_name()),\n            columns: <E::Column as Iterable>::iter()\n                .map(|c| {\n                    let (tbl, col) = c.as_column_ref();\n                    Column {\n                        table_name: Arc::from(tbl.inner()),\n                        column_name: Arc::from(col.inner()),\n                        column_def: c.def(),\n                        value_type: <E::Model as ModelTrait>::get_value_type(c),\n                        enum_type_name: c.enum_type_name().map(Arc::from),\n                    }\n                })\n                .collect(),\n        }\n    }\n\n    pub fn to_model_type(&self) -> ModelType {\n        ModelType {\n            fields: self\n                .columns\n                .iter()\n                .map(|c| FieldType {\n                    field: c.column_name.clone(),\n                    type_: c.value_type.clone(),\n                })\n                .collect(),\n        }\n    }\n}\n\nimpl Column {\n    pub fn def(&self) -> ColumnDef {\n        self.column_def.clone()\n    }\n\n    pub fn column_name(&self) -> &str {\n        &self.column_name\n    }\n\n    pub fn enum_type_name(&self) -> Option<&str> {\n        self.enum_type_name.as_deref()\n    }\n\n    pub fn entity_name(&self) -> DynIden {\n        self.table_name.to_string().into_iden()\n    }\n\n    pub fn as_column_ref(&self) -> (DynIden, DynIden) {\n        (\n            self.entity_name(),\n            self.column_name().to_owned().into_iden(),\n        )\n    }\n\n    crate::entity::column::macros::bind_oper!(pub eq, Equal);\n    crate::entity::column::macros::bind_oper!(pub ne, NotEqual);\n    crate::entity::column::macros::bind_oper!(pub gt, GreaterThan);\n    crate::entity::column::macros::bind_oper!(pub gte, GreaterThanOrEqual);\n    crate::entity::column::macros::bind_oper!(pub lt, SmallerThan);\n    crate::entity::column::macros::bind_oper!(pub lte, SmallerThanOrEqual);\n\n    pub fn between<V>(&self, a: V, b: V) -> SimpleExpr\n    where\n        V: Into<Value>,\n    {\n        Expr::col(self.as_column_ref()).between(a, b)\n    }\n\n    pub fn not_between<V>(&self, a: V, b: V) -> SimpleExpr\n    where\n        V: Into<Value>,\n    {\n        Expr::col(self.as_column_ref()).not_between(a, b)\n    }\n\n    pub fn like<T>(&self, s: T) -> SimpleExpr\n    where\n        T: IntoLikeExpr,\n    {\n        Expr::col(self.as_column_ref()).like(s)\n    }\n\n    pub fn not_like<T>(&self, s: T) -> SimpleExpr\n    where\n        T: IntoLikeExpr,\n    {\n        Expr::col(self.as_column_ref()).not_like(s)\n    }\n\n    pub fn starts_with<T>(&self, s: T) -> SimpleExpr\n    where\n        T: Into<String>,\n    {\n        let pattern = format!(\"{}%\", s.into());\n        Expr::col(self.as_column_ref()).like(pattern)\n    }\n\n    pub fn ends_with<T>(&self, s: T) -> SimpleExpr\n    where\n        T: Into<String>,\n    {\n        let pattern = format!(\"%{}\", s.into());\n        Expr::col(self.as_column_ref()).like(pattern)\n    }\n\n    pub fn contains<T>(&self, s: T) -> SimpleExpr\n    where\n        T: Into<String>,\n    {\n        let pattern = format!(\"%{}%\", s.into());\n        Expr::col(self.as_column_ref()).like(pattern)\n    }\n\n    crate::entity::column::macros::bind_func_no_params!(pub max);\n    crate::entity::column::macros::bind_func_no_params!(pub min);\n    crate::entity::column::macros::bind_func_no_params!(pub sum);\n    crate::entity::column::macros::bind_func_no_params!(pub count);\n    crate::entity::column::macros::bind_func_no_params!(pub is_null);\n    crate::entity::column::macros::bind_func_no_params!(pub is_not_null);\n\n    pub fn if_null<V>(&self, v: V) -> SimpleExpr\n    where\n        V: Into<Value>,\n    {\n        Expr::col(self.as_column_ref()).if_null(v)\n    }\n\n    crate::entity::column::macros::bind_vec_func!(pub is_in);\n    crate::entity::column::macros::bind_vec_func!(pub is_not_in);\n\n    crate::entity::column::macros::bind_subquery_func!(pub in_subquery);\n    crate::entity::column::macros::bind_subquery_func!(pub not_in_subquery);\n\n    pub fn into_expr(self) -> Expr {\n        SimpleExpr::Column(self.as_column_ref().into_column_ref())\n    }\n\n    #[allow(clippy::match_single_binding)]\n    pub fn into_returning_expr(self, db_backend: DbBackend) -> Expr {\n        match db_backend {\n            _ => Expr::col(self.column_name().to_owned()),\n        }\n    }\n\n    pub fn select_as(&self, expr: Expr) -> SimpleExpr {\n        crate::entity::column::cast_enum_as(\n            expr,\n            &self.def(),\n            crate::entity::column::select_enum_as,\n        )\n    }\n\n    pub fn save_as(&self, val: Expr) -> SimpleExpr {\n        crate::entity::column::cast_enum_as(val, &self.def(), crate::entity::column::save_enum_as)\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/dynamic/execute.rs",
    "content": "use crate::{\n    ConnectionTrait, DbBackend, DbErr, EntityTrait, FromQueryResult, QueryResult, Select,\n    Statement, dynamic,\n};\nuse itertools::Itertools;\nuse sea_query::{DynIden, Expr, IntoIden, SelectStatement};\nuse std::marker::PhantomData;\n\n#[derive(Debug)]\npub struct SelectModelAndDynModel<M>\nwhere\n    M: FromQueryResult,\n{\n    model: PhantomData<M>,\n    dyn_model: dynamic::ModelType,\n}\n\n#[derive(Clone, Debug)]\npub struct DynSelector<S>\nwhere\n    S: DynSelectorTrait,\n{\n    pub(crate) query: SelectStatement,\n    selector: S,\n}\n\npub trait DynSelectorTrait {\n    type Item: Sized;\n\n    #[allow(clippy::wrong_self_convention)]\n    fn from_raw_query_result(&self, res: QueryResult) -> Result<Self::Item, DbErr>;\n}\n\nimpl<M> DynSelectorTrait for SelectModelAndDynModel<M>\nwhere\n    M: FromQueryResult + Sized,\n{\n    type Item = (M, dynamic::Model);\n\n    fn from_raw_query_result(&self, res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, \"\")?,\n            self.dyn_model.from_query_result(&res, \"\")?,\n        ))\n    }\n}\n\nimpl<E> Select<E>\nwhere\n    E: EntityTrait,\n{\n    pub fn select_also_dyn_model(\n        mut self,\n        table: DynIden,\n        dyn_model: dynamic::ModelType,\n    ) -> DynSelector<SelectModelAndDynModel<E::Model>> {\n        for field in dyn_model.fields.iter() {\n            self.query.expr(Expr::col((\n                table.clone(),\n                field.field().to_owned().into_iden(),\n            )));\n        }\n        DynSelector {\n            query: self.query,\n            selector: SelectModelAndDynModel {\n                model: PhantomData,\n                dyn_model,\n            },\n        }\n    }\n}\n\nimpl<S> DynSelector<S>\nwhere\n    S: DynSelectorTrait,\n{\n    /// Get the SQL statement\n    pub fn into_statement(self, builder: DbBackend) -> Statement {\n        builder.build(&self.query)\n    }\n\n    /// Get an item from the Select query\n    pub fn one<C>(mut self, db: &C) -> Result<Option<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.query.limit(1);\n        let row = db.query_one(&self.query)?;\n        match row {\n            Some(row) => Ok(Some(self.selector.from_raw_query_result(row)?)),\n            None => Ok(None),\n        }\n    }\n\n    /// Get all items from the Select query\n    pub fn all<C>(self, db: &C) -> Result<Vec<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        db.query_all(&self.query)?\n            .into_iter()\n            .map(|row| self.selector.from_raw_query_result(row))\n            .try_collect()\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/dynamic/mod.rs",
    "content": "//! The API of this module is not yet stable, and may have breaking changes between minor versions.\n#![allow(missing_docs)]\n\nmod entity;\nmod execute;\nmod model;\n\npub use entity::*;\npub use execute::*;\npub use model::*;\n"
  },
  {
    "path": "sea-orm-sync/src/dynamic/model.rs",
    "content": "use crate::{DbErr, QueryResult};\nuse sea_query::{ArrayType, DynIden, Value};\nuse std::sync::Arc;\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ModelType {\n    pub fields: Vec<FieldType>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Hash)]\npub struct FieldType {\n    pub(super) field: Arc<str>,\n    pub(super) type_: ArrayType,\n}\n\n#[derive(Debug, Clone, PartialEq)]\npub struct Model {\n    pub fields: Vec<FieldValue>,\n}\n\n#[derive(Debug, Clone, PartialEq)]\npub struct FieldValue {\n    pub(super) field: Arc<str>,\n    pub value: Value,\n}\n\nimpl FieldType {\n    pub fn new(iden: DynIden, type_: ArrayType) -> Self {\n        Self {\n            field: Arc::from(iden.inner()),\n            type_,\n        }\n    }\n\n    pub fn field(&self) -> &str {\n        &self.field\n    }\n}\n\nimpl FieldValue {\n    pub fn field(&self) -> &str {\n        &self.field\n    }\n}\n\nimpl ModelType {\n    pub fn from_query_result(&self, res: &QueryResult, pre: &str) -> Result<Model, DbErr> {\n        let mut fields = Vec::new();\n        for f in self.fields.iter() {\n            fields.push(FieldValue {\n                field: f.field.clone(),\n                value: try_get(res, pre, f.field(), &f.type_)?,\n            });\n        }\n        Ok(Model { fields })\n    }\n}\n\nimpl Model {\n    pub fn try_get(&self, col: &str) -> Result<&Value, DbErr> {\n        for field in &self.fields {\n            if field.field() == col {\n                return Ok(&field.value);\n            }\n        }\n        Err(DbErr::Type(format!(\"{col} not exist\")))\n    }\n}\n\nfn try_get(res: &QueryResult, pre: &str, col: &str, ty: &ArrayType) -> Result<Value, DbErr> {\n    // how to handle postgres-array?\n    Ok(match ty {\n        ArrayType::Bool => Value::Bool(res.try_get(pre, col)?),\n        ArrayType::TinyInt => Value::TinyInt(res.try_get(pre, col)?),\n        ArrayType::SmallInt => Value::SmallInt(res.try_get(pre, col)?),\n        ArrayType::Int => Value::Int(res.try_get(pre, col)?),\n        ArrayType::BigInt => Value::BigInt(res.try_get(pre, col)?),\n        ArrayType::TinyUnsigned => Value::TinyUnsigned(res.try_get(pre, col)?),\n        ArrayType::SmallUnsigned => Value::SmallUnsigned(res.try_get(pre, col)?),\n        ArrayType::Unsigned => Value::Unsigned(res.try_get(pre, col)?),\n        ArrayType::BigUnsigned => Value::BigUnsigned(res.try_get(pre, col)?),\n        ArrayType::Float => Value::Float(res.try_get(pre, col)?),\n        ArrayType::Double => Value::Double(res.try_get(pre, col)?),\n        ArrayType::String => Value::String(res.try_get(pre, col)?),\n        ArrayType::Char => return Err(DbErr::Type(\"Unsupported type: char\".into())),\n        ArrayType::Bytes => Value::Bytes(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-json\")]\n        ArrayType::Json => Value::Json(res.try_get::<Option<_>>(pre, col)?.map(Box::new)),\n\n        #[cfg(feature = \"with-chrono\")]\n        ArrayType::ChronoDate => Value::ChronoDate(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-chrono\")]\n        ArrayType::ChronoTime => Value::ChronoTime(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-chrono\")]\n        ArrayType::ChronoDateTime => Value::ChronoDateTime(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-chrono\")]\n        ArrayType::ChronoDateTimeUtc => Value::ChronoDateTimeUtc(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-chrono\")]\n        ArrayType::ChronoDateTimeLocal => Value::ChronoDateTimeLocal(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-chrono\")]\n        ArrayType::ChronoDateTimeWithTimeZone => {\n            Value::ChronoDateTimeWithTimeZone(res.try_get(pre, col)?)\n        }\n\n        #[cfg(feature = \"with-time\")]\n        ArrayType::TimeDate => Value::TimeDate(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-time\")]\n        ArrayType::TimeTime => Value::TimeTime(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-time\")]\n        ArrayType::TimeDateTime => Value::TimeDateTime(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-time\")]\n        ArrayType::TimeDateTimeWithTimeZone => {\n            Value::TimeDateTimeWithTimeZone(res.try_get(pre, col)?)\n        }\n\n        #[cfg(feature = \"with-uuid\")]\n        ArrayType::Uuid => Value::Uuid(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-rust_decimal\")]\n        ArrayType::Decimal => Value::Decimal(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-bigdecimal\")]\n        ArrayType::BigDecimal => {\n            Value::BigDecimal(res.try_get::<Option<_>>(pre, col)?.map(Box::new))\n        }\n\n        #[cfg(feature = \"with-ipnetwork\")]\n        ArrayType::IpNetwork => Value::IpNetwork(res.try_get(pre, col)?),\n    })\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::{QueryResultRow, database::IntoMockRow, dynamic::Entity};\n\n    #[test]\n    fn test_from_query_result() {\n        let result = QueryResult {\n            row: QueryResultRow::Mock(\n                crate::tests_cfg::cake::Model {\n                    id: 12,\n                    name: \"hello\".into(),\n                }\n                .into_mock_row(),\n            ),\n        };\n        let model_ty = Entity::from_entity(crate::tests_cfg::cake::Entity).to_model_type();\n        assert_eq!(\n            model_ty,\n            ModelType {\n                fields: vec![\n                    FieldType {\n                        field: Arc::from(\"id\"),\n                        type_: ArrayType::Int,\n                    },\n                    FieldType {\n                        field: Arc::from(\"name\"),\n                        type_: ArrayType::String,\n                    },\n                ],\n            }\n        );\n        assert_eq!(\n            model_ty.from_query_result(&result, \"\").unwrap(),\n            Model {\n                fields: vec![\n                    FieldValue {\n                        field: Arc::from(\"id\"),\n                        value: 12i32.into(),\n                    },\n                    FieldValue {\n                        field: Arc::from(\"name\"),\n                        value: \"hello\".into(),\n                    }\n                ],\n            }\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/ARROW.md",
    "content": "# Apache Arrow Type Support in SeaORM\n\nThis document explains Apache Arrow's decimal and timestamp formats and their integration with SeaORM.\n\n## Arrow Decimal Types Overview\n\nApache Arrow provides fixed-point decimal types for representing precise numeric values with a specific precision and scale:\n\n### 1. **Decimal64**\n- **Storage**: 64-bit (8 bytes) fixed-point decimal\n- **Precision**: Up to 18 decimal digits\n- **Format**: `DataType::Decimal64(precision, scale)`\n  - `precision` (u8): Total number of decimal digits (1-18)\n  - `scale` (i8): Number of digits after decimal point (can be negative)\n- **Use case**: Compact precision decimals that fit in an i64 (e.g., prices, exchange rates)\n- **Example**: `Decimal64(10, 2)` represents numbers like `12345678.90`\n\n### 2. **Decimal128**\n- **Storage**: 128-bit (16 bytes) fixed-point decimal\n- **Precision**: Up to 38 decimal digits\n- **Format**: `DataType::Decimal128(precision, scale)`\n  - `precision` (u8): Total number of decimal digits (1-38)\n  - `scale` (i8): Number of digits after decimal point (can be negative)\n- **Use case**: Standard precision decimals (e.g., financial calculations requiring > 18 digits)\n- **Example**: `Decimal128(20, 4)` represents numbers like `9999999999999999.9999`\n\n### 3. **Decimal256**\n- **Storage**: 256-bit (32 bytes) fixed-point decimal\n- **Precision**: Up to 76 decimal digits\n- **Format**: `DataType::Decimal256(precision, scale)`\n  - `precision` (u8): Total number of decimal digits (1-76)\n  - `scale` (i8): Number of digits after decimal point (can be negative)\n- **Use case**: High-precision scientific calculations, very large numbers\n- **Example**: `Decimal256(76, 20)` for extreme precision requirements\n\n### Precision vs Scale\n\n- **Precision**: Total number of significant digits (before + after decimal point)\n- **Scale**: Number of digits after the decimal point\n  - Positive scale: digits after decimal (e.g., scale=2 → `123.45`)\n  - Zero scale: integer (e.g., scale=0 → `12345`)\n  - Negative scale: multiplier (e.g., scale=-2 → `12300` stored as `123`)\n\n**Examples**:\n```\nDecimal64(10, 2)   → Can store: -99999999.99 to 99999999.99 (compact, i64)\nDecimal64(5, 0)    → Can store: -99999 to 99999 (integers, compact)\nDecimal128(20, 4)  → Can store: -9999999999999999.9999 to 9999999999999999.9999\nDecimal128(10, 4)  → Can store: -999999.9999 to 999999.9999\nDecimal256(38, 10) → High precision: up to 28 digits before, 10 after decimal\n```\n\n## SeaORM Decimal Support\n\nSeaORM supports two Rust decimal libraries:\n\n### 1. **rust_decimal** (feature: `with-rust_decimal`)\n- Type: `rust_decimal::Decimal`\n- Precision: 28-29 significant digits\n- Scale: 0-28\n- Storage: 128-bit\n- Value type: `Value::Decimal`\n- Best for: Most business applications, financial calculations\n\n### 2. **bigdecimal** (feature: `with-bigdecimal`)\n- Type: `bigdecimal::BigDecimal`\n- Precision: Arbitrary (limited by memory)\n- Scale: Arbitrary\n- Storage: Variable (uses BigInt internally)\n- Value type: `Value::BigDecimal`\n- Best for: Arbitrary precision requirements, scientific computing\n\n## Arrow → SeaORM Mapping\n\n### Decimal64Array → rust_decimal::Decimal\n- **When**: Feature `with-rust_decimal` is enabled\n- **Limitation**: Precision ≤ 18 (fits in i64)\n- **Conversion**: Cast i64 to i128, then `Decimal::from_i128_with_scale()`\n- **Column Type**: `ColumnType::Decimal(Some((precision, scale)))`\n\n### Decimal64Array → bigdecimal::BigDecimal\n- **When**: Feature `with-bigdecimal` is enabled (fallback if rust_decimal not available)\n- **Conversion**: Convert i64 via BigInt\n- **Column Type**: `ColumnType::Decimal(Some((precision, scale)))`\n\n### Decimal128Array → rust_decimal::Decimal\n- **When**: Feature `with-rust_decimal` is enabled\n- **Limitation**: Precision ≤ 28, Scale ≤ 28\n- **Conversion**: Direct mapping using `i128` to `Decimal::from_i128_with_scale()`\n- **Column Type**: `ColumnType::Decimal(Some((precision, scale)))`\n\n### Decimal128Array → bigdecimal::BigDecimal\n- **When**: Feature `with-bigdecimal` is enabled (fallback if rust_decimal fails or not available)\n- **Limitation**: None (arbitrary precision)\n- **Conversion**: Convert via BigInt\n- **Column Type**: `ColumnType::Decimal(Some((precision, scale)))` or `ColumnType::Money(_)`\n\n### Decimal256Array → bigdecimal::BigDecimal\n- **When**: Feature `with-bigdecimal` is enabled\n- **Required**: BigDecimal for precision > 38\n- **Conversion**: Convert via byte array to BigInt, then apply scale\n- **Column Type**: `ColumnType::Decimal(Some((precision, scale)))`\n\n## Implementation Strategy\n\n1. **Decimal64Array**:\n   - Try `with-rust_decimal` first (always fits, precision ≤ 18)\n   - Fallback to `with-bigdecimal` if needed\n   - Return type error if neither feature is enabled\n\n2. **Decimal128Array**:\n   - Try `with-rust_decimal` first (if precision/scale fit)\n   - Fallback to `with-bigdecimal` if needed\n   - Return type error if neither feature is enabled\n\n3. **Decimal256Array**:\n   - Requires `with-bigdecimal` (rust_decimal can't handle precision > 28)\n   - Convert byte representation to BigInt\n   - Apply scale to create BigDecimal\n\n4. **Null Handling**:\n   - Return `Value::Decimal(None)` or `Value::BigDecimal(None)` for null values\n\n---\n\n# Apache Arrow Timestamp Types Support\n\nArrow provides several temporal types for representing dates, times, and timestamps with varying precision.\n\n## Arrow Temporal Types Overview\n\n### Date Types\n\n#### 1. **Date32**\n- **Storage**: 32-bit signed integer\n- **Unit**: Days since Unix epoch (1970-01-01)\n- **Format**: `DataType::Date32`\n- **Range**: Approximately ±5.8 million years from epoch\n- **Use case**: Calendar dates without time component\n\n#### 2. **Date64**\n- **Storage**: 64-bit signed integer\n- **Unit**: Milliseconds since Unix epoch\n- **Format**: `DataType::Date64`\n- **Range**: Much larger than Date32\n- **Use case**: Dates with millisecond precision (though time is typically zeroed)\n\n### Time Types\n\n#### 1. **Time32**\n- **Storage**: 32-bit signed integer\n- **Units**: Second or Millisecond\n- **Variants**:\n  - `Time32(TimeUnit::Second)` - seconds since midnight\n  - `Time32(TimeUnit::Millisecond)` - milliseconds since midnight\n- **Range**: 0 to 86,399 seconds (00:00:00 to 23:59:59)\n- **Use case**: Time of day without date\n\n#### 2. **Time64**\n- **Storage**: 64-bit signed integer\n- **Units**: Microsecond or Nanosecond\n- **Variants**:\n  - `Time64(TimeUnit::Microsecond)` - microseconds since midnight\n  - `Time64(TimeUnit::Nanosecond)` - nanoseconds since midnight\n- **Range**: 0 to 86,399,999,999,999 nanoseconds\n- **Use case**: High-precision time of day\n\n### Timestamp Types\n\n**Timestamp** types represent absolute points in time with optional timezone.\n\n- **Storage**: 64-bit signed integer\n- **Units**: Second, Millisecond, Microsecond, or Nanosecond\n- **Timezone**: Optional timezone string (e.g., \"UTC\", \"America/New_York\")\n- **Format**: `Timestamp(TimeUnit, Option<String>)`\n\n**Variants**:\n```rust\nDataType::Timestamp(TimeUnit::Second, None)        // No timezone\nDataType::Timestamp(TimeUnit::Millisecond, None)   // No timezone\nDataType::Timestamp(TimeUnit::Microsecond, None)   // No timezone\nDataType::Timestamp(TimeUnit::Nanosecond, None)    // No timezone\n\nDataType::Timestamp(TimeUnit::Second, Some(\"UTC\".into()))      // With timezone\nDataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into())) // With timezone\nDataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into()))  // With timezone\n```\n\n**TimeUnit Precision**:\n- **Second**: 1 second precision (1,000,000,000 ns)\n- **Millisecond**: 1 millisecond precision (1,000,000 ns)\n- **Microsecond**: 1 microsecond precision (1,000 ns)\n- **Nanosecond**: 1 nanosecond precision (highest)\n\n## SeaORM Temporal Type Support\n\nSeaORM supports two Rust datetime libraries for temporal types:\n\n### 1. **chrono** (feature: `with-chrono`) - Preferred\n- Type Mappings:\n  - `chrono::NaiveDate` - Date without timezone\n  - `chrono::NaiveTime` - Time without date/timezone\n  - `chrono::NaiveDateTime` - DateTime without timezone\n  - `chrono::DateTime<Utc>` - DateTime with UTC timezone\n- Value types:\n  - `Value::ChronoDate(Option<NaiveDate>)`\n  - `Value::ChronoTime(Option<NaiveTime>)`\n  - `Value::ChronoDateTime(Option<NaiveDateTime>)`\n  - `Value::ChronoDateTimeUtc(Option<DateTime<Utc>>)`\n- Best for: Most applications needing date/time support\n\n### 2. **time** (feature: `with-time`) - Alternative\n- Type Mappings:\n  - `time::Date` - Date without timezone\n  - `time::Time` - Time without date/timezone\n  - `time::PrimitiveDateTime` - DateTime without timezone\n  - `time::OffsetDateTime` - DateTime with timezone offset\n- Value types:\n  - `Value::TimeDate(Option<Date>)`\n  - `Value::TimeTime(Option<Time>)`\n  - `Value::TimeDateTime(Option<PrimitiveDateTime>)`\n  - `Value::TimeDateTimeWithTimeZone(Option<OffsetDateTime>)`\n- Best for: Projects preferring the `time` crate ecosystem\n\n### Feature Priority\n- **Both enabled**: Prefers `chrono`, with automatic fallback to `time` if type mismatch\n- **Only chrono**: Uses chrono types exclusively\n- **Only time**: Uses time crate types exclusively\n\n## Arrow → SeaORM Timestamp Mapping\n\n### Date32/Date64Array → Date\n\n**chrono**:\n```rust\nDate32Array → chrono::NaiveDate\nDate64Array → chrono::NaiveDate\n```\n- Conversion: Calculate days from epoch (1970-01-01) and add/subtract\n\n**time**:\n```rust\nDate32Array → time::Date\nDate64Array → time::Date\n```\n- Conversion: Julian day calculation (Unix epoch = Julian day 2,440,588)\n\n### Time32/Time64Array → Time\n\n**chrono**:\n```rust\nTime32(Second)      → chrono::NaiveTime\nTime32(Millisecond) → chrono::NaiveTime\nTime64(Microsecond) → chrono::NaiveTime\nTime64(Nanosecond)  → chrono::NaiveTime\n```\n- Conversion: Break down time units into (hours, minutes, seconds, nanoseconds)\n\n**time**:\n```rust\nTime32(Second)      → time::Time\nTime32(Millisecond) → time::Time\nTime64(Microsecond) → time::Time\nTime64(Nanosecond)  → time::Time\n```\n- Conversion: Extract hours, minutes, seconds, and nanoseconds from total time value\n\n### TimestampArray → DateTime\n\n**Without Timezone**:\n- **Arrow**: `Timestamp(TimeUnit, None)`\n- **chrono**: `→ chrono::NaiveDateTime`\n- **time**: `→ time::PrimitiveDateTime`\n- **Column Type**: `ColumnType::DateTime` or `ColumnType::Timestamp`\n\n**With Timezone**:\n- **Arrow**: `Timestamp(TimeUnit, Some(tz))`\n- **chrono**: `→ chrono::DateTime<Utc>`\n- **time**: `→ time::OffsetDateTime`\n- **Column Type**: `ColumnType::TimestampWithTimeZone`\n\n### Conversion Details by TimeUnit\n\n| TimeUnit | Conversion Method | Precision |\n|----------|-------------------|-----------|\n| **Second** | `from_timestamp(secs, 0)` | 1 second |\n| **Millisecond** | `from_timestamp_millis(ms)` | 1 millisecond |\n| **Microsecond** | `from_timestamp_micros(us)` | 1 microsecond |\n| **Nanosecond** | `from_timestamp_nanos(ns)` or `from_timestamp(secs, nsecs)` | 1 nanosecond |\n\n## References\n\n- [Arrow DataType Documentation](https://docs.rs/arrow/latest/arrow/datatypes/enum.DataType.html)\n- [Arrow Decimal Module](https://arrow.apache.org/rust/arrow_data/decimal/index.html)\n- [Decimal256Type](https://arrow.apache.org/rust/arrow/datatypes/struct.Decimal256Type.html)\n- [Arrow Temporal Types](https://arrow.apache.org/docs/python/api/datatypes.html#temporal-types)\n"
  },
  {
    "path": "sea-orm-sync/src/entity/DESIGN.md",
    "content": "# Design\n\n### Turbofish and inference\n\nConsider the following method:\n```rust\nfn left_join<E>(self) -> Self\nwhere\n    E: EntityTrait,\n{\n    // ...\n}\n```\nwhich has to be invoked like:\n```rust\n.left_join::<fruit::Entity>()\n```\n\nIf we instead do:\n```rust\nfn left_join<E>(self, _: E) -> Self\nwhere\n    E: EntityTrait,\n{\n    // ...\n}\n```\nthen the Turbofish can be omitted:\n```rust\n.left_join(fruit::Entity)\n```\nprovided that `fruit::Entity` is a unit struct.\n\n### Builder pattern\n\nInstead of:\n```rust\nfn has_many(entity: Entity, from: Column, to: Column);\n\nhas_many(cake::Entity, cake::Column::Id, fruit::Column::CakeId)\n```\n\nwe'd prefer having a builder and stating the params explicitly:\n```rust\nhas_many(cake::Entity).from(cake::Column::Id).to(fruit::Column::CakeId)\n```\n\n### Method overloading\n\nConsider the following two methods, which accept the same parameter but in different forms:\n\n```rust\nfn method_with_model(m: Model) { ... }\nfn method_with_active_model(a: ActiveModel) { ... }\n```\n\nWe would define a trait\n\n```rust\npub trait IntoActiveModel {\n    fn into_active_model(self) -> ActiveModel;\n}\n```\n\nSuch that `Model` and `ActiveModel` both impl this trait.\n\nIn this way, we can overload the two methods:\n\n```rust\npub fn method<A>(a: A)\nwhere\n    A: IntoActiveModel,\n{\n    let a: ActiveModel = a.into_active_model();\n    ...\n}\n```\n"
  },
  {
    "path": "sea-orm-sync/src/entity/active_enum.rs",
    "content": "use crate::{ColIdx, ColumnDef, DbErr, Iterable, QueryResult, TryFromU64, TryGetError, TryGetable};\nuse sea_query::{DynIden, Expr, ExprTrait, Nullable, SimpleExpr, Value, ValueType};\n\n/// A Rust representation of enum defined in database.\n///\n/// # Implementations\n///\n/// You can implement [ActiveEnum] manually by hand or use the derive macro [DeriveActiveEnum](sea_orm_macros::DeriveActiveEnum).\n///\n/// # Examples\n///\n/// Implementing it manually versus using the derive macro [DeriveActiveEnum](sea_orm_macros::DeriveActiveEnum).\n///\n/// > See [DeriveActiveEnum](sea_orm_macros::DeriveActiveEnum) for the full specification of macro attributes.\n///\n/// ```rust\n/// use sea_orm::entity::prelude::*;\n///\n/// // Using the derive macro\n/// #[derive(Debug, PartialEq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n/// #[sea_orm(\n///     rs_type = \"String\",\n///     db_type = \"String(StringLen::N(1))\",\n///     enum_name = \"category\"\n/// )]\n/// pub enum DeriveCategory {\n///     #[sea_orm(string_value = \"B\")]\n///     Big,\n///     #[sea_orm(string_value = \"S\")]\n///     Small,\n/// }\n///\n/// // Implementing it manually\n/// #[derive(Debug, PartialEq, EnumIter)]\n/// pub enum Category {\n///     Big,\n///     Small,\n/// }\n///\n/// #[derive(Debug, DeriveIden)]\n/// pub struct CategoryEnum;\n///\n/// impl ActiveEnum for Category {\n///     // The macro attribute `rs_type` is being pasted here\n///     type Value = String;\n///\n///     type ValueVec = Vec<String>;\n///\n///     // Will be atomically generated by `DeriveActiveEnum`\n///     fn name() -> DynIden {\n///         SeaRc::new(CategoryEnum)\n///     }\n///\n///     // Will be atomically generated by `DeriveActiveEnum`\n///     fn to_value(&self) -> Self::Value {\n///         match self {\n///             Self::Big => \"B\",\n///             Self::Small => \"S\",\n///         }\n///         .to_owned()\n///     }\n///\n///     // Will be atomically generated by `DeriveActiveEnum`\n///     fn try_from_value(v: &Self::Value) -> Result<Self, DbErr> {\n///         match v.as_ref() {\n///             \"B\" => Ok(Self::Big),\n///             \"S\" => Ok(Self::Small),\n///             _ => Err(DbErr::Type(format!(\n///                 \"unexpected value for Category enum: {}\",\n///                 v\n///             ))),\n///         }\n///     }\n///\n///     fn db_type() -> ColumnDef {\n///         // The macro attribute `db_type` is being pasted here\n///         ColumnType::String(StringLen::N(1)).def()\n///     }\n/// }\n/// ```\n///\n/// Using [ActiveEnum] on Model.\n///\n/// ```\n/// use sea_orm::entity::prelude::*;\n///\n/// // Define the `Category` active enum\n/// #[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n/// #[sea_orm(rs_type = \"String\", db_type = \"String(StringLen::N(1))\")]\n/// pub enum Category {\n///     #[sea_orm(string_value = \"B\")]\n///     Big,\n///     #[sea_orm(string_value = \"S\")]\n///     Small,\n/// }\n///\n/// #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #[sea_orm(table_name = \"active_enum\")]\n/// pub struct Model {\n///     #[sea_orm(primary_key)]\n///     pub id: i32,\n///     // Represents a db column using `Category` active enum\n///     pub category: Category,\n///     pub category_opt: Option<Category>,\n/// }\n///\n/// #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n/// pub enum Relation {}\n///\n/// impl ActiveModelBehavior for ActiveModel {}\n/// ```\npub trait ActiveEnum: Sized + Iterable {\n    /// Define the Rust type that each enum variant corresponds.\n    type Value: ActiveEnumValue;\n\n    /// This has no purpose. It will be removed in the next major version.\n    type ValueVec;\n\n    /// Get the name of enum\n    fn name() -> DynIden;\n\n    /// Convert enum variant into the corresponding value.\n    fn to_value(&self) -> Self::Value;\n\n    /// Try to convert the corresponding value into enum variant.\n    fn try_from_value(v: &Self::Value) -> Result<Self, DbErr>;\n\n    /// Get the database column definition of this active enum.\n    fn db_type() -> ColumnDef;\n\n    /// Convert an owned enum variant into the corresponding value.\n    fn into_value(self) -> Self::Value {\n        Self::to_value(&self)\n    }\n\n    /// Construct a enum expression with casting\n    fn as_enum(&self) -> SimpleExpr {\n        Expr::val(Self::to_value(self)).as_enum(Self::name())\n    }\n\n    /// Get the name of all enum variants\n    fn values() -> Vec<Self::Value> {\n        Self::iter().map(Self::into_value).collect()\n    }\n}\n\n/// The Rust Value backing ActiveEnums\npub trait ActiveEnumValue: Into<Value> + ValueType + Nullable + TryGetable {\n    /// For getting an array of enum. Postgres only\n    fn try_get_vec_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Vec<Self>, TryGetError>;\n}\n\nmacro_rules! impl_active_enum_value {\n    ($type:ident) => {\n        impl ActiveEnumValue for $type {\n            fn try_get_vec_by<I: ColIdx>(\n                _res: &QueryResult,\n                _index: I,\n            ) -> Result<Vec<Self>, TryGetError> {\n                Err(TryGetError::DbErr(DbErr::BackendNotSupported {\n                    db: \"Postgres\",\n                    ctx: \"ActiveEnumValue::try_get_vec_by\",\n                }))\n            }\n        }\n    };\n}\n\nmacro_rules! impl_active_enum_value_with_pg_array {\n    ($type:ident) => {\n        impl ActiveEnumValue for $type {\n            fn try_get_vec_by<I: ColIdx>(\n                _res: &QueryResult,\n                _index: I,\n            ) -> Result<Vec<Self>, TryGetError> {\n                #[cfg(feature = \"postgres-array\")]\n                {\n                    <Vec<Self>>::try_get_by(_res, _index)\n                }\n                #[cfg(not(feature = \"postgres-array\"))]\n                Err(TryGetError::DbErr(DbErr::BackendNotSupported {\n                    db: \"Postgres\",\n                    ctx: \"ActiveEnumValue::try_get_vec_by (`postgres-array` not enabled)\",\n                }))\n            }\n        }\n    };\n}\n\nimpl_active_enum_value!(u8);\nimpl_active_enum_value!(u16);\nimpl_active_enum_value!(u32);\nimpl_active_enum_value!(u64);\nimpl_active_enum_value_with_pg_array!(String);\nimpl_active_enum_value_with_pg_array!(i8);\nimpl_active_enum_value_with_pg_array!(i16);\nimpl_active_enum_value_with_pg_array!(i32);\nimpl_active_enum_value_with_pg_array!(i64);\n\nimpl<T> TryFromU64 for T\nwhere\n    T: ActiveEnum,\n{\n    fn try_from_u64(_: u64) -> Result<Self, DbErr> {\n        Err(DbErr::ConvertFromU64(\n            \"Fail to construct ActiveEnum from a u64, if your primary key consist of a ActiveEnum field, its auto increment should be set to false.\",\n        ))\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate as sea_orm;\n    use crate::{\n        error::*,\n        sea_query::{SeaRc, StringLen},\n        *,\n    };\n    use pretty_assertions::assert_eq;\n\n    #[test]\n    fn active_enum_string() {\n        #[derive(Debug, PartialEq, Eq, EnumIter)]\n        pub enum Category {\n            Big,\n            Small,\n        }\n\n        #[derive(Debug, DeriveIden)]\n        #[sea_orm(iden = \"category\")]\n        pub struct CategoryEnum;\n\n        impl ActiveEnum for Category {\n            type Value = String;\n\n            type ValueVec = Vec<String>;\n\n            fn name() -> DynIden {\n                SeaRc::new(CategoryEnum)\n            }\n\n            fn to_value(&self) -> Self::Value {\n                match self {\n                    Self::Big => \"B\",\n                    Self::Small => \"S\",\n                }\n                .to_owned()\n            }\n\n            fn try_from_value(v: &Self::Value) -> Result<Self, DbErr> {\n                match v.as_ref() {\n                    \"B\" => Ok(Self::Big),\n                    \"S\" => Ok(Self::Small),\n                    _ => Err(type_err(format!(\"unexpected value for Category enum: {v}\"))),\n                }\n            }\n\n            fn db_type() -> ColumnDef {\n                ColumnType::String(StringLen::N(1)).def()\n            }\n        }\n\n        #[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n        #[sea_orm(\n            rs_type = \"String\",\n            db_type = \"String(StringLen::N(1))\",\n            enum_name = \"category\"\n        )]\n        pub enum DeriveCategory {\n            #[sea_orm(string_value = \"B\")]\n            Big,\n            #[sea_orm(string_value = \"S\")]\n            Small,\n        }\n\n        assert_eq!(Category::Big.to_value(), \"B\".to_owned());\n        assert_eq!(Category::Small.to_value(), \"S\".to_owned());\n        assert_eq!(DeriveCategory::Big.to_value(), \"B\".to_owned());\n        assert_eq!(DeriveCategory::Small.to_value(), \"S\".to_owned());\n\n        assert_eq!(\n            Category::try_from_value(&\"A\".to_owned()).err(),\n            Some(type_err(\"unexpected value for Category enum: A\"))\n        );\n        assert_eq!(\n            Category::try_from_value(&\"B\".to_owned()).ok(),\n            Some(Category::Big)\n        );\n        assert_eq!(\n            Category::try_from_value(&\"S\".to_owned()).ok(),\n            Some(Category::Small)\n        );\n        assert_eq!(\n            DeriveCategory::try_from_value(&\"A\".to_owned()).err(),\n            Some(type_err(\"unexpected value for DeriveCategory enum: A\"))\n        );\n        assert_eq!(\n            DeriveCategory::try_from_value(&\"B\".to_owned()).ok(),\n            Some(DeriveCategory::Big)\n        );\n        assert_eq!(\n            DeriveCategory::try_from_value(&\"S\".to_owned()).ok(),\n            Some(DeriveCategory::Small)\n        );\n\n        assert_eq!(\n            Category::db_type(),\n            ColumnType::String(StringLen::N(1)).def()\n        );\n        assert_eq!(\n            DeriveCategory::db_type(),\n            ColumnType::String(StringLen::N(1)).def()\n        );\n\n        assert_eq!(\n            Category::name().to_string(),\n            DeriveCategory::name().to_string()\n        );\n        assert_eq!(Category::values(), DeriveCategory::values());\n\n        assert_eq!(format!(\"{}\", DeriveCategory::Big), \"Big\");\n        assert_eq!(format!(\"{}\", DeriveCategory::Small), \"Small\");\n    }\n\n    #[test]\n    fn active_enum_derive_signed_integers() {\n        macro_rules! test_num_value_int {\n            ($ident: ident, $rs_type: expr, $db_type: expr, $col_def: ident) => {\n                #[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n                #[sea_orm(rs_type = $rs_type, db_type = $db_type)]\n                pub enum $ident {\n                    #[sea_orm(num_value = -10)]\n                    Negative,\n                    #[sea_orm(num_value = 1)]\n                    Big,\n                    #[sea_orm(num_value = 0)]\n                    Small,\n                }\n\n                test_int!($ident, $rs_type, $db_type, $col_def);\n            };\n        }\n\n        macro_rules! test_fallback_int {\n            ($ident: ident, $fallback_type: ident, $rs_type: expr, $db_type: expr, $col_def: ident) => {\n                #[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n                #[sea_orm(rs_type = $rs_type, db_type = $db_type)]\n                #[repr(i32)]\n                pub enum $ident {\n                    Big = 1,\n                    Small = 0,\n                    Negative = -10,\n                }\n\n                test_int!($ident, $rs_type, $db_type, $col_def);\n            };\n        }\n\n        macro_rules! test_int {\n            ($ident: ident, $rs_type: expr, $db_type: expr, $col_def: ident) => {\n                assert_eq!($ident::Big.to_value(), 1);\n                assert_eq!($ident::Small.to_value(), 0);\n                assert_eq!($ident::Negative.to_value(), -10);\n\n                assert_eq!($ident::try_from_value(&1).ok(), Some($ident::Big));\n                assert_eq!($ident::try_from_value(&0).ok(), Some($ident::Small));\n                assert_eq!($ident::try_from_value(&-10).ok(), Some($ident::Negative));\n                assert_eq!(\n                    $ident::try_from_value(&2).err(),\n                    Some(type_err(format!(\n                        \"unexpected value for {} enum: 2\",\n                        stringify!($ident)\n                    )))\n                );\n\n                assert_eq!($ident::db_type(), ColumnType::$col_def.def());\n\n                assert_eq!(format!(\"{}\", $ident::Big), \"Big\");\n                assert_eq!(format!(\"{}\", $ident::Small), \"Small\");\n                assert_eq!(format!(\"{}\", $ident::Negative), \"Negative\");\n            };\n        }\n\n        test_num_value_int!(I8, \"i8\", \"TinyInteger\", TinyInteger);\n        test_num_value_int!(I16, \"i16\", \"SmallInteger\", SmallInteger);\n        test_num_value_int!(I32, \"i32\", \"Integer\", Integer);\n        test_num_value_int!(I64, \"i64\", \"BigInteger\", BigInteger);\n\n        test_fallback_int!(I8Fallback, i8, \"i8\", \"TinyInteger\", TinyInteger);\n        test_fallback_int!(I16Fallback, i16, \"i16\", \"SmallInteger\", SmallInteger);\n        test_fallback_int!(I32Fallback, i32, \"i32\", \"Integer\", Integer);\n        test_fallback_int!(I64Fallback, i64, \"i64\", \"BigInteger\", BigInteger);\n    }\n\n    #[test]\n    fn active_enum_derive_unsigned_integers() {\n        macro_rules! test_num_value_uint {\n            ($ident: ident, $rs_type: expr, $db_type: expr, $col_def: ident) => {\n                #[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n                #[sea_orm(rs_type = $rs_type, db_type = $db_type)]\n                pub enum $ident {\n                    #[sea_orm(num_value = 1)]\n                    Big,\n                    #[sea_orm(num_value = 0)]\n                    Small,\n                }\n\n                test_uint!($ident, $rs_type, $db_type, $col_def);\n            };\n        }\n\n        macro_rules! test_fallback_uint {\n            ($ident: ident, $fallback_type: ident, $rs_type: expr, $db_type: expr, $col_def: ident) => {\n                #[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n                #[sea_orm(rs_type = $rs_type, db_type = $db_type)]\n                #[repr($fallback_type)]\n                pub enum $ident {\n                    Big = 1,\n                    Small = 0,\n                }\n\n                test_uint!($ident, $rs_type, $db_type, $col_def);\n            };\n        }\n\n        macro_rules! test_uint {\n            ($ident: ident, $rs_type: expr, $db_type: expr, $col_def: ident) => {\n                assert_eq!($ident::Big.to_value(), 1);\n                assert_eq!($ident::Small.to_value(), 0);\n\n                assert_eq!($ident::try_from_value(&1).ok(), Some($ident::Big));\n                assert_eq!($ident::try_from_value(&0).ok(), Some($ident::Small));\n                assert_eq!(\n                    $ident::try_from_value(&2).err(),\n                    Some(type_err(format!(\n                        \"unexpected value for {} enum: 2\",\n                        stringify!($ident)\n                    )))\n                );\n\n                assert_eq!($ident::db_type(), ColumnType::$col_def.def());\n\n                assert_eq!(format!(\"{}\", $ident::Big), \"Big\");\n                assert_eq!(format!(\"{}\", $ident::Small), \"Small\");\n            };\n        }\n\n        test_num_value_uint!(U8, \"u8\", \"TinyInteger\", TinyInteger);\n        test_num_value_uint!(U16, \"u16\", \"SmallInteger\", SmallInteger);\n        test_num_value_uint!(U32, \"u32\", \"Integer\", Integer);\n        test_num_value_uint!(U64, \"u64\", \"BigInteger\", BigInteger);\n\n        test_fallback_uint!(U8Fallback, u8, \"u8\", \"TinyInteger\", TinyInteger);\n        test_fallback_uint!(U16Fallback, u16, \"u16\", \"SmallInteger\", SmallInteger);\n        test_fallback_uint!(U32Fallback, u32, \"u32\", \"Integer\", Integer);\n        test_fallback_uint!(U64Fallback, u64, \"u64\", \"BigInteger\", BigInteger);\n    }\n\n    #[test]\n    fn escaped_non_uax31() {\n        #[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Copy)]\n        #[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"pop_os_names_typos\")]\n        pub enum PopOSTypos {\n            #[sea_orm(string_value = \"Pop!_OS\")]\n            PopOSCorrect,\n            #[sea_orm(string_value = \"Pop\\u{2757}_OS\")]\n            PopOSEmoji,\n            #[sea_orm(string_value = \"Pop!_操作系统\")]\n            PopOSChinese,\n            #[sea_orm(string_value = \"PopOS\")]\n            PopOSASCIIOnly,\n            #[sea_orm(string_value = \"Pop OS\")]\n            PopOSASCIIOnlyWithSpace,\n            #[sea_orm(string_value = \"Pop!OS\")]\n            PopOSNoUnderscore,\n            #[sea_orm(string_value = \"Pop_OS\")]\n            PopOSNoExclaimation,\n            #[sea_orm(string_value = \"!PopOS_\")]\n            PopOSAllOverThePlace,\n            #[sea_orm(string_value = \"Pop!_OS22.04LTS\")]\n            PopOSWithVersion,\n            #[sea_orm(string_value = \"22.04LTSPop!_OS\")]\n            PopOSWithVersionPrefix,\n            #[sea_orm(string_value = \"!_\")]\n            PopOSJustTheSymbols,\n            #[sea_orm(string_value = \"\")]\n            Nothing,\n            // This WILL fail:\n            // Both PopOs and PopOS will create identifier \"Popos\"\n            // #[sea_orm(string_value = \"PopOs\")]\n            // PopOSLowerCase,\n        }\n        let values = [\n            \"Pop!_OS\",\n            \"Pop\\u{2757}_OS\",\n            \"Pop!_操作系统\",\n            \"PopOS\",\n            \"Pop OS\",\n            \"Pop!OS\",\n            \"Pop_OS\",\n            \"!PopOS_\",\n            \"Pop!_OS22.04LTS\",\n            \"22.04LTSPop!_OS\",\n            \"!_\",\n            \"\",\n        ];\n        for (variant, val) in PopOSTypos::iter().zip(values) {\n            assert_eq!(variant.to_value(), val);\n            assert_eq!(PopOSTypos::try_from_value(&val.to_owned()), Ok(variant));\n        }\n\n        #[derive(Clone, Debug, PartialEq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n        #[sea_orm(\n            rs_type = \"String\",\n            db_type = \"String(StringLen::None)\",\n            enum_name = \"conflicting_string_values\"\n        )]\n        pub enum ConflictingStringValues {\n            #[sea_orm(string_value = \"\")]\n            Member1,\n            #[sea_orm(string_value = \"$\")]\n            Member2,\n            #[sea_orm(string_value = \"$$\")]\n            Member3,\n            #[sea_orm(string_value = \"AB\")]\n            Member4,\n            #[sea_orm(string_value = \"A_B\")]\n            Member5,\n            #[sea_orm(string_value = \"A$B\")]\n            Member6,\n            #[sea_orm(string_value = \"0 123\")]\n            Member7,\n        }\n        type EnumVariant = ConflictingStringValuesVariant;\n        assert_eq!(EnumVariant::__Empty.to_string(), \"\");\n        assert_eq!(EnumVariant::_0x24.to_string(), \"$\");\n        assert_eq!(EnumVariant::_0x240x24.to_string(), \"$$\");\n        assert_eq!(EnumVariant::Ab.to_string(), \"AB\");\n        assert_eq!(EnumVariant::A0x5Fb.to_string(), \"A_B\");\n        assert_eq!(EnumVariant::A0x24B.to_string(), \"A$B\");\n        assert_eq!(EnumVariant::_0x300x20123.to_string(), \"0 123\");\n    }\n\n    #[test]\n    fn test_derive_display() {\n        use crate::DeriveDisplay;\n\n        #[derive(DeriveDisplay)]\n        enum DisplayTea {\n            EverydayTea,\n            #[sea_orm(display_value = \"Breakfast Tea\")]\n            BreakfastTea,\n        }\n        assert_eq!(format!(\"{}\", DisplayTea::EverydayTea), \"EverydayTea\");\n        assert_eq!(format!(\"{}\", DisplayTea::BreakfastTea), \"Breakfast Tea\");\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/active_model.rs",
    "content": "use super::{ActiveValue, ActiveValue::*};\nuse crate::{\n    ColumnTrait, Condition, ConnectionTrait, DbBackend, DeleteResult, EntityName, EntityTrait,\n    IdenStatic, Iterable, PrimaryKeyArity, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter,\n    Related, RelatedSelfVia, RelationDef, RelationTrait, Value,\n    error::*,\n    query::{\n        clear_key_on_active_model, column_tuple_in_condition, get_key_from_active_model,\n        set_key_on_active_model,\n    },\n};\nuse sea_query::ValueTuple;\nuse std::fmt::Debug;\n\n/// `ActiveModel` is a type for constructing `INSERT` and `UPDATE` statements for a particular table.\n///\n/// Like [Model][ModelTrait], it represents a database record and each field represents a column.\n///\n/// But unlike [Model][ModelTrait], it also stores [additional state][ActiveValue] for every field,\n/// and fields are not guaranteed to have a value.\n///\n/// This allows you to:\n///\n/// - omit columns from the query,\n/// - know which columns have changed after editing a record.\npub trait ActiveModelTrait: Clone + Debug {\n    /// The Entity this ActiveModel belongs to\n    type Entity: EntityTrait;\n\n    /// Get a mutable [ActiveValue] from an ActiveModel\n    fn take(&mut self, c: <Self::Entity as EntityTrait>::Column) -> ActiveValue<Value>;\n\n    /// Get a immutable [ActiveValue] from an ActiveModel\n    fn get(&self, c: <Self::Entity as EntityTrait>::Column) -> ActiveValue<Value>;\n\n    /// Set the Value of a ActiveModel field, panic if failed\n    fn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) {\n        self.try_set(c, v)\n            .unwrap_or_else(|e| panic!(\"Failed to set value for {:?}: {e:?}\", c.as_column_ref()))\n    }\n\n    /// Set the Value of a ActiveModel field if value is different, panic if failed\n    fn set_if_not_equals(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value);\n\n    /// Set the Value of a ActiveModel field, return error if failed\n    fn try_set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) -> Result<(), DbErr>;\n\n    /// Set the state of an [ActiveValue] to the not set state\n    fn not_set(&mut self, c: <Self::Entity as EntityTrait>::Column);\n\n    /// Check the state of a [ActiveValue]\n    fn is_not_set(&self, c: <Self::Entity as EntityTrait>::Column) -> bool;\n\n    /// Create an ActiveModel with all fields to NotSet\n    fn default() -> Self;\n\n    /// Create an ActiveModel with all fields to Set(default_value) if Default is implemented, NotSet otherwise\n    fn default_values() -> Self;\n\n    /// Reset the value from [ActiveValue::Unchanged] to [ActiveValue::Set],\n    /// leaving [ActiveValue::NotSet] untouched.\n    fn reset(&mut self, c: <Self::Entity as EntityTrait>::Column);\n\n    /// Reset all values from [ActiveValue::Unchanged] to [ActiveValue::Set],\n    /// leaving [ActiveValue::NotSet] untouched.\n    fn reset_all(mut self) -> Self {\n        for col in <Self::Entity as EntityTrait>::Column::iter() {\n            self.reset(col);\n        }\n        self\n    }\n\n    /// Get the primary key of the ActiveModel, only if it's fully specified.\n    fn get_primary_key_value(&self) -> Option<ValueTuple> {\n        let mut cols = <Self::Entity as EntityTrait>::PrimaryKey::iter();\n        macro_rules! next {\n            () => {\n                self.get(cols.next()?.into_column()).into_value()?\n            };\n        }\n        match <<<Self::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n            1 => {\n                let s1 = next!();\n                Some(ValueTuple::One(s1))\n            }\n            2 => {\n                let s1 = next!();\n                let s2 = next!();\n                Some(ValueTuple::Two(s1, s2))\n            }\n            3 => {\n                let s1 = next!();\n                let s2 = next!();\n                let s3 = next!();\n                Some(ValueTuple::Three(s1, s2, s3))\n            }\n            len => {\n                let mut vec = Vec::with_capacity(len);\n                for _ in 0..len {\n                    let s = next!();\n                    vec.push(s);\n                }\n                Some(ValueTuple::Many(vec))\n            }\n        }\n    }\n\n    /// Perform an `INSERT` operation on the ActiveModel\n    ///\n    /// # Example (Postgres)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 15,\n    /// #             name: \"Apple Pie\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let apple = cake::ActiveModel {\n    ///     name: Set(\"Apple Pie\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// assert_eq!(\n    ///     apple.insert(&db)?,\n    ///     cake::Model {\n    ///         id: 15,\n    ///         name: \"Apple Pie\".to_owned(),\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"INSERT INTO \"cake\" (\"name\") VALUES ($1) RETURNING \"id\", \"name\"\"#,\n    ///         [\"Apple Pie\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// # Example (MySQL)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::MySql)\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 15,\n    /// #             name: \"Apple Pie\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 15,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let apple = cake::ActiveModel {\n    ///     name: Set(\"Apple Pie\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// assert_eq!(\n    ///     apple.insert(&db)?,\n    ///     cake::Model {\n    ///         id: 15,\n    ///         name: \"Apple Pie\".to_owned(),\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::MySql,\n    ///             r#\"INSERT INTO `cake` (`name`) VALUES (?)\"#,\n    ///             [\"Apple Pie\".into()]\n    ///         ),\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::MySql,\n    ///             r#\"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = ? LIMIT ?\"#,\n    ///             [15.into(), 1u64.into()]\n    ///         )\n    ///     ]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn insert<'a, C>(self, db: &'a C) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>\n    where\n        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,\n        Self: ActiveModelBehavior,\n        C: ConnectionTrait,\n    {\n        let am = ActiveModelBehavior::before_save(self, db, true)?;\n        let model = <Self::Entity as EntityTrait>::insert(am).exec_with_returning(db)?;\n        Self::after_save(model, db, true)\n    }\n\n    /// Perform the `UPDATE` operation on an ActiveModel\n    ///\n    /// # Example (Postgres)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [fruit::Model {\n    /// #             id: 1,\n    /// #             name: \"Orange\".to_owned(),\n    /// #             cake_id: None,\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let orange = fruit::ActiveModel {\n    ///     id: Set(1),\n    ///     name: Set(\"Orange\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// assert_eq!(\n    ///     orange.update(&db)?,\n    ///     fruit::Model {\n    ///         id: 1,\n    ///         name: \"Orange\".to_owned(),\n    ///         cake_id: None,\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"UPDATE \"fruit\" SET \"name\" = $1 WHERE \"fruit\".\"id\" = $2 RETURNING \"id\", \"name\", \"cake_id\"\"#,\n    ///         [\"Orange\".into(), 1i32.into()]\n    ///     )]);\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// # Example (MySQL)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::MySql)\n    /// #     .append_query_results([\n    /// #         [fruit::Model {\n    /// #             id: 1,\n    /// #             name: \"Orange\".to_owned(),\n    /// #             cake_id: None,\n    /// #         }],\n    /// #     ])\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let orange = fruit::ActiveModel {\n    ///     id: Set(1),\n    ///     name: Set(\"Orange\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// assert_eq!(\n    ///     orange.update(&db)?,\n    ///     fruit::Model {\n    ///         id: 1,\n    ///         name: \"Orange\".to_owned(),\n    ///         cake_id: None,\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::MySql,\n    ///             r#\"UPDATE `fruit` SET `name` = ? WHERE `fruit`.`id` = ?\"#,\n    ///             [\"Orange\".into(), 1i32.into()]\n    ///         ),\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::MySql,\n    ///             r#\"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = ? LIMIT ?\"#,\n    ///             [1i32.into(), 1u64.into()]\n    ///         )]);\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn update<'a, C>(self, db: &'a C) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>\n    where\n        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,\n        Self: ActiveModelBehavior,\n        C: ConnectionTrait,\n    {\n        let am = ActiveModelBehavior::before_save(self, db, false)?;\n        let model: <Self::Entity as EntityTrait>::Model = Self::Entity::update(am).exec(db)?;\n        Self::after_save(model, db, false)\n    }\n\n    /// Insert the model if primary key is `NotSet`, update otherwise.\n    /// Only works if the entity has auto increment primary key.\n    fn save<'a, C>(self, db: &'a C) -> Result<Self, DbErr>\n    where\n        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,\n        Self: ActiveModelBehavior,\n        C: ConnectionTrait,\n    {\n        let res = if !self.is_update() {\n            self.insert(db)\n        } else {\n            self.update(db)\n        }?;\n        Ok(res.into_active_model())\n    }\n\n    /// Returns true if the primary key is fully-specified\n    #[doc(hidden)]\n    fn is_update(&self) -> bool {\n        let mut is_update = true;\n        for key in <Self::Entity as EntityTrait>::PrimaryKey::iter() {\n            let col = key.into_column();\n            if self.is_not_set(col) {\n                is_update = false;\n                break;\n            }\n        }\n        is_update\n    }\n\n    /// Delete an active model by its primary key\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let orange = fruit::ActiveModel {\n    ///     id: Set(3),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// let delete_result = orange.delete(&db)?;\n    ///\n    /// assert_eq!(delete_result.rows_affected, 1);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"DELETE FROM \"fruit\" WHERE \"fruit\".\"id\" = $1\"#,\n    ///         [3i32.into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn delete<'a, C>(self, db: &'a C) -> Result<DeleteResult, DbErr>\n    where\n        Self: ActiveModelBehavior,\n        C: ConnectionTrait,\n    {\n        let am = ActiveModelBehavior::before_delete(self, db)?;\n        let am_clone = am.clone();\n        let delete_res = Self::Entity::delete(am).exec(db)?;\n        ActiveModelBehavior::after_delete(am_clone, db)?;\n        Ok(delete_res)\n    }\n\n    /// Set the corresponding attributes in the ActiveModel from a JSON value\n    ///\n    /// Note that this method will not alter the primary key values in ActiveModel.\n    #[cfg(feature = \"with-json\")]\n    fn set_from_json(&mut self, json: serde_json::Value) -> Result<(), DbErr>\n    where\n        Self: crate::TryIntoModel<<Self::Entity as EntityTrait>::Model>,\n        <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self>,\n        for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model:\n            serde::de::Deserialize<'de> + serde::Serialize,\n    {\n        use crate::Iterable;\n\n        // Backup primary key values\n        let primary_key_values: Vec<(<Self::Entity as EntityTrait>::Column, ActiveValue<Value>)> =\n            <<Self::Entity as EntityTrait>::PrimaryKey>::iter()\n                .map(|pk| (pk.into_column(), self.take(pk.into_column())))\n                .collect();\n\n        // Replace all values in ActiveModel\n        *self = Self::from_json(json)?;\n\n        // Restore primary key values\n        for (col, active_value) in primary_key_values {\n            match active_value {\n                ActiveValue::Unchanged(v) | ActiveValue::Set(v) => self.set(col, v),\n                NotSet => self.not_set(col),\n            }\n        }\n\n        Ok(())\n    }\n\n    /// Create ActiveModel from a JSON value\n    #[cfg(feature = \"with-json\")]\n    fn from_json(mut json: serde_json::Value) -> Result<Self, DbErr>\n    where\n        Self: crate::TryIntoModel<<Self::Entity as EntityTrait>::Model>,\n        <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self>,\n        for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model:\n            serde::de::Deserialize<'de> + serde::Serialize,\n    {\n        use crate::{IdenStatic, Iterable};\n\n        let serde_json::Value::Object(obj) = &json else {\n            return Err(DbErr::Json(format!(\n                \"invalid type: expected JSON object for {}\",\n                <<Self as ActiveModelTrait>::Entity as IdenStatic>::as_str(&Default::default())\n            )));\n        };\n\n        // Mark down which attribute exists in the JSON object\n        let mut json_keys: Vec<(<Self::Entity as EntityTrait>::Column, bool)> = Vec::new();\n\n        for col in <<Self::Entity as EntityTrait>::Column>::iter() {\n            let key = col.json_key();\n            let has_key = obj.contains_key(key);\n            json_keys.push((col, has_key));\n        }\n\n        // Create dummy model with dummy values\n        let dummy_model = Self::default_values();\n        if let Ok(dummy_model) = dummy_model.try_into_model() {\n            if let Ok(mut dummy_json) = serde_json::to_value(&dummy_model) {\n                let serde_json::Value::Object(merged) = &mut dummy_json else {\n                    unreachable!();\n                };\n                let serde_json::Value::Object(obj) = json else {\n                    unreachable!();\n                };\n                // overwrite dummy values with input values\n                for (key, value) in obj {\n                    merged.insert(key, value);\n                }\n                json = dummy_json;\n            }\n        }\n\n        // Convert JSON object into ActiveModel via Model\n        let model: <Self::Entity as EntityTrait>::Model =\n            serde_json::from_value(json).map_err(json_err)?;\n        let mut am = model.into_active_model();\n\n        // Transform attribute that exists in JSON object into ActiveValue::Set, otherwise ActiveValue::NotSet\n        for (col, json_key_exists) in json_keys {\n            match (json_key_exists, am.get(col)) {\n                (true, ActiveValue::Set(value) | ActiveValue::Unchanged(value)) => {\n                    am.set(col, value);\n                }\n                _ => {\n                    am.not_set(col);\n                }\n            }\n        }\n\n        Ok(am)\n    }\n\n    /// Create a Vec of ActiveModels from an Arrow RecordBatch.\n    ///\n    /// Each row in the RecordBatch becomes one ActiveModel.\n    /// Columns are matched by name (using [`ColumnTrait::as_str`](crate::ColumnTrait::as_str)).\n    /// Columns present in the RecordBatch are marked as `Set`;\n    /// columns absent from the RecordBatch are marked as `NotSet`.\n    ///\n    /// Supported column types: integers (i8–i64, u8–u64), floats (f32, f64),\n    /// `String`/`Text`, `Boolean`, and date/time types (with `with-chrono` or `with-time`).\n    /// Null values in nullable columns are handled.\n    ///\n    /// When both `with-chrono` and `with-time` features are enabled, chrono values\n    /// are attempted first. If the model uses time-crate types, the conversion\n    /// automatically falls back to the time-crate representation.\n    #[cfg(feature = \"with-arrow\")]\n    fn from_arrow(batch: &sea_orm_arrow::arrow::array::RecordBatch) -> Result<Vec<Self>, DbErr> {\n        use crate::{IdenStatic, Iterable, with_arrow::arrow_array_to_value};\n\n        let num_rows = batch.num_rows();\n        let mut results = Vec::with_capacity(num_rows);\n\n        for row in 0..num_rows {\n            let mut am = Self::default();\n\n            for col in <<Self::Entity as EntityTrait>::Column>::iter() {\n                let col_name = col.as_str();\n\n                if let Some(arrow_col) = batch.column_by_name(col_name) {\n                    let col_def = col.def();\n                    let col_type = col_def.get_column_type();\n                    let value = arrow_array_to_value(arrow_col.as_ref(), col_type, row)?;\n\n                    // When both chrono and time features are enabled, the primary\n                    // conversion produces chrono Values for date/time columns.\n                    // If the model's field uses time-crate types, try_set will fail;\n                    // retry with the time-crate alternative.\n                    #[cfg(all(feature = \"with-chrono\", feature = \"with-time\"))]\n                    {\n                        use crate::with_arrow::{arrow_array_to_value_alt, is_datetime_column};\n                        match am.try_set(col, value) {\n                            Ok(()) => {}\n                            Err(first_err) if is_datetime_column(col_type) => {\n                                if let Some(alt_value) =\n                                    arrow_array_to_value_alt(arrow_col.as_ref(), col_type, row)?\n                                {\n                                    am.try_set(col, alt_value)?;\n                                } else {\n                                    return Err(first_err);\n                                }\n                            }\n                            Err(e) => return Err(e),\n                        }\n                    }\n\n                    #[cfg(not(all(feature = \"with-chrono\", feature = \"with-time\")))]\n                    am.try_set(col, value)?;\n                } else {\n                    am.not_set(col);\n                }\n            }\n\n            results.push(am);\n        }\n\n        Ok(results)\n    }\n\n    /// Convert a slice of ActiveModels into an Arrow [`RecordBatch`](arrow::array::RecordBatch).\n    ///\n    /// The `schema` determines the output columns: each schema field is matched\n    /// to an entity column by name (using [`ColumnTrait::as_str`](crate::ColumnTrait::as_str)).\n    /// Columns marked `Set` or `Unchanged` contribute their value;\n    /// `NotSet` columns become null in the output.\n    ///\n    /// Typical usage together with [`ArrowSchema`](crate::ArrowSchema):\n    /// ```ignore\n    /// let schema = MyEntity::arrow_schema();\n    /// let batch = MyActiveModel::to_arrow(&models, &schema)?;\n    /// ```\n    #[cfg(feature = \"with-arrow\")]\n    fn to_arrow(\n        models: &[Self],\n        schema: &sea_orm_arrow::arrow::datatypes::Schema,\n    ) -> Result<sea_orm_arrow::arrow::array::RecordBatch, DbErr> {\n        use crate::{Iterable, with_arrow::option_values_to_arrow_array};\n        use std::sync::Arc;\n\n        let mut columns: Vec<Arc<dyn sea_orm_arrow::arrow::array::Array>> =\n            Vec::with_capacity(schema.fields().len());\n\n        for field in schema.fields() {\n            let field_name = field.name();\n\n            // Find the entity column whose name matches this schema field\n            let entity_col =\n                <<Self::Entity as EntityTrait>::Column>::iter().find(|c| c.as_str() == field_name);\n\n            if let Some(col) = entity_col {\n                let values: Vec<Option<Value>> = models\n                    .iter()\n                    .map(|m| match m.get(col) {\n                        ActiveValue::Set(v) | ActiveValue::Unchanged(v) => Some(v),\n                        ActiveValue::NotSet => None,\n                    })\n                    .collect();\n\n                let array = option_values_to_arrow_array(&values, field.data_type())?;\n                columns.push(array);\n            } else {\n                // Field in schema but not in entity → null column\n                let array =\n                    sea_orm_arrow::arrow::array::new_null_array(field.data_type(), models.len());\n                columns.push(array);\n            }\n        }\n\n        sea_orm_arrow::arrow::array::RecordBatch::try_new(Arc::new(schema.clone()), columns)\n            .map_err(|e| DbErr::Type(format!(\"Failed to create RecordBatch: {e}\")))\n    }\n\n    /// Return `true` if any attribute of `ActiveModel` is `Set`\n    fn is_changed(&self) -> bool {\n        <Self::Entity as EntityTrait>::Column::iter()\n            .any(|col| matches!(self.get(col), ActiveValue::Set(_)))\n    }\n\n    #[doc(hidden)]\n    /// Set the key to parent's key value for a belongs to relation.\n    fn set_parent_key<R, AM>(&mut self, model: &AM) -> Result<(), DbErr>\n    where\n        R: EntityTrait,\n        AM: ActiveModelTrait<Entity = R>,\n        Self::Entity: Related<R>,\n    {\n        let rel_def = Self::Entity::to();\n\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\n                \"Relation from {} to {} is not belongs_to\",\n                <Self::Entity as Default>::default().as_str(),\n                <R as Default>::default().as_str()\n            )));\n        }\n\n        let values = get_key_from_active_model(&rel_def.to_col, model)?;\n\n        set_key_on_active_model(&rel_def.from_col, self, values)?;\n\n        Ok(())\n    }\n\n    #[doc(hidden)]\n    fn set_parent_key_for<R, AM>(\n        &mut self,\n        model: &AM,\n        rel: <Self::Entity as EntityTrait>::Relation,\n    ) -> Result<(), DbErr>\n    where\n        R: EntityTrait,\n        AM: ActiveModelTrait<Entity = R>,\n    {\n        let rel_def = rel.def();\n\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\"Relation {rel:?} is not belongs_to\")));\n        }\n\n        let values = get_key_from_active_model(&rel_def.to_col, model)?;\n\n        set_key_on_active_model(&rel_def.from_col, self, values)?;\n\n        Ok(())\n    }\n\n    #[doc(hidden)]\n    fn set_parent_key_for_def<R, AM>(\n        &mut self,\n        model: &AM,\n        rel_def: &RelationDef,\n    ) -> Result<(), DbErr>\n    where\n        R: EntityTrait,\n        AM: ActiveModelTrait<Entity = R>,\n    {\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\n                \"Relation {rel_def:?} is not belongs_to\"\n            )));\n        }\n\n        let values = get_key_from_active_model(&rel_def.to_col, model)?;\n\n        set_key_on_active_model(&rel_def.from_col, self, values)?;\n\n        Ok(())\n    }\n\n    #[doc(hidden)]\n    fn set_parent_key_for_self_rev<AM>(\n        &mut self,\n        model: &AM,\n        rel: <Self::Entity as EntityTrait>::Relation,\n    ) -> Result<(), DbErr>\n    where\n        AM: ActiveModelTrait<Entity = Self::Entity>,\n    {\n        let rel_def = rel.def();\n\n        if !rel_def.is_owner {\n            return Err(DbErr::Type(format!(\"Relation {rel:?} is not owner\")));\n        }\n\n        let values = get_key_from_active_model(&rel_def.from_col, model)?;\n\n        set_key_on_active_model(&rel_def.to_col, self, values)?;\n\n        Ok(())\n    }\n\n    #[doc(hidden)]\n    /// Clear parent association if the relation is optional and return true\n    fn clear_parent_key<R>(&mut self) -> Result<bool, DbErr>\n    where\n        R: EntityTrait,\n        Self::Entity: Related<R>,\n    {\n        let rel_def = Self::Entity::to();\n\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\n                \"Relation from {} to {} is not belongs_to\",\n                <Self::Entity as Default>::default().as_str(),\n                <R as Default>::default().as_str()\n            )));\n        }\n\n        clear_key_on_active_model(&rel_def.from_col, self)\n    }\n\n    #[doc(hidden)]\n    fn clear_parent_key_for_self_rev(\n        &mut self,\n        rel: <Self::Entity as EntityTrait>::Relation,\n    ) -> Result<bool, DbErr> {\n        let rel_def = rel.def();\n\n        if !rel_def.is_owner {\n            return Err(DbErr::Type(format!(\"Relation {rel:?} is not owner\")));\n        }\n\n        clear_key_on_active_model(&rel_def.to_col, self)\n    }\n\n    #[doc(hidden)]\n    /// Get the key value of belongs to relation\n    fn get_parent_key<R>(&self) -> Result<ValueTuple, DbErr>\n    where\n        R: EntityTrait,\n        Self::Entity: Related<R>,\n    {\n        let rel_def = Self::Entity::to();\n\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\n                \"Relation from {} to {} is not belongs_to\",\n                <Self::Entity as Default>::default().as_str(),\n                <R as Default>::default().as_str()\n            )));\n        }\n\n        get_key_from_active_model(&rel_def.from_col, self)\n    }\n\n    #[doc(hidden)]\n    /// Get the key value of belongs to relation\n    fn get_parent_key_for(\n        &self,\n        rel: <Self::Entity as EntityTrait>::Relation,\n    ) -> Result<ValueTuple, DbErr> {\n        let rel_def = rel.def();\n\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\"Relation {rel:?} is not belongs_to\")));\n        }\n\n        get_key_from_active_model(&rel_def.from_col, self)\n    }\n\n    #[doc(hidden)]\n    fn find_belongs_to_self(\n        &self,\n        rel: <Self::Entity as EntityTrait>::Relation,\n        db_backend: DbBackend,\n    ) -> Result<crate::query::Select<Self::Entity>, DbErr> {\n        let rel_def = rel.def();\n\n        if !rel_def.is_owner {\n            return Err(DbErr::Type(format!(\n                \"Relation {rel:?} is not has_one / has_many\"\n            )));\n        }\n\n        let id = get_key_from_active_model(&rel_def.from_col, self)?;\n\n        Ok(Self::Entity::find().filter(\n            column_tuple_in_condition(\n                &<Self::Entity as Default>::default().table_ref(),\n                &rel_def.to_col,\n                &[id],\n                db_backend,\n            )\n            .expect(\"\"),\n        ))\n    }\n\n    #[doc(hidden)]\n    fn find_belongs_to_model<AM>(\n        rel_def: &RelationDef,\n        belongs_to: &AM,\n        db_backend: DbBackend,\n    ) -> Result<crate::query::Select<Self::Entity>, DbErr>\n    where\n        AM: ActiveModelTrait,\n    {\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\n                \"Relation {rel_def:?} is not belongs_to\"\n            )));\n        }\n\n        let id = get_key_from_active_model(&rel_def.to_col, belongs_to)?;\n        Ok(<Self::Entity as EntityTrait>::find().filter(\n            column_tuple_in_condition(&rel_def.from_tbl, &rel_def.from_col, &[id], db_backend)\n                .expect(\"\"),\n        ))\n    }\n\n    /// Find related Models belonging to self\n    fn find_related<R>(&self, _: R) -> crate::query::Select<R>\n    where\n        R: EntityTrait,\n        Self::Entity: Related<R>,\n    {\n        Self::Entity::find_related().belongs_to_active_model(self)\n    }\n\n    /// Like find_related, but infer type from `AM`\n    #[doc(hidden)]\n    fn find_related_of<AM>(&self, _: &[AM]) -> crate::query::Select<AM::Entity>\n    where\n        AM: ActiveModelTrait,\n        Self::Entity: Related<AM::Entity>,\n    {\n        self.find_related(AM::Entity::default())\n    }\n\n    /// Establish links between self and a related Entity for a many-to-many relation.\n    /// New associations will be added, and leftovers can be optionally deleted.\n    #[doc(hidden)]\n    fn establish_links<J, R, RM, C>(\n        &self,\n        _: J,\n        related_models: &[RM],\n        delete_leftover: bool,\n        db: &C,\n    ) -> Result<(), DbErr>\n    where\n        R: EntityTrait,\n        RM: ActiveModelTrait<Entity = R>,\n        J: EntityTrait + Related<R> + Related<Self::Entity>,\n        J::Model: IntoActiveModel<J::ActiveModel>,\n        J::ActiveModel: ActiveModelBehavior,\n        C: ConnectionTrait,\n    {\n        let left = <J as Related<Self::Entity>>::to();\n        let right = <J as Related<R>>::to();\n\n        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db)\n    }\n\n    /// Establish links for self-referencing many-to-many relation\n    #[doc(hidden)]\n    fn establish_links_self<J, RM, C>(\n        &self,\n        _: J,\n        related_models: &[RM],\n        delete_leftover: bool,\n        db: &C,\n    ) -> Result<(), DbErr>\n    where\n        RM: ActiveModelTrait<Entity = Self::Entity>,\n        J: EntityTrait,\n        J::Model: IntoActiveModel<J::ActiveModel>,\n        J::ActiveModel: ActiveModelBehavior,\n        C: ConnectionTrait,\n        Self::Entity: RelatedSelfVia<J>,\n    {\n        let left = <Self::Entity as RelatedSelfVia<J>>::via().rev();\n        let right = <Self::Entity as RelatedSelfVia<J>>::to();\n\n        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db)\n    }\n\n    /// Establish links for self-referencing many-to-many relation, but left-right reversed\n    #[doc(hidden)]\n    fn establish_links_self_rev<J, RM, C>(\n        &self,\n        _: J,\n        related_models: &[RM],\n        delete_leftover: bool,\n        db: &C,\n    ) -> Result<(), DbErr>\n    where\n        RM: ActiveModelTrait<Entity = Self::Entity>,\n        J: EntityTrait,\n        J::Model: IntoActiveModel<J::ActiveModel>,\n        J::ActiveModel: ActiveModelBehavior,\n        C: ConnectionTrait,\n        Self::Entity: RelatedSelfVia<J>,\n    {\n        let left = <Self::Entity as RelatedSelfVia<J>>::to();\n        let right = <Self::Entity as RelatedSelfVia<J>>::via().rev();\n\n        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db)\n    }\n\n    /// Inverse of establish link, break links between two many-to-many models\n    #[doc(hidden)]\n    fn delete_links<J, C>(&self, _: J, db: &C) -> Result<DeleteResult, DbErr>\n    where\n        J: EntityTrait + Related<Self::Entity>,\n        C: ConnectionTrait,\n    {\n        let rel_def = <J as Related<Self::Entity>>::to();\n        let id = get_key_from_active_model(&rel_def.to_col, self)?;\n\n        J::delete_many()\n            .filter(\n                column_tuple_in_condition(\n                    &rel_def.from_tbl,\n                    &rel_def.from_col,\n                    &[id],\n                    db.get_database_backend(),\n                )\n                .expect(\"\"),\n            )\n            .exec(db)\n    }\n\n    /// Like `delete_links` but for self-referencing relations\n    #[doc(hidden)]\n    fn delete_links_self<J, C>(&self, _: J, db: &C) -> Result<DeleteResult, DbErr>\n    where\n        J: EntityTrait,\n        C: ConnectionTrait,\n        Self::Entity: RelatedSelfVia<J>,\n    {\n        let left = <Self::Entity as RelatedSelfVia<J>>::via().rev();\n        let right = <Self::Entity as RelatedSelfVia<J>>::to();\n\n        let id = get_key_from_active_model(&left.to_col, self)?;\n\n        if left.to_col != right.to_col {\n            return Err(DbErr::Type(\"Expect Self Referencing Relation\".into()));\n        }\n\n        J::delete_many()\n            .filter(\n                Condition::any()\n                    .add(\n                        column_tuple_in_condition(\n                            &left.from_tbl,\n                            &left.from_col,\n                            std::slice::from_ref(&id),\n                            db.get_database_backend(),\n                        )\n                        .expect(\"\"),\n                    )\n                    .add(\n                        column_tuple_in_condition(\n                            &right.from_tbl,\n                            &right.from_col,\n                            std::slice::from_ref(&id),\n                            db.get_database_backend(),\n                        )\n                        .expect(\"\"),\n                    ),\n            )\n            .exec(db)\n    }\n}\n\n/// A Trait for overriding the ActiveModel behavior\n///\n/// ### Example\n/// ```ignore\n/// use sea_orm::entity::prelude::*;\n///\n///  // Use [DeriveEntity] to derive the EntityTrait automatically\n/// #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n/// pub struct Entity;\n///\n/// /// The [EntityName] describes the name of a table\n/// impl EntityName for Entity {\n///     fn table_name(&self) -> &'static str {\n///         \"cake\"\n///     }\n/// }\n///\n/// // Derive the ActiveModel\n/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\n/// pub struct Model {\n///     pub id: i32,\n///     pub name: String,\n/// }\n///\n/// impl ActiveModelBehavior for ActiveModel {}\n/// ```\n/// See module level docs [crate::entity] for a full example\n#[allow(unused_variables)]\npub trait ActiveModelBehavior: ActiveModelTrait {\n    /// Create a new ActiveModel with default values. This is also called by `Default::default()`.\n    ///\n    /// You can override it like the following:\n    ///\n    /// ```ignore\n    /// fn new() -> Self {\n    ///     Self {\n    ///         status: Set(Status::New),\n    ///         ..ActiveModelTrait::default()\n    ///     }\n    /// }\n    /// ```\n    fn new() -> Self {\n        <Self as ActiveModelTrait>::default()\n    }\n\n    /// Will be called before `ActiveModel::insert`, `ActiveModel::update`, and `ActiveModel::save`\n    fn before_save<C>(self, db: &C, insert: bool) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Ok(self)\n    }\n\n    /// Will be called after `ActiveModel::insert`, `ActiveModel::update`, and `ActiveModel::save`\n    fn after_save<C>(\n        model: <Self::Entity as EntityTrait>::Model,\n        db: &C,\n        insert: bool,\n    ) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Ok(model)\n    }\n\n    /// Will be called before `ActiveModel::delete`\n    fn before_delete<C>(self, db: &C) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Ok(self)\n    }\n\n    /// Will be called after `ActiveModel::delete`\n    fn after_delete<C>(self, db: &C) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Ok(self)\n    }\n}\n\n/// A Trait for any type that can be converted into an `ActiveModel`,\n/// can be derived using `DeriveIntoActiveModel`.\n///\n/// ## Derive Macro Example\n///\n/// ```rust\n/// use sea_orm::DeriveIntoActiveModel;\n/// mod fruit {\n///     use sea_orm::entity::prelude::*;\n///     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n///     #[sea_orm(table_name = \"fruit\")]\n///     pub struct Model {\n///         #[sea_orm(primary_key)]\n///         pub id: i32,\n///         pub name: String,\n///         pub cake_id: Option<i32>,\n///     }\n///     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n///     pub enum Relation {}\n///     impl ActiveModelBehavior for ActiveModel {}\n/// }\n///\n/// #[derive(DeriveIntoActiveModel)]\n/// #[sea_orm(active_model = \"fruit::ActiveModel\")]\n/// struct NewFruit {\n///     name: String,\n///     // `id` and `cake_id` are omitted - they become `NotSet`\n/// }\n/// ```\n///\n/// ## `set(...)` - always set absent ActiveModel fields\n///\n/// ```rust\n/// # mod fruit {\n/// #     use sea_orm::entity::prelude::*;\n/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #     #[sea_orm(table_name = \"fruit\")]\n/// #     pub struct Model {\n/// #         #[sea_orm(primary_key)]\n/// #         pub id: i32,\n/// #         pub name: String,\n/// #         pub cake_id: Option<i32>,\n/// #     }\n/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n/// #     pub enum Relation {}\n/// #     impl ActiveModelBehavior for ActiveModel {}\n/// # }\n/// use sea_orm::DeriveIntoActiveModel;\n///\n/// #[derive(DeriveIntoActiveModel)]\n/// #[sea_orm(active_model = \"fruit::ActiveModel\", set(cake_id = \"None\"))]\n/// struct NewFruit {\n///     name: String,\n///     // `cake_id` is not on the struct, but will always be `Set(None)`\n/// }\n/// ```\n///\n/// ## `default = \"expr\"` - fallback for `Option<T>` struct fields\n///\n/// ```rust\n/// # mod fruit {\n/// #     use sea_orm::entity::prelude::*;\n/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #     #[sea_orm(table_name = \"fruit\")]\n/// #     pub struct Model {\n/// #         #[sea_orm(primary_key)]\n/// #         pub id: i32,\n/// #         pub name: String,\n/// #         pub cake_id: Option<i32>,\n/// #     }\n/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n/// #     pub enum Relation {}\n/// #     impl ActiveModelBehavior for ActiveModel {}\n/// # }\n/// use sea_orm::DeriveIntoActiveModel;\n///\n/// #[derive(DeriveIntoActiveModel)]\n/// #[sea_orm(active_model = \"fruit::ActiveModel\")]\n/// struct UpdateFruit {\n///     /// `Some(\"Apple\")` -> `Set(\"Apple\")`, `None` ->`Set(\"Unnamed\")`\n///     #[sea_orm(default = \"String::from(\\\"Unnamed\\\")\")]\n///     name: Option<String>,\n/// }\n/// ```\npub trait IntoActiveModel<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Method to call to perform the conversion\n    fn into_active_model(self) -> A;\n}\n\nimpl<A> IntoActiveModel<A> for A\nwhere\n    A: ActiveModelTrait,\n{\n    fn into_active_model(self) -> A {\n        self\n    }\n}\n\nfn establish_links<EM, J, RM, C>(\n    model: &EM,\n    related_models: &[RM],\n    left: RelationDef,\n    right: RelationDef,\n    delete_leftover: bool,\n    db: &C,\n) -> Result<(), DbErr>\nwhere\n    EM: ActiveModelTrait,\n    RM: ActiveModelTrait,\n    J: EntityTrait,\n    J::Model: IntoActiveModel<J::ActiveModel>,\n    J::ActiveModel: ActiveModelBehavior,\n    C: ConnectionTrait,\n{\n    let mut require_leftover = true;\n\n    if related_models.is_empty() {\n        // if there are no related models, then there is no risk of insert conflict\n        require_leftover = false;\n    }\n\n    let primary_key = J::primary_key_identity();\n    if require_leftover\n        && primary_key.fully_contains(&left.from_col)\n        && primary_key.fully_contains(&right.from_col)\n    {\n        // if the primary key is a composite key of the two relations\n        // we can use on conflict no action safely\n        require_leftover = false;\n    }\n\n    let mut leftover = Vec::new();\n    if delete_leftover || require_leftover {\n        for item in <J::ActiveModel as ActiveModelTrait>::find_belongs_to_model(\n            &left,\n            model,\n            db.get_database_backend(),\n        )?\n        .all(db)?\n        {\n            let item = item.into_active_model();\n            let key = get_key_from_active_model(&right.from_col, &item)?;\n            leftover.push((item, key));\n        }\n    }\n    let leftover = leftover; // un-mut\n\n    let mut via_models = Vec::new();\n    let mut all_keys = std::collections::HashSet::new();\n\n    for related_model in related_models {\n        let mut via: J::ActiveModel = ActiveModelBehavior::new();\n        via.set_parent_key_for_def(model, &left)?;\n        via.set_parent_key_for_def(related_model, &right)?;\n        let via_key = get_key_from_active_model(&right.from_col, &via)?;\n        if !leftover.iter().any(|t| t.1 == via_key) {\n            // if not already exist, save for insert\n            via_models.push(via);\n        }\n        if delete_leftover {\n            all_keys.insert(via_key);\n        }\n    }\n\n    if delete_leftover {\n        let mut to_delete = Vec::new();\n        for (leftover, key) in leftover {\n            if !all_keys.contains(&key) {\n                to_delete.push(\n                    leftover\n                        .get_primary_key_value()\n                        .expect(\"item is a full model\"),\n                );\n            }\n        }\n        if !to_delete.is_empty() {\n            J::delete_many()\n                .filter_by_value_tuples(&to_delete, db.get_database_backend())\n                .exec(db)?;\n        }\n    }\n\n    if !via_models.is_empty() {\n        // insert new junctions\n        J::insert_many(via_models)\n            .on_conflict_do_nothing()\n            .exec(db)?;\n    }\n\n    Ok(())\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{DbErr, entity::*, tests_cfg::*};\n    use pretty_assertions::assert_eq;\n\n    #[cfg(feature = \"with-json\")]\n    use serde_json::json;\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_1() {\n        mod my_fruit {\n            pub use super::fruit::*;\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(DeriveIntoActiveModel)]\n            pub struct NewFruit {\n                // id is omitted\n                pub name: String,\n                // it is required as opposed to optional in Model\n                pub cake_id: i32,\n            }\n        }\n\n        assert_eq!(\n            my_fruit::NewFruit {\n                name: \"Apple\".to_owned(),\n                cake_id: 1,\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(1)),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_2() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct RequiredFruitName {\n            name: String,\n        }\n\n        assert_eq!(\n            RequiredFruitName {\n                name: \"Apple Pie\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple Pie\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct OptionalFruitName {\n            name: Option<String>,\n        }\n\n        assert_eq!(\n            OptionalFruitName {\n                name: Some(\"Apple Pie\".to_owned()),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple Pie\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n\n        assert_eq!(\n            OptionalFruitName { name: None }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: NotSet,\n            }\n        );\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"<fruit::Entity as EntityTrait>::ActiveModel\")]\n        struct RequiredAndNotNullFruitCake {\n            cake_id: i32,\n        }\n\n        assert_eq!(\n            RequiredAndNotNullFruitCake { cake_id: 1 }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: Set(Some(1)),\n            }\n        );\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"<fruit::Entity as EntityTrait>::ActiveModel\")]\n        struct OptionalAndNotNullFruitCake {\n            cake_id: Option<i32>,\n        }\n\n        assert_eq!(\n            OptionalAndNotNullFruitCake { cake_id: Some(1) }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: Set(Some(1)),\n            }\n        );\n\n        assert_eq!(\n            OptionalAndNotNullFruitCake { cake_id: None }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: NotSet,\n            }\n        );\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"<fruit::Entity as EntityTrait>::ActiveModel\")]\n        struct OptionalAndNullableFruitCake {\n            cake_id: Option<Option<i32>>,\n        }\n\n        assert_eq!(\n            OptionalAndNullableFruitCake {\n                cake_id: Some(Some(1)),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: Set(Some(1)),\n            }\n        );\n\n        assert_eq!(\n            OptionalAndNullableFruitCake {\n                cake_id: Some(None),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: Set(None),\n            }\n        );\n\n        assert_eq!(\n            OptionalAndNullableFruitCake { cake_id: None }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: NotSet,\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_set_single() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\", set(cake_id = \"None\"))]\n        struct NewFruit {\n            name: String,\n        }\n\n        assert_eq!(\n            NewFruit {\n                name: \"Apple\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_set_multiple() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(\n            active_model = \"fruit::ActiveModel\",\n            set(name = \"String::from(\\\"cherry\\\")\", cake_id = \"None\")\n        )]\n        struct IdOnlyFruit {\n            id: i32,\n        }\n        assert_eq!(\n            IdOnlyFruit { id: 1 }.into_active_model(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"cherry\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(\n            active_model = \"fruit::ActiveModel\",\n            set(name = \"String::from(\\\"cherry\\\")\"),\n            set(cake_id = \"None\")\n        )]\n        struct IdOnlyFruit2 {\n            id: i32,\n        }\n        assert_eq!(\n            IdOnlyFruit2 { id: 1 }.into_active_model(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"cherry\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_set_separate_attrs() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(\n            active_model = \"fruit::ActiveModel\",\n            set(name = \"String::from(\\\"cherry\\\")\")\n        )]\n        #[sea_orm(set(cake_id = \"None\"))]\n        struct IdOnlyFruit {\n            id: i32,\n        }\n\n        assert_eq!(\n            IdOnlyFruit { id: 1 }.into_active_model(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"cherry\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_ignore() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct NewFruit {\n            name: String,\n            cake_id: i32,\n            #[sea_orm(ignore)]\n            _extra: String,\n        }\n\n        assert_eq!(\n            NewFruit {\n                name: \"Apple\".to_owned(),\n                cake_id: 1,\n                _extra: \"ignored\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(1)),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_skip() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct NewFruit {\n            name: String,\n            #[sea_orm(skip)]\n            _extra: String,\n        }\n\n        assert_eq!(\n            NewFruit {\n                name: \"Apple\".to_owned(),\n                _extra: \"skipped\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_set_and_ignore() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\", set(cake_id = \"Some(42)\"))]\n        struct NewFruit {\n            name: String,\n            #[sea_orm(ignore)]\n            _extra: String,\n        }\n\n        assert_eq!(\n            NewFruit {\n                name: \"Apple\".to_owned(),\n                _extra: \"ignored\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(42)),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_foreign_ignore() {\n        use serde::{Deserialize, Serialize};\n\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel, Serialize, Deserialize)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct NewFruit {\n            #[sea_orm(ignore)]\n            id: i32,\n            name: String,\n            #[serde(skip)]\n            cake_id: Option<i32>,\n        }\n\n        assert_eq!(\n            NewFruit {\n                id: 1.to_owned(),\n                name: \"Apple\".to_owned(),\n                cake_id: Some(42)\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(42)),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_exhaustive() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\", exhaustive, set(cake_id = \"None\"))]\n        struct FullFruit {\n            id: i32,\n            name: String,\n        }\n\n        assert_eq!(\n            FullFruit {\n                id: 1,\n                name: \"Apple\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_multiple_sets() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        const DEFULT_CAKE_ID: i32 = 1;\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(\n            active_model = \"fruit::ActiveModel\",\n            exhaustive,\n            set(cake_id = \"Some(DEFULT_CAKE_ID)\")\n        )]\n        struct FullFruit {\n            id: i32,\n            name: String,\n        }\n\n        assert_eq!(\n            FullFruit {\n                id: 1,\n                name: \"Apple\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(1)),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_field_empty_default() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct NewFruit {\n            #[sea_orm(default)]\n            name: Option<String>,\n        }\n\n        // Some(v) -> Set(v)\n        assert_eq!(\n            NewFruit {\n                name: Some(\"Apple\".to_owned()),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n\n        // None -> Set(fallback)\n        assert_eq!(\n            NewFruit { name: None }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_field_custom_option() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n        mod foreign_crate {\n            #[derive(Debug, Clone, PartialEq, Eq)]\n            pub enum CustomOption<T> {\n                None,\n                Some(T),\n            }\n\n            impl From<CustomOption<String>> for Option<String> {\n                fn from(option: CustomOption<String>) -> Self {\n                    match option {\n                        CustomOption::None => Option::None,\n                        CustomOption::Some(value) => value.into(),\n                    }\n                }\n            }\n        }\n        use foreign_crate::CustomOption;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct NewFruit {\n            #[sea_orm(default)]\n            name: CustomOption<String>,\n        }\n\n        // Some(v) -> Set(v)\n        assert_eq!(\n            NewFruit {\n                name: CustomOption::Some(\"Apple\".to_owned()),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n\n        // None -> Set(fallback)\n        assert_eq!(\n            NewFruit {\n                name: CustomOption::None\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_field_default_some() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct NewFruit {\n            #[sea_orm(default = \"String::from(\\\"Unnamed\\\")\")]\n            name: Option<String>,\n        }\n\n        // Some(v) -> Set(v)\n        assert_eq!(\n            NewFruit {\n                name: Some(\"Apple\".to_owned()),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n\n        // None -> Set(fallback)\n        assert_eq!(\n            NewFruit { name: None }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Unnamed\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_field_default_with_set() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\", set(cake_id = \"Some(99)\"))]\n        struct NewFruit {\n            #[sea_orm(default = \"String::from(\\\"Unnamed\\\")\")]\n            name: Option<String>,\n            #[sea_orm(ignore)]\n            _extra: String,\n        }\n\n        assert_eq!(\n            NewFruit {\n                name: Some(\"Apple\".to_owned()),\n                _extra: \"ignored\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(99)),\n            }\n        );\n\n        assert_eq!(\n            NewFruit {\n                name: None,\n                _extra: \"ignored\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Unnamed\".to_owned()),\n                cake_id: Set(Some(99)),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_field_default_exhaustive() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\", exhaustive, set(cake_id = \"None\"))]\n        struct NewFruit {\n            id: i32,\n            #[sea_orm(default = \"String::from(\\\"Unnamed\\\")\")]\n            name: Option<String>,\n        }\n\n        assert_eq!(\n            NewFruit {\n                id: 1,\n                name: Some(\"Apple\".to_owned()),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n\n        assert_eq!(\n            NewFruit { id: 2, name: None }.into_active_model(),\n            fruit::ActiveModel {\n                id: Set(2),\n                name: Set(\"Unnamed\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_try_into_model_1() {\n        mod my_fruit {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"fruit\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                pub name: String,\n                pub cake_id: Option<i32>,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n        assert_eq!(\n            my_fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Pineapple\".to_owned()),\n                cake_id: Set(None),\n            }\n            .try_into_model()\n            .unwrap(),\n            my_fruit::Model {\n                id: 1,\n                name: \"Pineapple\".to_owned(),\n                cake_id: None,\n            }\n        );\n\n        assert_eq!(\n            my_fruit::ActiveModel {\n                id: Set(2),\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(1)),\n            }\n            .try_into_model()\n            .unwrap(),\n            my_fruit::Model {\n                id: 2,\n                name: \"Apple\".to_owned(),\n                cake_id: Some(1),\n            }\n        );\n\n        assert_eq!(\n            my_fruit::ActiveModel {\n                id: Set(1),\n                name: NotSet,\n                cake_id: Set(None),\n            }\n            .try_into_model(),\n            Err(DbErr::AttrNotSet(String::from(\"name\")))\n        );\n\n        assert_eq!(\n            my_fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Pineapple\".to_owned()),\n                cake_id: NotSet,\n            }\n            .try_into_model(),\n            Err(DbErr::AttrNotSet(String::from(\"cake_id\")))\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_try_into_model_2() {\n        mod my_fruit {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"fruit\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                pub name: String,\n                #[sea_orm(ignore)]\n                pub cake_id: Option<i32>,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n        assert_eq!(\n            my_fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Pineapple\".to_owned()),\n            }\n            .try_into_model()\n            .unwrap(),\n            my_fruit::Model {\n                id: 1,\n                name: \"Pineapple\".to_owned(),\n                cake_id: None,\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_try_into_model_3() {\n        mod my_fruit {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"fruit\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                #[sea_orm(ignore)]\n                pub name: String,\n                pub cake_id: Option<i32>,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n        assert_eq!(\n            my_fruit::ActiveModel {\n                id: Set(1),\n                cake_id: Set(Some(1)),\n            }\n            .try_into_model()\n            .unwrap(),\n            my_fruit::Model {\n                id: 1,\n                name: \"\".to_owned(),\n                cake_id: Some(1),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"with-json\")]\n    fn test_active_model_set_from_json_1() {\n        assert_eq!(\n            cake::ActiveModel::from_json(json!({\n                \"id\": 1,\n                \"name\": \"Apple Pie\",\n            }))\n            .unwrap(),\n            cake::ActiveModel {\n                id: Set(1),\n                name: Set(\"Apple Pie\".to_owned()),\n            }\n        );\n\n        assert_eq!(\n            cake::ActiveModel::from_json(json!({\n                \"id\": 1,\n            }))\n            .unwrap(),\n            cake::ActiveModel {\n                id: Set(1),\n                name: NotSet,\n            }\n        );\n\n        assert_eq!(\n            cake::ActiveModel::from_json(json!({\n                \"name\": \"Apple Pie\",\n            }))\n            .unwrap(),\n            cake::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple Pie\".to_owned()),\n            }\n        );\n\n        let mut cake: cake::ActiveModel = Default::default();\n        cake.set_from_json(json!({\n            \"name\": \"Apple Pie\",\n        }))\n        .unwrap();\n        assert_eq!(\n            cake,\n            cake::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple Pie\".to_owned()),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"with-json\")]\n    fn test_active_model_set_from_json_2() -> Result<(), DbErr> {\n        let mut fruit: fruit::ActiveModel = Default::default();\n\n        fruit.set_from_json(json!({\n            \"name\": \"Apple\",\n        }))?;\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: ActiveValue::NotSet,\n                name: ActiveValue::Set(\"Apple\".to_owned()),\n                cake_id: ActiveValue::NotSet,\n            }\n        );\n\n        assert_eq!(\n            fruit::ActiveModel::from_json(json!({\n                \"name\": \"Apple\",\n            }))?,\n            fruit::ActiveModel {\n                id: ActiveValue::NotSet,\n                name: ActiveValue::Set(\"Apple\".to_owned()),\n                cake_id: ActiveValue::NotSet,\n            }\n        );\n\n        fruit.set_from_json(json!({\n            \"name\": \"Apple\",\n            \"cake_id\": null,\n        }))?;\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: ActiveValue::NotSet,\n                name: ActiveValue::Set(\"Apple\".to_owned()),\n                cake_id: ActiveValue::Set(None),\n            }\n        );\n\n        fruit.set_from_json(json!({\n            \"id\": null,\n            \"name\": \"Apple\",\n            \"cake_id\": 1,\n        }))?;\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: ActiveValue::NotSet,\n                name: ActiveValue::Set(\"Apple\".to_owned()),\n                cake_id: ActiveValue::Set(Some(1)),\n            }\n        );\n\n        fruit.set_from_json(json!({\n            \"id\": 2,\n            \"name\": \"Apple\",\n            \"cake_id\": 1,\n        }))?;\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: ActiveValue::NotSet,\n                name: ActiveValue::Set(\"Apple\".to_owned()),\n                cake_id: ActiveValue::Set(Some(1)),\n            }\n        );\n\n        let mut fruit = fruit::ActiveModel {\n            id: ActiveValue::Set(1),\n            name: ActiveValue::NotSet,\n            cake_id: ActiveValue::NotSet,\n        };\n        fruit.set_from_json(json!({\n            \"id\": 8,\n            \"name\": \"Apple\",\n            \"cake_id\": 1,\n        }))?;\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: ActiveValue::Set(1),\n                name: ActiveValue::Set(\"Apple\".to_owned()),\n                cake_id: ActiveValue::Set(Some(1)),\n            }\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    #[cfg(feature = \"with-json\")]\n    fn test_active_model_set_from_json_3() -> Result<(), DbErr> {\n        use crate::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_exec_results([\n                MockExecResult {\n                    last_insert_id: 1,\n                    rows_affected: 1,\n                },\n                MockExecResult {\n                    last_insert_id: 1,\n                    rows_affected: 1,\n                },\n            ])\n            .append_query_results([\n                [fruit::Model {\n                    id: 1,\n                    name: \"Apple\".to_owned(),\n                    cake_id: None,\n                }],\n                [fruit::Model {\n                    id: 2,\n                    name: \"Orange\".to_owned(),\n                    cake_id: Some(1),\n                }],\n            ])\n            .into_connection();\n\n        let mut fruit: fruit::ActiveModel = Default::default();\n        fruit.set_from_json(json!({\n            \"name\": \"Apple\",\n        }))?;\n        fruit.save(&db)?;\n\n        let mut fruit = fruit::ActiveModel {\n            id: Set(2),\n            ..Default::default()\n        };\n        fruit.set_from_json(json!({\n            \"id\": 9,\n            \"name\": \"Orange\",\n            \"cake_id\": 1,\n        }))?;\n        fruit.save(&db)?;\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"INSERT INTO \"fruit\" (\"name\") VALUES ($1) RETURNING \"id\", \"name\", \"cake_id\"\"#,\n                    [\"Apple\".into()],\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"fruit\" SET \"name\" = $1, \"cake_id\" = $2 WHERE \"fruit\".\"id\" = $3 RETURNING \"id\", \"name\", \"cake_id\"\"#,\n                    [\"Orange\".into(), 1i32.into(), 2i32.into()],\n                ),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_active_model_is_changed() {\n        let mut fruit: fruit::ActiveModel = Default::default();\n        assert!(!fruit.is_changed());\n\n        fruit.set(fruit::Column::Name, \"apple\".into());\n        assert!(fruit.is_changed());\n\n        let mut fruit = fruit::Model {\n            id: 1,\n            name: \"\".into(),\n            cake_id: None,\n        };\n        fruit.set(\"name\".parse().unwrap(), \"orange\".into());\n        assert_eq!(fruit.name, \"orange\");\n    }\n\n    #[test]\n    fn test_reset_1() {\n        assert_eq!(\n            fruit::Model {\n                id: 1,\n                name: \"Apple\".into(),\n                cake_id: None,\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: Unchanged(1),\n                name: Unchanged(\"Apple\".into()),\n                cake_id: Unchanged(None)\n            },\n        );\n\n        assert_eq!(\n            fruit::Model {\n                id: 1,\n                name: \"Apple\".into(),\n                cake_id: None,\n            }\n            .into_active_model()\n            .reset_all(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Apple\".into()),\n                cake_id: Set(None)\n            },\n        );\n\n        assert_eq!(\n            fruit::Model {\n                id: 1,\n                name: \"Apple\".into(),\n                cake_id: Some(2),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: Unchanged(1),\n                name: Unchanged(\"Apple\".into()),\n                cake_id: Unchanged(Some(2)),\n            },\n        );\n\n        assert_eq!(\n            fruit::Model {\n                id: 1,\n                name: \"Apple\".into(),\n                cake_id: Some(2),\n            }\n            .into_active_model()\n            .reset_all(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Apple\".into()),\n                cake_id: Set(Some(2)),\n            },\n        );\n    }\n\n    #[test]\n    fn test_reset_2() -> Result<(), DbErr> {\n        use crate::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_exec_results(vec![\n                MockExecResult {\n                    last_insert_id: 1,\n                    rows_affected: 1,\n                },\n                MockExecResult {\n                    last_insert_id: 1,\n                    rows_affected: 1,\n                },\n            ])\n            .append_query_results(vec![\n                vec![fruit::Model {\n                    id: 1,\n                    name: \"Apple\".to_owned(),\n                    cake_id: None,\n                }],\n                vec![fruit::Model {\n                    id: 1,\n                    name: \"Apple\".to_owned(),\n                    cake_id: None,\n                }],\n            ])\n            .into_connection();\n\n        fruit::Model {\n            id: 1,\n            name: \"Apple\".into(),\n            cake_id: None,\n        }\n        .into_active_model()\n        .update(&db)?;\n\n        fruit::Model {\n            id: 1,\n            name: \"Apple\".into(),\n            cake_id: None,\n        }\n        .into_active_model()\n        .reset_all()\n        .update(&db)?;\n\n        assert_eq!(\n            db.into_transaction_log(),\n            vec![\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\" WHERE \"fruit\".\"id\" = $1 LIMIT $2\"#,\n                    vec![1i32.into(), 1u64.into()],\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"fruit\" SET \"name\" = $1, \"cake_id\" = $2 WHERE \"fruit\".\"id\" = $3 RETURNING \"id\", \"name\", \"cake_id\"\"#,\n                    vec![\"Apple\".into(), Option::<i32>::None.into(), 1i32.into()],\n                ),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_active_model_default_values() {\n        assert_eq!(\n            fruit::ActiveModel::default_values(),\n            fruit::ActiveModel {\n                id: Set(0),\n                name: Set(\"\".into()),\n                cake_id: Set(None),\n            },\n        );\n\n        assert_eq!(\n            lunch_set::ActiveModel::default_values(),\n            lunch_set::ActiveModel {\n                id: Set(0),\n                name: Set(\"\".into()),\n                tea: NotSet,\n            },\n        );\n    }\n\n    #[test]\n    fn test_active_model_set_parent_key() {\n        let mut fruit = fruit::Model {\n            id: 2,\n            name: \"F\".into(),\n            cake_id: None,\n        }\n        .into_active_model();\n\n        let cake = cake::Model {\n            id: 4,\n            name: \"C\".into(),\n        }\n        .into_active_model();\n\n        fruit.set_parent_key(&cake).unwrap();\n\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: Unchanged(2),\n                name: Unchanged(\"F\".into()),\n                cake_id: Set(Some(4)),\n            }\n        );\n\n        assert!(fruit.clear_parent_key::<cake::Entity>().unwrap());\n\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: Unchanged(2),\n                name: Unchanged(\"F\".into()),\n                cake_id: Set(None),\n            }\n        );\n\n        let mut cake_filling = cake_filling::ActiveModel::new();\n\n        cake_filling.set_parent_key(&cake).unwrap();\n\n        assert_eq!(\n            cake_filling,\n            cake_filling::ActiveModel {\n                cake_id: Set(4),\n                filling_id: NotSet,\n            }\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/active_model_ex.rs",
    "content": "use super::compound::{HasMany, HasOne};\nuse crate::{ActiveModelTrait, DbErr, EntityTrait, ModelTrait, TryIntoModel};\nuse core::ops::{Index, IndexMut};\n\n/// Container for belongs_to or has_one relation\n#[derive(Debug, Default, Clone)]\npub enum HasOneModel<E: EntityTrait> {\n    /// Unspecified value, do nothing\n    #[default]\n    NotSet,\n    /// Specify the value for the has one relation\n    Set(Box<E::ActiveModelEx>),\n}\n\n/// Container for 1-N or M-N related Models\n#[derive(Debug, Default, Clone)]\npub enum HasManyModel<E: EntityTrait> {\n    /// Unspecified value, do nothing\n    #[default]\n    NotSet,\n    /// Replace all items with this value set; delete leftovers\n    Replace(Vec<E::ActiveModelEx>),\n    /// Add new items to this has many relation; do not delete\n    Append(Vec<E::ActiveModelEx>),\n}\n\n/// Action to perform on ActiveModel\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub enum ActiveModelAction {\n    /// Insert\n    Insert,\n    /// Update\n    Update,\n    /// Insert the model if primary key is `NotSet`, update otherwise.\n    /// Only works if the entity has auto increment primary key.\n    Save,\n}\n\nimpl<E> HasOneModel<E>\nwhere\n    E: EntityTrait,\n{\n    /// Construct a `HasOneModel::Set`\n    pub fn set<AM: Into<E::ActiveModelEx>>(model: AM) -> Self {\n        Self::Set(Box::new(model.into()))\n    }\n\n    /// Replace the inner Model\n    pub fn replace<AM: Into<E::ActiveModelEx>>(&mut self, model: AM) {\n        *self = Self::Set(Box::new(model.into()));\n    }\n\n    /// Take ownership of this model, leaving `NotSet` in place\n    pub fn take(&mut self) -> Option<E::ActiveModelEx> {\n        match std::mem::take(self) {\n            Self::Set(model) => Some(*model),\n            _ => None,\n        }\n    }\n\n    /// Get a reference, if set\n    pub fn as_ref(&self) -> Option<&E::ActiveModelEx> {\n        match self {\n            Self::Set(model) => Some(model),\n            _ => None,\n        }\n    }\n\n    /// Get a mutable reference, if set\n    #[allow(clippy::should_implement_trait)]\n    pub fn as_mut(&mut self) -> Option<&mut E::ActiveModelEx> {\n        match self {\n            Self::Set(model) => Some(model),\n            _ => None,\n        }\n    }\n\n    /// Return true if there is a model\n    pub fn is_set(&self) -> bool {\n        matches!(self, Self::Set(_))\n    }\n\n    /// Return true if self is NotSet\n    pub fn is_not_set(&self) -> bool {\n        matches!(self, Self::NotSet)\n    }\n\n    /// Return true if self is NotSet\n    pub fn is_none(&self) -> bool {\n        matches!(self, Self::NotSet)\n    }\n\n    /// Return true if the containing model is set and changed\n    pub fn is_changed(&self) -> bool {\n        match self {\n            Self::Set(model) => model.is_changed(),\n            _ => false,\n        }\n    }\n\n    /// Convert into an `Option<ActiveModelEx>`\n    pub fn into_option(self) -> Option<E::ActiveModelEx> {\n        match self {\n            Self::Set(model) => Some(*model),\n            Self::NotSet => None,\n        }\n    }\n\n    /// For type inference purpose\n    #[doc(hidden)]\n    pub fn empty_slice(&self) -> &[E::ActiveModelEx] {\n        &[]\n    }\n\n    /// Convert this back to a `ModelEx` container\n    pub fn try_into_model(self) -> Result<HasOne<E>, DbErr>\n    where\n        E::ActiveModelEx: TryIntoModel<E::ModelEx>,\n    {\n        Ok(match self {\n            Self::Set(model) => HasOne::Loaded(Box::new((*model).try_into_model()?)),\n            Self::NotSet => HasOne::Unloaded,\n        })\n    }\n}\n\nimpl<E> PartialEq for HasOneModel<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: PartialEq,\n{\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (HasOneModel::NotSet, HasOneModel::NotSet) => true,\n            (HasOneModel::Set(a), HasOneModel::Set(b)) => a == b,\n            _ => false,\n        }\n    }\n}\n\nimpl<E> PartialEq<Option<E::ActiveModelEx>> for HasOneModel<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: PartialEq,\n{\n    fn eq(&self, other: &Option<E::ActiveModelEx>) -> bool {\n        match (self, other) {\n            (HasOneModel::NotSet, None) => true,\n            (HasOneModel::Set(a), Some(b)) => a.as_ref() == b,\n            _ => false,\n        }\n    }\n}\n\nimpl<E> Eq for HasOneModel<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: Eq,\n{\n}\n\nimpl<E> HasManyModel<E>\nwhere\n    E: EntityTrait,\n{\n    /// Take ownership of the models, leaving `NotSet` in place\n    pub fn take(&mut self) -> Self {\n        std::mem::take(self)\n    }\n\n    /// Borrow models as slice\n    pub fn as_slice(&self) -> &[E::ActiveModelEx] {\n        match self {\n            Self::Replace(models) | Self::Append(models) => models,\n            Self::NotSet => &[],\n        }\n    }\n\n    /// Get a mutable vec. If self is `NotSet`, convert to append.\n    pub fn as_mut_vec(&mut self) -> &mut Vec<E::ActiveModelEx> {\n        match self {\n            Self::Replace(models) | Self::Append(models) => models,\n            Self::NotSet => {\n                *self = Self::Append(vec![]);\n                self.as_mut_vec()\n            }\n        }\n    }\n\n    /// Consume self as vector\n    pub fn into_vec(self) -> Vec<E::ActiveModelEx> {\n        match self {\n            Self::Replace(models) | Self::Append(models) => models,\n            Self::NotSet => vec![],\n        }\n    }\n\n    /// Returns an empty container of self\n    pub fn empty_holder(&self) -> Self {\n        match self {\n            Self::Replace(_) => Self::Replace(vec![]),\n            Self::Append(_) => Self::Append(vec![]),\n            Self::NotSet => Self::NotSet,\n        }\n    }\n\n    /// Push an item to self\n    pub fn push<AM: Into<E::ActiveModelEx>>(&mut self, model: AM) -> &mut Self {\n        let model = model.into();\n        match self {\n            Self::Replace(models) | Self::Append(models) => models.push(model),\n            Self::NotSet => {\n                *self = Self::Append(vec![model]);\n            }\n        }\n\n        self\n    }\n\n    /// Push an item to self, but convert Replace to Append\n    pub fn append<AM: Into<E::ActiveModelEx>>(&mut self, model: AM) -> &mut Self {\n        self.convert_to_append().push(model)\n    }\n\n    /// Replace all items in this set\n    pub fn replace_all<I>(&mut self, models: I) -> &mut Self\n    where\n        I: IntoIterator<Item = E::ActiveModelEx>,\n    {\n        *self = Self::Replace(models.into_iter().collect());\n        self\n    }\n\n    /// Convert self to Append, if set\n    pub fn convert_to_append(&mut self) -> &mut Self {\n        match self.take() {\n            Self::Replace(models) | Self::Append(models) => {\n                *self = Self::Append(models);\n            }\n            Self::NotSet => {\n                *self = Self::NotSet;\n            }\n        }\n\n        self\n    }\n\n    /// Reset self to NotSet\n    pub fn not_set(&mut self) {\n        *self = Self::NotSet;\n    }\n\n    /// If self is `Replace`\n    pub fn is_replace(&self) -> bool {\n        matches!(self, Self::Replace(_))\n    }\n\n    /// If self is `Append`\n    pub fn is_append(&self) -> bool {\n        matches!(self, Self::Append(_))\n    }\n\n    /// Return true if self is `Replace` or any containing model is changed\n    pub fn is_changed(&self) -> bool {\n        match self {\n            Self::Replace(_) => true,\n            Self::Append(models) => models.iter().any(|model| model.is_changed()),\n            Self::NotSet => false,\n        }\n    }\n\n    /// Find within the models by primary key, return true if found\n    pub fn find(&self, model: &E::Model) -> bool {\n        let pk = model.get_primary_key_value();\n\n        for item in self.as_slice() {\n            if let Some(pk_item) = item.get_primary_key_value() {\n                if pk_item == pk {\n                    return true;\n                }\n            }\n        }\n\n        false\n    }\n\n    /// Convert this back to a `ModelEx` container\n    pub fn try_into_model(self) -> Result<HasMany<E>, DbErr>\n    where\n        E::ActiveModelEx: TryIntoModel<E::ModelEx>,\n    {\n        Ok(match self {\n            Self::Replace(models) | Self::Append(models) => HasMany::Loaded(\n                models\n                    .into_iter()\n                    .map(|t| t.try_into_model())\n                    .collect::<Result<Vec<_>, DbErr>>()?,\n            ),\n            Self::NotSet => HasMany::Unloaded,\n        })\n    }\n}\n\nimpl<E> PartialEq for HasManyModel<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: PartialEq,\n{\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (HasManyModel::NotSet, HasManyModel::NotSet) => true,\n            (HasManyModel::Replace(a), HasManyModel::Replace(b)) => a == b,\n            (HasManyModel::Append(a), HasManyModel::Append(b)) => a == b,\n            _ => false,\n        }\n    }\n}\n\nimpl<E> Eq for HasManyModel<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: Eq,\n{\n}\n\nimpl<E: EntityTrait> From<HasManyModel<E>> for Option<Vec<E::ActiveModelEx>> {\n    fn from(value: HasManyModel<E>) -> Self {\n        match value {\n            HasManyModel::NotSet => None,\n            HasManyModel::Replace(models) | HasManyModel::Append(models) => Some(models),\n        }\n    }\n}\n\nimpl<E: EntityTrait> Index<usize> for HasManyModel<E> {\n    type Output = E::ActiveModelEx;\n\n    fn index(&self, index: usize) -> &Self::Output {\n        match self {\n            HasManyModel::NotSet => {\n                panic!(\"index out of bounds: the HasManyModel is NotSet (index: {index})\")\n            }\n            HasManyModel::Replace(models) | HasManyModel::Append(models) => models.index(index),\n        }\n    }\n}\n\nimpl<E: EntityTrait> IndexMut<usize> for HasManyModel<E> {\n    fn index_mut(&mut self, index: usize) -> &mut Self::Output {\n        match self {\n            HasManyModel::NotSet => {\n                panic!(\"index out of bounds: the HasManyModel is NotSet (index: {index})\")\n            }\n            HasManyModel::Replace(models) | HasManyModel::Append(models) => models.index_mut(index),\n        }\n    }\n}\n\nimpl<E: EntityTrait> IntoIterator for HasManyModel<E> {\n    type Item = E::ActiveModelEx;\n    type IntoIter = std::vec::IntoIter<E::ActiveModelEx>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        match self {\n            HasManyModel::Replace(models) | HasManyModel::Append(models) => models.into_iter(),\n            HasManyModel::NotSet => Vec::new().into_iter(),\n        }\n    }\n}\n\n/// Converts from a set of models into `Append`, which performs non-destructive action\nimpl<E: EntityTrait> From<Vec<E::ActiveModelEx>> for HasManyModel<E> {\n    fn from(value: Vec<E::ActiveModelEx>) -> Self {\n        HasManyModel::Append(value)\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/active_value.rs",
    "content": "use crate::Value;\nuse sea_query::Nullable;\nuse std::fmt::Debug;\n\npub use ActiveValue::{NotSet, Set, Unchanged};\n\n/// The state of a field in an [ActiveModel][ActiveModelTrait].\n///\n/// There are three possible states represented by three enum variants:\n///\n/// - [Set] - a value that's explicitly set by the application and sent to the database.\n/// - [Unchanged] - an existing, unchanged value from the database.\n/// - [NotSet] - an undefined value (nothing is sent to the database).\n///\n/// The difference between these states is useful\n/// when constructing `INSERT` and `UPDATE` SQL statements (see an example below).\n/// It's also useful for knowing which fields have changed in a record.\n///\n/// # Examples\n///\n/// ```\n/// use sea_orm::tests_cfg::{cake, fruit};\n/// use sea_orm::{DbBackend, entity::*, query::*};\n///\n/// // Here, we use `NotSet` to let the database automatically generate an `id`.\n/// // This is different from `Set(None)` that explicitly sets `cake_id` to `NULL`.\n/// assert_eq!(\n///     Insert::one(fruit::ActiveModel {\n///         id: ActiveValue::NotSet,\n///         name: ActiveValue::Set(\"Orange\".to_owned()),\n///         cake_id: ActiveValue::Set(None),\n///     })\n///     .build(DbBackend::Postgres)\n///     .to_string(),\n///     r#\"INSERT INTO \"fruit\" (\"name\", \"cake_id\") VALUES ('Orange', NULL)\"#\n/// );\n///\n/// // Here, we update the record, set `cake_id` to the new value\n/// // and use `NotSet` to avoid updating the `name` field.\n/// // `id` is the primary key, so it's used in the condition and not updated.\n/// assert_eq!(\n///     Update::one(fruit::ActiveModel {\n///         id: ActiveValue::Unchanged(1),\n///         name: ActiveValue::NotSet,\n///         cake_id: ActiveValue::Set(Some(2)),\n///     })\n///     .validate()\n///     .unwrap()\n///     .build(DbBackend::Postgres)\n///     .to_string(),\n///     r#\"UPDATE \"fruit\" SET \"cake_id\" = 2 WHERE \"fruit\".\"id\" = 1\"#\n/// );\n/// ```\n#[derive(Clone, Debug)]\npub enum ActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    /// A [Value] that's explicitly set by the application and sent to the database.\n    ///\n    /// Use this to insert or set a specific value.\n    ///\n    /// When editing an existing value, you can use [set_if_not_equals][ActiveValue::set_if_not_equals]\n    /// to preserve the [Unchanged] state when the new value is the same as the old one.\n    /// Then you can meaningfully use methods like [ActiveModelTrait::is_changed].\n    Set(V),\n    /// An existing, unchanged [Value] from the database.\n    ///\n    /// You get these when you query an existing [Model][crate::ModelTrait]\n    /// from the database and convert it into an [ActiveModel][ActiveModelTrait].\n    ///\n    /// When you edit it, you can use [set_if_not_equals][ActiveValue::set_if_not_equals]\n    /// to preserve this \"unchanged\" state if the new value is the same as the old one.\n    /// Then you can meaningfully use methods like [ActiveModelTrait::is_changed].\n    Unchanged(V),\n    /// An undefined [Value]. Nothing is sent to the database.\n    ///\n    /// When you create a new [ActiveModel][ActiveModelTrait],\n    /// its fields are [NotSet][ActiveValue::NotSet] by default.\n    ///\n    /// This can be useful when:\n    ///\n    /// - You insert a new record and want the database to generate a default value (e.g., an id).\n    /// - In an `UPDATE` statement, you don't want to update some field.\n    NotSet,\n}\n\n/// Defines an not set operation on an [ActiveValue]\n#[deprecated(\n    since = \"0.5.0\",\n    note = \"Please use [`ActiveValue::NotSet`] or [`NotSet`]\"\n)]\n#[allow(non_snake_case)]\npub fn Unset<V>(_: Option<bool>) -> ActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    ActiveValue::not_set()\n}\n\n/// Any type that can be converted into an [ActiveValue]\npub trait IntoActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    /// Method to perform the conversion\n    fn into_active_value(self) -> ActiveValue<V>;\n}\n\nimpl<V> IntoActiveValue<V> for Option<V>\nwhere\n    V: IntoActiveValue<V> + Into<Value> + Nullable,\n{\n    fn into_active_value(self) -> ActiveValue<V> {\n        match self {\n            Some(value) => Set(value),\n            None => NotSet,\n        }\n    }\n}\n\nimpl<V> IntoActiveValue<Option<V>> for Option<Option<V>>\nwhere\n    V: IntoActiveValue<V> + Into<Value> + Nullable,\n{\n    fn into_active_value(self) -> ActiveValue<Option<V>> {\n        match self {\n            Some(value) => Set(value),\n            None => NotSet,\n        }\n    }\n}\n\nmacro_rules! impl_into_active_value {\n    ($ty: ty) => {\n        impl IntoActiveValue<$ty> for $ty {\n            fn into_active_value(self) -> ActiveValue<$ty> {\n                Set(self)\n            }\n        }\n    };\n}\n\nimpl_into_active_value!(bool);\nimpl_into_active_value!(i8);\nimpl_into_active_value!(i16);\nimpl_into_active_value!(i32);\nimpl_into_active_value!(i64);\nimpl_into_active_value!(u8);\nimpl_into_active_value!(u16);\nimpl_into_active_value!(u32);\nimpl_into_active_value!(u64);\nimpl_into_active_value!(f32);\nimpl_into_active_value!(f64);\nimpl_into_active_value!(&'static str);\nimpl_into_active_value!(String);\nimpl_into_active_value!(Vec<u8>);\n\n#[cfg(feature = \"with-json\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-json\")))]\nimpl_into_active_value!(crate::prelude::Json);\n\n#[cfg(feature = \"with-chrono\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-chrono\")))]\nimpl_into_active_value!(crate::prelude::Date);\n\n#[cfg(feature = \"with-chrono\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-chrono\")))]\nimpl_into_active_value!(crate::prelude::Time);\n\n#[cfg(feature = \"with-chrono\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-chrono\")))]\nimpl_into_active_value!(crate::prelude::DateTime);\n\n#[cfg(feature = \"with-chrono\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-chrono\")))]\nimpl_into_active_value!(crate::prelude::DateTimeWithTimeZone);\n\n#[cfg(feature = \"with-chrono\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-chrono\")))]\nimpl_into_active_value!(crate::prelude::DateTimeUtc);\n\n#[cfg(feature = \"with-chrono\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-chrono\")))]\nimpl_into_active_value!(crate::prelude::DateTimeLocal);\n\n#[cfg(feature = \"with-rust_decimal\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-rust_decimal\")))]\nimpl_into_active_value!(crate::prelude::Decimal);\n\n#[cfg(feature = \"with-bigdecimal\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-bigdecimal\")))]\nimpl_into_active_value!(crate::prelude::BigDecimal);\n\n#[cfg(feature = \"with-uuid\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-uuid\")))]\nimpl_into_active_value!(crate::prelude::Uuid);\n\n#[cfg(feature = \"with-time\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-time\")))]\nimpl_into_active_value!(crate::prelude::TimeDate);\n\n#[cfg(feature = \"with-time\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-time\")))]\nimpl_into_active_value!(crate::prelude::TimeTime);\n\n#[cfg(feature = \"with-time\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-time\")))]\nimpl_into_active_value!(crate::prelude::TimeDateTime);\n\n#[cfg(feature = \"with-time\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-time\")))]\nimpl_into_active_value!(crate::prelude::TimeDateTimeWithTimeZone);\n\n#[cfg(feature = \"with-ipnetwork\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-ipnetwork\")))]\nimpl_into_active_value!(crate::prelude::IpNetwork);\n\nimpl<V> Default for ActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    /// Create an [ActiveValue::NotSet]\n    fn default() -> Self {\n        Self::NotSet\n    }\n}\n\nimpl<V> ActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    /// Create an [ActiveValue::Set]\n    pub fn set(value: V) -> Self {\n        Self::Set(value)\n    }\n\n    /// Check if the [ActiveValue] is [ActiveValue::Set]\n    pub fn is_set(&self) -> bool {\n        matches!(self, Self::Set(_))\n    }\n\n    /// Create an [ActiveValue::Unchanged]\n    pub fn unchanged(value: V) -> Self {\n        Self::Unchanged(value)\n    }\n\n    /// Check if the [ActiveValue] is [ActiveValue::Unchanged]\n    pub fn is_unchanged(&self) -> bool {\n        matches!(self, Self::Unchanged(_))\n    }\n\n    /// Create an [ActiveValue::NotSet]\n    pub fn not_set() -> Self {\n        Self::default()\n    }\n\n    /// Check if the [ActiveValue] is [ActiveValue::NotSet]\n    pub fn is_not_set(&self) -> bool {\n        matches!(self, Self::NotSet)\n    }\n\n    /// Take ownership of the inner value, also setting self to `NotSet`\n    pub fn take(&mut self) -> Option<V> {\n        match std::mem::take(self) {\n            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => Some(value),\n            ActiveValue::NotSet => None,\n        }\n    }\n\n    /// Get an owned value of the [ActiveValue]\n    ///\n    /// # Panics\n    ///\n    /// Panics if it is [ActiveValue::NotSet]\n    pub fn unwrap(self) -> V {\n        match self {\n            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => value,\n            ActiveValue::NotSet => panic!(\"Cannot unwrap ActiveValue::NotSet\"),\n        }\n    }\n\n    /// Take ownership of the inner value, consuming self\n    pub fn into_value(self) -> Option<Value> {\n        match self {\n            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => Some(value.into()),\n            ActiveValue::NotSet => None,\n        }\n    }\n\n    /// Wrap the [Value] into a `ActiveValue<Value>`\n    pub fn into_wrapped_value(self) -> ActiveValue<Value> {\n        match self {\n            Self::Set(value) => ActiveValue::set(value.into()),\n            Self::Unchanged(value) => ActiveValue::unchanged(value.into()),\n            Self::NotSet => ActiveValue::not_set(),\n        }\n    }\n\n    /// Reset the value from [ActiveValue::Unchanged] to [ActiveValue::Set],\n    /// leaving [ActiveValue::NotSet] untouched.\n    pub fn reset(&mut self) {\n        *self = match self.take() {\n            Some(value) => ActiveValue::Set(value),\n            None => ActiveValue::NotSet,\n        };\n    }\n\n    /// `Set(value)`, except when [`self.is_unchanged()`][ActiveValue#method.is_unchanged]\n    /// and `value` equals the current [Unchanged][ActiveValue::Unchanged] value.\n    ///\n    /// This is useful when you have an [Unchanged][ActiveValue::Unchanged] value from the database,\n    /// then update it using this method,\n    /// and then use [`.is_unchanged()`][ActiveValue#method.is_unchanged] to see whether it has *actually* changed.\n    ///\n    /// The same nice effect applies to the entire `ActiveModel`.\n    /// You can now meaningfully use [ActiveModelTrait::is_changed][ActiveModelTrait#method.is_changed]\n    /// to see whether are any changes that need to be saved to the database.\n    ///\n    /// ## Examples\n    ///\n    /// ```\n    /// # use sea_orm::ActiveValue;\n    /// #\n    /// let mut value = ActiveValue::Unchanged(\"old\");\n    ///\n    /// // This wouldn't be the case if we used plain `value = Set(\"old\");`\n    /// value.set_if_not_equals(\"old\");\n    /// assert!(value.is_unchanged());\n    ///\n    /// // Only when we change the actual `&str` value, it becomes `Set`\n    /// value.set_if_not_equals(\"new\");\n    /// assert_eq!(value.is_unchanged(), false);\n    /// assert_eq!(value, ActiveValue::Set(\"new\"));\n    /// ```\n    pub fn set_if_not_equals(&mut self, value: V)\n    where\n        V: PartialEq,\n    {\n        match self {\n            ActiveValue::Unchanged(current) if &value == current => {}\n            _ => *self = ActiveValue::Set(value),\n        }\n    }\n\n    /// `Set(value)`, except when [`self.is_unchanged()`][ActiveValue#method.is_unchanged],\n    /// `value` equals the current [Unchanged][ActiveValue::Unchanged] value, and `value`\n    /// does not match a given predicate.\n    ///\n    /// This is useful in the same situations as [ActiveValue#method.set_if_not_equals] as\n    /// well as when you want to leave an existing [Set][ActiveValue::Set] value alone\n    /// depending on a condition, such as ensuring a `None` value never replaced an\n    /// existing `Some` value. This can come up when trying to merge two [ActiveValue]s.\n    ///\n    /// ## Examples\n    ///\n    /// ```\n    /// # use sea_orm::ActiveValue;\n    /// #\n    /// let mut value = ActiveValue::Set(Some(\"old\"));\n    ///\n    /// // since Option::is_some(None) == false, we leave the existing set value alone\n    /// value.set_if_not_equals_and(None, Option::is_some);\n    /// assert_eq!(value, ActiveValue::Set(Some(\"old\")));\n    ///\n    /// // since Option::is_some(Some(\"new\")) == true, we replace the set value\n    /// value.set_if_not_equals_and(Some(\"new\"), Option::is_some);\n    /// assert_eq!(value, ActiveValue::Set(Some(\"new\")));\n    /// ```\n    pub fn set_if_not_equals_and(&mut self, value: V, f: impl FnOnce(&V) -> bool)\n    where\n        V: PartialEq,\n    {\n        match self {\n            ActiveValue::Unchanged(current) if &value == current => {}\n            ActiveValue::Set(_) if !f(&value) => {}\n            _ => *self = ActiveValue::Set(value),\n        }\n    }\n\n    /// Get the inner value, unless `self` is [NotSet][ActiveValue::NotSet].\n    ///\n    /// There's also a panicking version: [ActiveValue::as_ref].\n    ///\n    /// ## Examples\n    ///\n    /// ```\n    /// # use sea_orm::ActiveValue;\n    /// #\n    /// assert_eq!(ActiveValue::Unchanged(42).try_as_ref(), Some(&42));\n    /// assert_eq!(ActiveValue::Set(42).try_as_ref(), Some(&42));\n    /// assert_eq!(ActiveValue::NotSet.try_as_ref(), None::<&i32>);\n    /// ```\n    pub fn try_as_ref(&self) -> Option<&V> {\n        match self {\n            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => Some(value),\n            ActiveValue::NotSet => None,\n        }\n    }\n}\n\nimpl<V> std::convert::AsRef<V> for ActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    /// # Panics\n    ///\n    /// Panics if it is [ActiveValue::NotSet].\n    ///\n    /// See [ActiveValue::try_as_ref] for a fallible non-panicking version.\n    fn as_ref(&self) -> &V {\n        match self {\n            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => value,\n            ActiveValue::NotSet => panic!(\"Cannot borrow ActiveValue::NotSet\"),\n        }\n    }\n}\n\nimpl<V> PartialEq for ActiveValue<V>\nwhere\n    V: Into<Value> + std::cmp::PartialEq,\n{\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (ActiveValue::Set(l), ActiveValue::Set(r)) => l == r,\n            (ActiveValue::Unchanged(l), ActiveValue::Unchanged(r)) => l == r,\n            (ActiveValue::NotSet, ActiveValue::NotSet) => true,\n            _ => false,\n        }\n    }\n}\n\nimpl<V> From<ActiveValue<V>> for ActiveValue<Option<V>>\nwhere\n    V: Into<Value> + Nullable,\n{\n    fn from(value: ActiveValue<V>) -> Self {\n        match value {\n            ActiveValue::Set(value) => ActiveValue::set(Some(value)),\n            ActiveValue::Unchanged(value) => ActiveValue::unchanged(Some(value)),\n            ActiveValue::NotSet => ActiveValue::not_set(),\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/arrow_schema.rs",
    "content": "/// Trait for Entities with Arrow integration\npub trait ArrowSchema {\n    /// Get the Arrow schema for this Entity\n    fn arrow_schema() -> sea_orm_arrow::arrow::datatypes::Schema;\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/base_entity.rs",
    "content": "use crate::{\n    ActiveModelBehavior, ActiveModelTrait, ColumnTrait, Delete, DeleteMany, DeleteOne,\n    FromQueryResult, Identity, Insert, InsertMany, ModelTrait, PrimaryKeyArity, PrimaryKeyToColumn,\n    PrimaryKeyTrait, QueryFilter, Related, RelationBuilder, RelationTrait, RelationType, Select,\n    Update, UpdateMany, UpdateOne, ValidatedDeleteOne,\n};\nuse sea_query::{Iden, IntoIden, IntoTableRef, IntoValueTuple, TableRef};\nuse std::fmt::Debug;\npub use strum::IntoEnumIterator as Iterable;\n\n/// Ensure the identifier for an Entity can be converted to a static str\npub trait IdenStatic: Iden + Copy + Debug + 'static {\n    /// Method to call to get the static string identity\n    fn as_str(&self) -> &'static str;\n}\n\n/// A Trait for mapping an Entity to a database table\npub trait EntityName: IdenStatic + Default {\n    /// Method to get the name for the schema, defaults to [Option::None] if not set\n    fn schema_name(&self) -> Option<&str> {\n        None\n    }\n\n    /// Method to get the comment for the schema, defaults to [Option::None] if not set\n    fn comment(&self) -> Option<&str> {\n        None\n    }\n\n    /// Get the name of the table\n    fn table_name(&self) -> &'static str;\n\n    /// Get the [TableRef] from invoking the `self.schema_name()`\n    fn table_ref(&self) -> TableRef {\n        match self.schema_name() {\n            Some(schema) => (schema.to_owned(), self.into_iden()).into_table_ref(),\n            None => self.into_table_ref(),\n        }\n    }\n}\n\n/// An abstract base class for defining Entities.\n///\n/// This trait provides an API for you to inspect it's properties\n/// - Column (implemented [`ColumnTrait`])\n/// - Relation (implemented [`RelationTrait`])\n/// - Primary Key (implemented [`PrimaryKeyTrait`] and [`PrimaryKeyToColumn`])\n///\n/// This trait also provides an API for CRUD actions\n/// - Select: `find`, `find_*`\n/// - Insert: `insert`, `insert_*`\n/// - Update: `update`, `update_*`\n/// - Delete: `delete`, `delete_*`\npub trait EntityTrait: EntityName {\n    #[allow(missing_docs)]\n    type Model: ModelTrait<Entity = Self> + FromQueryResult;\n\n    #[allow(missing_docs)]\n    type ModelEx: ModelTrait<Entity = Self>;\n\n    #[allow(missing_docs)]\n    type ActiveModel: ActiveModelBehavior<Entity = Self>;\n\n    #[allow(missing_docs)]\n    type ActiveModelEx: ActiveModelTrait<Entity = Self>;\n\n    #[allow(missing_docs)]\n    type Column: ColumnTrait;\n\n    #[allow(missing_docs)]\n    type Relation: RelationTrait;\n\n    #[allow(missing_docs)]\n    type PrimaryKey: PrimaryKeyTrait + PrimaryKeyToColumn<Column = Self::Column>;\n\n    /// Construct a belongs to relation, where this table has a foreign key to\n    /// another table.\n    fn belongs_to<R>(related: R) -> RelationBuilder<Self, R>\n    where\n        R: EntityTrait,\n    {\n        RelationBuilder::new(RelationType::HasOne, Self::default(), related, false)\n    }\n\n    /// Construct a has one relation\n    fn has_one<R>(_: R) -> RelationBuilder<Self, R>\n    where\n        R: EntityTrait + Related<Self>,\n    {\n        RelationBuilder::from_rel(RelationType::HasOne, R::to().rev(), true)\n    }\n\n    /// Construct a has many relation\n    fn has_many<R>(_: R) -> RelationBuilder<Self, R>\n    where\n        R: EntityTrait + Related<Self>,\n    {\n        RelationBuilder::from_rel(RelationType::HasMany, R::to().rev(), true)\n    }\n\n    /// Construct a has many relation, with the Relation provided.\n    /// This is for the case where `Related<Self>` is not possible.\n    fn has_many_via<R, T>(_: R, rel: T) -> RelationBuilder<Self, R>\n    where\n        R: EntityTrait,\n        T: RelationTrait,\n    {\n        RelationBuilder::from_rel(RelationType::HasMany, rel.def().rev(), true)\n    }\n\n    /// Construct select statement to find one / all models\n    ///\n    /// - To select columns, join tables and group by expressions, see [`QuerySelect`](crate::query::QuerySelect)\n    /// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)\n    /// - To apply order by expressions, see [`QueryOrder`](crate::query::QueryOrder)\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         vec![\n    /// #             cake::Model {\n    /// #                 id: 1,\n    /// #                 name: \"New York Cheese\".to_owned(),\n    /// #             },\n    /// #         ],\n    /// #         vec![\n    /// #             cake::Model {\n    /// #                 id: 1,\n    /// #                 name: \"New York Cheese\".to_owned(),\n    /// #             },\n    /// #             cake::Model {\n    /// #                 id: 2,\n    /// #                 name: \"Chocolate Forest\".to_owned(),\n    /// #             },\n    /// #         ],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find().one(&db)?,\n    ///     Some(cake::Model {\n    ///         id: 1,\n    ///         name: \"New York Cheese\".to_owned(),\n    ///     })\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find().all(&db)?,\n    ///     [\n    ///         cake::Model {\n    ///             id: 1,\n    ///             name: \"New York Cheese\".to_owned(),\n    ///         },\n    ///         cake::Model {\n    ///             id: 2,\n    ///             name: \"Chocolate Forest\".to_owned(),\n    ///         },\n    ///     ]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::Postgres,\n    ///             r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" LIMIT $1\"#,\n    ///             [1u64.into()]\n    ///         ),\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::Postgres,\n    ///             r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n    ///             []\n    ///         ),\n    ///     ]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn find() -> Select<Self> {\n        Select::new()\n    }\n\n    /// Same as `find_related`, but using the other Entity's relation definition.\n    /// Not stable.\n    #[doc(hidden)]\n    fn find_related_rev<R>() -> Select<R>\n    where\n        R: EntityTrait,\n        R: Related<Self>,\n    {\n        use crate::{JoinType, QuerySelect};\n        Select::<R>::new().join_join(JoinType::InnerJoin, R::to(), R::via())\n    }\n\n    /// Find a model by primary key\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [\n    /// #             cake::Model {\n    /// #                 id: 11,\n    /// #                 name: \"Sponge Cake\".to_owned(),\n    /// #             },\n    /// #         ],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find_by_id(11).all(&db)?,\n    ///     [cake::Model {\n    ///         id: 11,\n    ///         name: \"Sponge Cake\".to_owned(),\n    ///     }]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = $1\"#,\n    ///         [11i32.into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    /// Find by composite key\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [\n    /// #             cake_filling::Model {\n    /// #                 cake_id: 2,\n    /// #                 filling_id: 3,\n    /// #             },\n    /// #         ],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake_filling};\n    ///\n    /// assert_eq!(\n    ///     cake_filling::Entity::find_by_id((2, 3)).all(&db)?,\n    ///     [cake_filling::Model {\n    ///         cake_id: 2,\n    ///         filling_id: 3,\n    ///     }]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         [\n    ///             r#\"SELECT \"cake_filling\".\"cake_id\", \"cake_filling\".\"filling_id\" FROM \"cake_filling\"\"#,\n    ///             r#\"WHERE \"cake_filling\".\"cake_id\" = $1 AND \"cake_filling\".\"filling_id\" = $2\"#,\n    ///         ].join(\" \").as_str(),\n    ///         [2i32.into(), 3i32.into()]\n    ///     )]);\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn find_by_id<T>(values: T) -> Select<Self>\n    where\n        T: Into<<Self::PrimaryKey as PrimaryKeyTrait>::ValueType>,\n    {\n        let mut select = Self::find();\n        let mut keys = Self::PrimaryKey::iter();\n        for v in values.into().into_value_tuple() {\n            if let Some(key) = keys.next() {\n                let col = key.into_column();\n                select = select.filter(col.eq(v));\n            } else {\n                unreachable!(\"primary key arity mismatch\");\n            }\n        }\n        select\n    }\n\n    /// Get primary key as Identity\n    fn primary_key_identity() -> Identity {\n        let mut cols = Self::PrimaryKey::iter();\n        macro_rules! next {\n            () => {\n                cols.next()\n                    .expect(\"Already checked arity\")\n                    .into_column()\n                    .as_column_ref()\n                    .1\n            };\n        }\n        match <<Self::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n            1 => {\n                let s1 = next!();\n                Identity::Unary(s1)\n            }\n            2 => {\n                let s1 = next!();\n                let s2 = next!();\n                Identity::Binary(s1, s2)\n            }\n            3 => {\n                let s1 = next!();\n                let s2 = next!();\n                let s3 = next!();\n                Identity::Ternary(s1, s2, s3)\n            }\n            len => {\n                let mut vec = Vec::with_capacity(len);\n                for _ in 0..len {\n                    let s = next!();\n                    vec.push(s);\n                }\n                Identity::Many(vec)\n            }\n        }\n    }\n\n    /// Insert a model into database\n    ///\n    /// # Example (Postgres)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[maplit::btreemap! {\n    /// #         \"id\" => Into::<Value>::into(15),\n    /// #     }]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let apple = cake::ActiveModel {\n    ///     name: Set(\"Apple Pie\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// let insert_result = cake::Entity::insert(apple).exec(&db)?;\n    ///\n    /// assert_eq!(dbg!(insert_result.last_insert_id), 15);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"INSERT INTO \"cake\" (\"name\") VALUES ($1) RETURNING \"id\"\"#,\n    ///         [\"Apple Pie\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// # Example (MySQL)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::MySql)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 15,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let apple = cake::ActiveModel {\n    ///     name: Set(\"Apple Pie\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// let insert_result = cake::Entity::insert(apple).exec(&db)?;\n    ///\n    /// assert_eq!(insert_result.last_insert_id, 15);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::MySql,\n    ///         r#\"INSERT INTO `cake` (`name`) VALUES (?)\"#,\n    ///         [\"Apple Pie\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// To get back inserted Model\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Apple Pie\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::insert(cake::ActiveModel {\n    ///         id: NotSet,\n    ///         name: Set(\"Apple Pie\".to_owned()),\n    ///     })\n    ///     .exec_with_returning(&db)\n    ///     ?,\n    ///     cake::Model {\n    ///         id: 1,\n    ///         name: \"Apple Pie\".to_owned(),\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log()[0].statements()[0].sql,\n    ///     r#\"INSERT INTO \"cake\" (\"name\") VALUES ($1) RETURNING \"id\", \"name\"\"#\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn insert<A>(model: A) -> Insert<A>\n    where\n        A: ActiveModelTrait<Entity = Self>,\n    {\n        Insert::one(model)\n    }\n\n    /// Insert many models into database\n    ///\n    /// # Example (Postgres)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[maplit::btreemap! {\n    /// #         \"id\" => Into::<Value>::into(28),\n    /// #     }]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let apple = cake::ActiveModel {\n    ///     name: Set(\"Apple Pie\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    /// let orange = cake::ActiveModel {\n    ///     name: Set(\"Orange Scone\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// let insert_result = cake::Entity::insert_many::<cake::ActiveModel, _>([])\n    ///     .exec(&db)\n    ///     ?;\n    ///\n    /// assert_eq!(insert_result.last_insert_id, None);\n    ///\n    /// let insert_result = cake::Entity::insert_many([apple, orange]).exec(&db)?;\n    ///\n    /// assert_eq!(insert_result.last_insert_id, Some(28));\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"INSERT INTO \"cake\" (\"name\") VALUES ($1), ($2) RETURNING \"id\"\"#,\n    ///         [\"Apple Pie\".into(), \"Orange Scone\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// # Example (MySQL)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::MySql)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 28,\n    /// #             rows_affected: 2,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let apple = cake::ActiveModel {\n    ///     name: Set(\"Apple Pie\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    /// let orange = cake::ActiveModel {\n    ///     name: Set(\"Orange Scone\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// let insert_result = cake::Entity::insert_many([apple, orange]).exec(&db)?;\n    ///\n    /// assert_eq!(insert_result.last_insert_id, Some(28));\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::MySql,\n    ///         r#\"INSERT INTO `cake` (`name`) VALUES (?), (?)\"#,\n    ///         [\"Apple Pie\".into(), \"Orange Scone\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// Before 1.1.3, if the active models have different column set, this method would panic.\n    /// Now, it'd attempt to fill in the missing columns with null\n    /// (which may or may not be correct, depending on whether the column is nullable):\n    ///\n    /// ```\n    /// use sea_orm::{\n    ///     DbBackend,\n    ///     entity::*,\n    ///     query::*,\n    ///     tests_cfg::{cake, cake_filling},\n    /// };\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::insert_many([\n    ///         cake::ActiveModel {\n    ///             id: NotSet,\n    ///             name: Set(\"Apple Pie\".to_owned()),\n    ///         },\n    ///         cake::ActiveModel {\n    ///             id: NotSet,\n    ///             name: Set(\"Orange Scone\".to_owned()),\n    ///         }\n    ///     ])\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"name\") VALUES ('Apple Pie'), ('Orange Scone')\"#,\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake_filling::Entity::insert_many([\n    ///         cake_filling::ActiveModel {\n    ///             cake_id: ActiveValue::set(2),\n    ///             filling_id: ActiveValue::NotSet,\n    ///         },\n    ///         cake_filling::ActiveModel {\n    ///             cake_id: ActiveValue::NotSet,\n    ///             filling_id: ActiveValue::set(3),\n    ///         }\n    ///     ])\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"INSERT INTO \"cake_filling\" (\"cake_id\", \"filling_id\") VALUES (2, NULL), (NULL, 3)\"#,\n    /// );\n    /// ```\n    ///\n    /// To get back inserted Models\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Apple Pie\".to_owned(),\n    /// #         }, cake::Model {\n    /// #             id: 2,\n    /// #             name: \"Choco Pie\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::insert_many([\n    ///         cake::ActiveModel {\n    ///             id: NotSet,\n    ///             name: Set(\"Apple Pie\".to_owned()),\n    ///         },\n    ///         cake::ActiveModel {\n    ///             id: NotSet,\n    ///             name: Set(\"Choco Pie\".to_owned()),\n    ///         },\n    ///     ])\n    ///     .exec_with_returning(&db)\n    ///     ?,\n    ///     [\n    ///         cake::Model {\n    ///             id: 1,\n    ///             name: \"Apple Pie\".to_owned(),\n    ///         },\n    ///         cake::Model {\n    ///             id: 2,\n    ///             name: \"Choco Pie\".to_owned(),\n    ///         }\n    ///     ]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log()[0].statements()[0].sql,\n    ///     r#\"INSERT INTO \"cake\" (\"name\") VALUES ($1), ($2) RETURNING \"id\", \"name\"\"#\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn insert_many<A, I>(models: I) -> InsertMany<A>\n    where\n        A: ActiveModelTrait<Entity = Self>,\n        I: IntoIterator<Item = A>,\n    {\n        InsertMany::many(models)\n    }\n\n    /// Update a model in database\n    ///\n    /// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)\n    ///\n    /// # Example (Postgres)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [fruit::Model {\n    /// #             id: 1,\n    /// #             name: \"Orange\".to_owned(),\n    /// #             cake_id: None,\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let orange = fruit::ActiveModel {\n    ///     id: Set(1),\n    ///     name: Set(\"Orange\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// assert_eq!(\n    ///     fruit::Entity::update(orange.clone())\n    ///         .validate()?\n    ///         .filter(fruit::Column::Name.contains(\"orange\"))\n    ///         .exec(&db)\n    ///         ?,\n    ///     fruit::Model {\n    ///         id: 1,\n    ///         name: \"Orange\".to_owned(),\n    ///         cake_id: None,\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"UPDATE \"fruit\" SET \"name\" = $1 WHERE \"fruit\".\"id\" = $2 AND \"fruit\".\"name\" LIKE $3 RETURNING \"id\", \"name\", \"cake_id\"\"#,\n    ///         [\"Orange\".into(), 1i32.into(), \"%orange%\".into()]\n    ///     )]);\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// # Example (MySQL)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::MySql)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .append_query_results([\n    /// #         [fruit::Model {\n    /// #             id: 1,\n    /// #             name: \"Orange\".to_owned(),\n    /// #             cake_id: None,\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let orange = fruit::ActiveModel {\n    ///     id: Set(1),\n    ///     name: Set(\"Orange\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// assert_eq!(\n    ///     fruit::Entity::update(orange.clone())\n    ///         .validate()?\n    ///         .filter(fruit::Column::Name.contains(\"orange\"))\n    ///         .exec(&db)\n    ///         ?,\n    ///     fruit::Model {\n    ///         id: 1,\n    ///         name: \"Orange\".to_owned(),\n    ///         cake_id: None,\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::MySql,\n    ///             r#\"UPDATE `fruit` SET `name` = ? WHERE `fruit`.`id` = ? AND `fruit`.`name` LIKE ?\"#,\n    ///             [\"Orange\".into(), 1i32.into(), \"%orange%\".into()]\n    ///         ),\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::MySql,\n    ///             r#\"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = ? LIMIT ?\"#,\n    ///             [1i32.into(), 1u64.into()]\n    ///         )]);\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn update<A>(model: A) -> UpdateOne<A>\n    where\n        A: ActiveModelTrait<Entity = Self>,\n    {\n        Update::one(model)\n    }\n\n    /// Update many models in database\n    ///\n    /// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 5,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{\n    ///     entity::*,\n    ///     query::*,\n    ///     sea_query::{Expr, Value},\n    ///     tests_cfg::fruit,\n    /// };\n    ///\n    /// let update_result = fruit::Entity::update_many()\n    ///     .col_expr(fruit::Column::CakeId, Expr::value(Value::Int(None)))\n    ///     .filter(fruit::Column::Name.contains(\"Apple\"))\n    ///     .exec(&db)\n    ///     ?;\n    ///\n    /// assert_eq!(update_result.rows_affected, 5);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"UPDATE \"fruit\" SET \"cake_id\" = $1 WHERE \"fruit\".\"name\" LIKE $2\"#,\n    ///         [Value::Int(None), \"%Apple%\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn update_many() -> UpdateMany<Self> {\n        Update::many(Self::default())\n    }\n\n    /// Delete a model from database\n    ///\n    /// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let orange = fruit::ActiveModel {\n    ///     id: Set(3),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// let delete_result = fruit::Entity::delete(orange).exec(&db)?;\n    ///\n    /// assert_eq!(delete_result.rows_affected, 1);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"DELETE FROM \"fruit\" WHERE \"fruit\".\"id\" = $1\"#,\n    ///         [3i32.into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn delete<A>(model: A) -> DeleteOne<Self>\n    where\n        A: ActiveModelTrait<Entity = Self>,\n    {\n        Delete::one(model)\n    }\n\n    /// Delete many models from database\n    ///\n    /// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 5,\n    /// #         },\n    /// #     ])\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 15,\n    /// #             name: \"Apple Pie\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let delete_result = fruit::Entity::delete_many()\n    ///     .filter(fruit::Column::Name.contains(\"Apple\"))\n    ///     .exec(&db)\n    ///     ?;\n    ///\n    /// assert_eq!(delete_result.rows_affected, 5);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"DELETE FROM \"fruit\" WHERE \"fruit\".\"name\" LIKE $1\"#,\n    ///         [\"%Apple%\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn delete_many() -> DeleteMany<Self> {\n        Delete::many(Self::default())\n    }\n\n    /// Delete a model based on primary key\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let delete_result = fruit::Entity::delete_by_id(1).exec(&db)?;\n    ///\n    /// assert_eq!(delete_result.rows_affected, 1);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"DELETE FROM \"fruit\" WHERE \"fruit\".\"id\" = $1\"#,\n    ///         [1i32.into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    /// Delete by composite key\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    ///\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake_filling};\n    ///\n    /// let delete_result = cake_filling::Entity::delete_by_id((2, 3)).exec(&db)?;\n    ///\n    /// assert_eq!(delete_result.rows_affected, 1);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"DELETE FROM \"cake_filling\" WHERE \"cake_filling\".\"cake_id\" = $1 AND \"cake_filling\".\"filling_id\" = $2\"#,\n    ///         [2i32.into(), 3i32.into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn delete_by_id<T>(values: T) -> ValidatedDeleteOne<Self>\n    where\n        T: Into<<Self::PrimaryKey as PrimaryKeyTrait>::ValueType>,\n    {\n        let mut am = Self::ActiveModel::default();\n        let mut keys = Self::PrimaryKey::iter();\n        for v in values.into().into_value_tuple() {\n            if let Some(key) = keys.next() {\n                let col = key.into_column();\n                am.set(col, v);\n            } else {\n                unreachable!(\"primary key arity mismatch\");\n            }\n        }\n        Delete::one(am).validate().expect(\"Must be valid\")\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    #[test]\n    fn test_delete_by_id_1() {\n        use crate::tests_cfg::cake;\n        use crate::{DbBackend, entity::*, query::*};\n        assert_eq!(\n            cake::Entity::delete_by_id(1)\n                .build(DbBackend::Sqlite)\n                .to_string(),\n            r#\"DELETE FROM \"cake\" WHERE \"cake\".\"id\" = 1\"#,\n        );\n    }\n\n    #[test]\n    fn test_delete_by_id_2() {\n        use crate::tests_cfg::cake_filling_price;\n        use crate::{DbBackend, entity::*, query::*};\n        assert_eq!(\n            cake_filling_price::Entity::delete_by_id((1, 2))\n                .build(DbBackend::Sqlite)\n                .to_string(),\n            r#\"DELETE FROM \"public\".\"cake_filling_price\" WHERE \"cake_filling_price\".\"cake_id\" = 1 AND \"cake_filling_price\".\"filling_id\" = 2\"#,\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn entity_model_1() {\n        use crate::entity::*;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Entity.table_name(), \"hello\");\n        assert_eq!(hello::Entity.schema_name(), None);\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn entity_model_2() {\n        use crate::entity::*;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\", schema_name = \"world\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Entity.table_name(), \"hello\");\n        assert_eq!(hello::Entity.schema_name(), Some(\"world\"));\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn entity_model_3() {\n        use crate::{DbBackend, entity::*, query::*};\n        use std::borrow::Cow;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\", schema_name = \"world\")]\n            pub struct Model {\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        fn delete_by_id<T>(value: T)\n        where\n            T: Into<<<hello::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType>,\n        {\n            assert_eq!(\n                hello::Entity::delete_by_id(value)\n                    .build(DbBackend::Sqlite)\n                    .to_string(),\n                r#\"DELETE FROM \"world\".\"hello\" WHERE \"hello\".\"id\" = 'UUID'\"#\n            );\n        }\n\n        delete_by_id(\"UUID\".to_string());\n        delete_by_id(\"UUID\");\n        delete_by_id(Cow::from(\"UUID\"));\n    }\n\n    #[test]\n    fn test_find_by_id() {\n        use crate::tests_cfg::{cake, cake_filling};\n        use crate::{DbBackend, EntityTrait, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::MySql).into_connection();\n\n        cake::Entity::find_by_id(1).all(&db).ok();\n        cake_filling::Entity::find_by_id((2, 3)).all(&db).ok();\n\n        // below does not compile:\n\n        // cake::Entity::find_by_id((1, 2)).all(&db).ok();\n        // cake_filling::Entity::find_by_id(1).all(&db).ok();\n        // cake_filling::Entity::find_by_id((1, 2, 3))\n        //     .all(&db)\n        //\n        //     .ok();\n    }\n\n    #[test]\n    fn test_triangle() {\n        mod triangle {\n            use crate as sea_orm;\n            use sea_orm::entity::prelude::*;\n            use serde::{Deserialize, Serialize};\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"triangle\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                pub p1: Point,\n                pub p2: Point,\n                pub p3: Point,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n\n            #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, FromJsonQueryResult)]\n            pub struct Point {\n                pub x: f64,\n                pub y: f64,\n            }\n        }\n        use triangle::{Model as Triangle, Point};\n\n        impl Triangle {\n            fn area(&self) -> f64 {\n                let a = self.p1.distance_to(&self.p2);\n                let b = self.p2.distance_to(&self.p3);\n                let c = self.p3.distance_to(&self.p1);\n                let s = (a + b + c) / 2.0;\n                (s * (s - a) * (s - b) * (s - c)).sqrt()\n            }\n        }\n\n        impl Point {\n            fn distance_to(&self, p: &Point) -> f64 {\n                let dx = self.x - p.x;\n                let dy = self.y - p.y;\n                (dx * dx + dy * dy).sqrt()\n            }\n        }\n\n        assert!(\n            (Triangle {\n                id: 1,\n                p1: Point { x: 0., y: 0. },\n                p2: Point { x: 2., y: 0. },\n                p3: Point { x: 0., y: 2. },\n            }\n            .area()\n                - 2.)\n                .abs()\n                < 0.00000001\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/column/types/postgres_array.rs",
    "content": "use super::*;\nuse crate::ExprTrait;\n\nmacro_rules! bind_array_oper {\n    ($vis:vis $op:ident) => {\n        /// Postgres only.\n        $vis fn $op<V, I>(&self, v: I) -> Expr\n        where\n            V: Into<Value> + sea_query::ValueType + sea_query::postgres_array::NotU8,\n            I: IntoIterator<Item = V>,\n        {\n            let vec: Vec<_> = v.into_iter().collect();\n            Expr::col(self.as_column_ref()).$op(self.0.save_as(Expr::val(vec)))\n        }\n    };\n    ($vis:vis $op:ident, trait $value_ty:ident) => {\n        /// Postgres only.\n        $vis fn $op<V, I>(&self, v: I) -> Expr\n        where\n            V: Into<Value> + $value_ty + sea_query::ValueType + sea_query::postgres_array::NotU8,\n            I: IntoIterator<Item = V>,\n        {\n            let vec: Vec<_> = v.into_iter().collect();\n            Expr::col(self.as_column_ref()).$op(self.0.save_as(Expr::val(vec)))\n        }\n    };\n    ($vis:vis $op:ident, $func:ident) => {\n        /// Postgres only.\n        $vis fn $op<V, I>(&self, v: I) -> Expr\n        where\n            V: Into<Value> + sea_query::ValueType + sea_query::postgres_array::NotU8,\n            I: IntoIterator<Item = V>,\n        {\n            self.0.$func(v)\n        }\n    };\n    ($vis:vis $op:ident, $func:ident, trait $value_ty:ident) => {\n        /// Postgres only.\n        $vis fn $op<V, I>(&self, v: I) -> Expr\n        where\n            V: Into<Value> + $value_ty + sea_query::ValueType + sea_query::postgres_array::NotU8,\n            I: IntoIterator<Item = V>,\n        {\n            self.0.$func(v)\n        }\n    };\n}\n\nimpl<E: EntityTrait> NumericArrayColumn<E> {\n    boilerplate!(pub);\n\n    bind_array_oper!(pub eq, trait NumericValue);\n    bind_array_oper!(pub ne, trait NumericValue);\n    bind_array_oper!(pub contains, array_contains, trait NumericValue);\n    bind_array_oper!(pub contained, array_contained, trait NumericValue);\n    bind_array_oper!(pub overlap, array_overlap, trait NumericValue);\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n\nimpl<E: EntityTrait> GenericArrayColumn<E> {\n    boilerplate!(pub);\n\n    bind_array_oper!(pub eq);\n    bind_array_oper!(pub ne);\n    bind_array_oper!(pub contains, array_contains);\n    bind_array_oper!(pub contained, array_contained);\n    bind_array_oper!(pub overlap, array_overlap);\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/column/types/with_datetime.rs",
    "content": "use super::*;\nuse sea_query::{DateLikeValue, DateTimeLikeValue, TimeLikeValue};\n\nimpl<E: EntityTrait> DateLikeColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait DateLikeValue);\n    bind_oper!(pub ne, ne, trait DateLikeValue);\n    bind_oper!(pub gt, gt, trait DateLikeValue);\n    bind_oper!(pub gte, gte, trait DateLikeValue);\n    bind_oper!(pub lt, lt, trait DateLikeValue);\n    bind_oper!(pub lte, lte, trait DateLikeValue);\n\n    bind_oper_2!(pub between, between, trait DateLikeValue);\n    bind_oper_2!(pub not_between, not_between, trait DateLikeValue);\n\n    bind_oper_0!(pub max, max);\n    bind_oper_0!(pub min, min);\n    bind_oper_0!(pub sum, sum);\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait DateLikeValue);\n\n    bind_vec_func!(pub is_in, is_in, trait DateLikeValue);\n    bind_vec_func!(pub is_not_in, is_not_in, trait DateLikeValue);\n\n    /// `= ANY(..)` operator. Postgres only.\n    #[cfg(feature = \"postgres-array\")]\n    pub fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + DateLikeValue + sea_query::ValueType + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        self.0.eq_any(v)\n    }\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n\nimpl<E: EntityTrait> TimeLikeColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait TimeLikeValue);\n    bind_oper!(pub ne, ne, trait TimeLikeValue);\n    bind_oper!(pub gt, gt, trait TimeLikeValue);\n    bind_oper!(pub gte, gte, trait TimeLikeValue);\n    bind_oper!(pub lt, lt, trait TimeLikeValue);\n    bind_oper!(pub lte, lte, trait TimeLikeValue);\n\n    bind_oper_2!(pub between, between, trait TimeLikeValue);\n    bind_oper_2!(pub not_between, not_between, trait TimeLikeValue);\n\n    bind_oper_0!(pub max, max);\n    bind_oper_0!(pub min, min);\n    bind_oper_0!(pub sum, sum);\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait TimeLikeValue);\n\n    bind_vec_func!(pub is_in, is_in, trait TimeLikeValue);\n    bind_vec_func!(pub is_not_in, is_not_in, trait TimeLikeValue);\n\n    /// `= ANY(..)` operator. Postgres only.\n    #[cfg(feature = \"postgres-array\")]\n    pub fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + TimeLikeValue + sea_query::ValueType + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        self.0.eq_any(v)\n    }\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n\nimpl<E: EntityTrait> DateTimeLikeColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait DateTimeLikeValue);\n    bind_oper!(pub ne, ne, trait DateTimeLikeValue);\n    bind_oper!(pub gt, gt, trait DateTimeLikeValue);\n    bind_oper!(pub gte, gte, trait DateTimeLikeValue);\n    bind_oper!(pub lt, lt, trait DateTimeLikeValue);\n    bind_oper!(pub lte, lte, trait DateTimeLikeValue);\n\n    bind_oper_2!(pub between, between, trait DateTimeLikeValue);\n    bind_oper_2!(pub not_between, not_between, trait DateTimeLikeValue);\n\n    bind_oper_0!(pub max, max);\n    bind_oper_0!(pub min, min);\n    bind_oper_0!(pub sum, sum);\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait DateTimeLikeValue);\n\n    bind_vec_func!(pub is_in, is_in, trait DateTimeLikeValue);\n    bind_vec_func!(pub is_not_in, is_not_in, trait DateTimeLikeValue);\n\n    /// `= ANY(..)` operator. Postgres only.\n    #[cfg(feature = \"postgres-array\")]\n    pub fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + DateTimeLikeValue + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        self.0.eq_any(v)\n    }\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/column/types/with_ipnetwork.rs",
    "content": "use super::*;\nuse crate::prelude::IpNetwork;\n\nimpl<E: EntityTrait> IpNetworkColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait Into<IpNetwork>);\n    bind_oper!(pub ne, ne, trait Into<IpNetwork>);\n    bind_oper!(pub gt, gt, trait Into<IpNetwork>);\n    bind_oper!(pub gte, gte, trait Into<IpNetwork>);\n    bind_oper!(pub lt, lt, trait Into<IpNetwork>);\n    bind_oper!(pub lte, lte, trait Into<IpNetwork>);\n\n    bind_oper_2!(pub between, between, trait Into<IpNetwork>);\n    bind_oper_2!(pub not_between, not_between, trait Into<IpNetwork>);\n\n    bind_oper_0!(pub max, max);\n    bind_oper_0!(pub min, min);\n    bind_oper_0!(pub sum, sum);\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait Into<IpNetwork>);\n\n    bind_vec_func!(pub is_in, is_in, trait Into<IpNetwork>);\n    bind_vec_func!(pub is_not_in, is_not_in, trait Into<IpNetwork>);\n\n    /// `= ANY(..)` operator. Postgres only.\n    #[cfg(feature = \"postgres-array\")]\n    pub fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + Into<IpNetwork> + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        self.0.eq_any(v)\n    }\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/column/types/with_json.rs",
    "content": "use super::*;\nuse crate::prelude::Json;\n\nimpl<E: EntityTrait> JsonColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait Into<Json>);\n    bind_oper!(pub ne, ne, trait Into<Json>);\n\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait Into<Json>);\n\n    bind_vec_func!(pub is_in, is_in, trait Into<Json>);\n    bind_vec_func!(pub is_not_in, is_not_in, trait Into<Json>);\n\n    /// `= ANY(..)` operator. Postgres only.\n    #[cfg(feature = \"postgres-array\")]\n    pub fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + Into<Json> + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        self.0.eq_any(v)\n    }\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/column/types/with_uuid.rs",
    "content": "use super::*;\nuse crate::prelude::{TextUuid, Uuid};\n\nimpl<E: EntityTrait> UuidColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait Into<Uuid>);\n    bind_oper!(pub ne, ne, trait Into<Uuid>);\n    bind_oper!(pub gt, gt, trait Into<Uuid>);\n    bind_oper!(pub gte, gte, trait Into<Uuid>);\n    bind_oper!(pub lt, lt, trait Into<Uuid>);\n    bind_oper!(pub lte, lte, trait Into<Uuid>);\n\n    bind_oper_2!(pub between, between, trait Into<Uuid>);\n    bind_oper_2!(pub not_between, not_between, trait Into<Uuid>);\n\n    bind_oper_0!(pub max, max);\n    bind_oper_0!(pub min, min);\n    bind_oper_0!(pub sum, sum);\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait Into<Uuid>);\n\n    bind_vec_func!(pub is_in, is_in, trait Into<Uuid>);\n    bind_vec_func!(pub is_not_in, is_not_in, trait Into<Uuid>);\n\n    /// `= ANY(..)` operator. Postgres only.\n    #[cfg(feature = \"postgres-array\")]\n    pub fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + Into<Uuid> + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        self.0.eq_any(v)\n    }\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n\nimpl<E: EntityTrait> TextUuidColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, type TextUuid);\n    bind_oper!(pub ne, ne, type TextUuid);\n    bind_oper!(pub gt, gt, type TextUuid);\n    bind_oper!(pub gte, gte, type TextUuid);\n    bind_oper!(pub lt, lt, type TextUuid);\n    bind_oper!(pub lte, lte, type TextUuid);\n\n    bind_oper_2!(pub between, between, type TextUuid);\n    bind_oper_2!(pub not_between, not_between, type TextUuid);\n\n    bind_oper_0!(pub max, max);\n    bind_oper_0!(pub min, min);\n    bind_oper_0!(pub sum, sum);\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, type TextUuid);\n\n    bind_vec_func!(pub is_in, is_in, type TextUuid);\n    bind_vec_func!(pub is_not_in, is_not_in, type TextUuid);\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/column/types.rs",
    "content": "#![allow(missing_docs)]\n\nuse crate::{ColumnDef, ColumnTrait, DynIden, EntityTrait, ExprTrait, Iden, IntoSimpleExpr, Value};\nuse sea_query::{Expr, NumericValue, NumericValueNullable, SelectStatement};\nuse std::borrow::Cow;\n\npub trait IntoOption<T> {\n    #[allow(dead_code)]\n    fn into_option(self) -> Option<T>;\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct BoolColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(BoolColumn);\n\n/// A column of numeric type, including integer, float and decimal\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct NumericColumn<E: EntityTrait>(pub E::Column);\n/// A column of numeric type, including integer, float and decimal that is also nullable\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct NumericColumnNullable<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(NumericColumn);\nimpl_expr_traits!(NumericColumnNullable);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct StringColumn<E: EntityTrait>(pub E::Column);\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct StringColumnNullable<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(StringColumn);\nimpl_expr_traits!(StringColumnNullable);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct BytesColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(BytesColumn);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct JsonColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(JsonColumn);\n// we dont need JsonColumnNullable because None can be converted to Json\n\n/// Supports both chrono and time Date\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct DateLikeColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(DateLikeColumn);\n\n/// Supports both chrono and time Time\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct TimeLikeColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(TimeLikeColumn);\n\n/// Supports both chrono and time DateTime\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct DateTimeLikeColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(DateTimeLikeColumn);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct UuidColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(UuidColumn);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct TextUuidColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(TextUuidColumn);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct IpNetworkColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(IpNetworkColumn);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct NumericArrayColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(NumericArrayColumn);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct GenericArrayColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(GenericArrayColumn);\n\n#[cfg(feature = \"with-json\")]\nmod with_json;\n\n#[cfg(any(feature = \"with-chrono\", feature = \"with-time\"))]\nmod with_datetime;\n\n#[cfg(feature = \"with-uuid\")]\nmod with_uuid;\n\n#[cfg(feature = \"with-ipnetwork\")]\nmod with_ipnetwork;\n\n#[cfg(feature = \"postgres-array\")]\nmod postgres_array;\n\nmod macros {\n    macro_rules! impl_expr_traits {\n        ($ty:ident) => {\n            impl<E: EntityTrait> Iden for $ty<E> {\n                fn quoted(&self) -> std::borrow::Cow<'static, str> {\n                    self.0.quoted()\n                }\n                fn unquoted(&self) -> &str {\n                    self.0.unquoted()\n                }\n            }\n\n            impl<E: EntityTrait> IntoSimpleExpr for $ty<E> {\n                fn into_simple_expr(self) -> Expr {\n                    self.0.into_simple_expr()\n                }\n            }\n        };\n    }\n\n    macro_rules! bind_oper_0 {\n        ($vis:vis $op:ident, $bind_op:ident) => {\n            $vis fn $op(&self) -> Expr {\n                self.0.$bind_op()\n            }\n        };\n    }\n\n    macro_rules! bind_oper {\n        ($vis:vis $op:ident, $bind_op:ident, trait $value_ty:path) => {\n            $vis fn $op<V>(&self, v: V) -> Expr\n            where\n                V: Into<Value> + $value_ty,\n            {\n                self.0.$bind_op(v)\n            }\n        };\n        ($vis:vis $op:ident, $bind_op:ident, type $value_ty:path) => {\n            $vis fn $op<V>(&self, v: V) -> Expr\n            where\n                V: Into<$value_ty>,\n            {\n                self.0.$bind_op(v.into())\n            }\n        };\n    }\n\n    macro_rules! bind_expr_oper {\n        ($vis:vis $op:ident, $bind_op:ident) => {\n            $vis fn $op<T>(&self, expr: T) -> Expr\n            where\n                T: Into<Expr>,\n            {\n                Expr::col(self.as_column_ref()).$bind_op(expr)\n            }\n        };\n    }\n\n    macro_rules! bind_oper_2 {\n        ($vis:vis $op:ident, $bind_op:ident, trait $value_ty:path) => {\n            $vis fn $op<V>(&self, v1: V, v2: V) -> Expr\n            where\n                V: Into<Value> + $value_ty,\n            {\n                self.0.$bind_op(v1, v2)\n            }\n        };\n        ($vis:vis $op:ident, $bind_op:ident, type $value_ty:path) => {\n            $vis fn $op<V>(&self, v1: V, v2: V) -> Expr\n            where\n                V: Into<$value_ty>,\n            {\n                self.0.$bind_op(v1.into(), v2.into())\n            }\n        };\n    }\n\n    macro_rules! bind_vec_func {\n        ($vis:vis $op:ident, $bind_op:ident, trait $value_ty:path) => {\n            #[allow(clippy::wrong_self_convention)]\n            $vis fn $op<V, I>(&self, v: I) -> Expr\n            where\n                V: Into<Value> + $value_ty,\n                I: IntoIterator<Item = V>,\n            {\n                self.0.$bind_op(v)\n            }\n        };\n        ($vis:vis $op:ident, $bind_op:ident, type $value_ty:path) => {\n            #[allow(clippy::wrong_self_convention)]\n            $vis fn $op<V, I>(&self, v: I) -> Expr\n            where\n                V: Into<$value_ty>,\n                I: IntoIterator<Item = V>,\n            {\n                self.0.$bind_op(v.into_iter().map(|v| v.into()))\n            }\n        };\n    }\n\n    macro_rules! bind_subquery_func {\n        ($vis:vis $func:ident) => {\n            #[allow(clippy::wrong_self_convention)]\n            $vis fn $func(&self, s: SelectStatement) -> Expr {\n                self.0.$func(s)\n            }\n        };\n    }\n\n    macro_rules! boilerplate {\n        ($vis:vis) => {\n            /// Get the column definition with SQL attributes\n            $vis fn def(&self) -> ColumnDef {\n                self.0.def()\n            }\n\n            /// Get the enum type name if this is a enum column\n            $vis fn enum_type_name(&self) -> Option<&'static str> {\n                self.0.enum_type_name()\n            }\n\n            /// Get the name of the entity the column belongs to\n            $vis fn entity_name(&self) -> DynIden {\n                self.0.entity_name()\n            }\n\n            /// Get the table.column reference\n            $vis fn as_column_ref(&self) -> (DynIden, DynIden) {\n                self.0.as_column_ref()\n            }\n        };\n    }\n\n    pub(super) use bind_expr_oper;\n    pub(super) use bind_oper;\n    pub(super) use bind_oper_0;\n    pub(super) use bind_oper_2;\n    pub(super) use bind_subquery_func;\n    pub(super) use bind_vec_func;\n    pub(super) use boilerplate;\n    pub(super) use impl_expr_traits;\n}\n\nuse macros::*;\n\nimpl<E: EntityTrait> BoolColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait Into<bool>);\n    bind_oper!(pub ne, ne, trait Into<bool>);\n\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait Into<bool>);\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n\nmacro_rules! impl_numeric_column {\n    ($ty:ident, $trait:ident) => {\n    impl<E: EntityTrait> $ty<E> {\n        boilerplate!(pub);\n\n        bind_oper!(pub eq, eq, trait $trait);\n        bind_oper!(pub ne, ne, trait $trait);\n        bind_oper!(pub gt, gt, trait NumericValue);\n        bind_oper!(pub gte, gte, trait NumericValue);\n        bind_oper!(pub lt, lt, trait NumericValue);\n        bind_oper!(pub lte, lte, trait NumericValue);\n\n        bind_expr_oper!(pub add, add);\n        bind_expr_oper!(pub sub, sub);\n        bind_expr_oper!(pub div, div);\n        bind_expr_oper!(pub mul, mul);\n\n        bind_oper_2!(pub between, between, trait NumericValue);\n        bind_oper_2!(pub not_between, not_between, trait NumericValue);\n\n        bind_oper_0!(pub max, max);\n        bind_oper_0!(pub min, min);\n        bind_oper_0!(pub sum, sum);\n        bind_oper_0!(pub count, count);\n        bind_oper_0!(pub is_null, is_null);\n        bind_oper_0!(pub is_not_null, is_not_null);\n\n        bind_oper!(pub if_null, if_null, trait $trait);\n\n        bind_vec_func!(pub is_in, is_in, trait $trait);\n        bind_vec_func!(pub is_not_in, is_not_in, trait $trait);\n\n        /// `= ANY(..)` operator. Postgres only.\n        #[cfg(feature = \"postgres-array\")]\n        pub fn eq_any<V, I>(&self, v: I) -> Expr\n        where\n            V: Into<Value> + $trait + sea_query::postgres_array::NotU8,\n            I: IntoIterator<Item = V>,\n        {\n            self.0.eq_any(v)\n        }\n\n        bind_subquery_func!(pub in_subquery);\n        bind_subquery_func!(pub not_in_subquery);\n    }\n};}\nimpl_numeric_column!(NumericColumn, NumericValue);\nimpl_numeric_column!(NumericColumnNullable, NumericValueNullable);\n\nmacro_rules! impl_string_column {\n    ($ty:ident, $trait:path) => {\n    impl<E: EntityTrait> $ty<E> {\n        boilerplate!(pub);\n\n        bind_oper!(pub eq, eq, trait $trait);\n        bind_oper!(pub ne, ne, trait $trait);\n        bind_oper!(pub gt, gt, trait Into<String>);\n        bind_oper!(pub gte, gte, trait Into<String>);\n        bind_oper!(pub lt, lt, trait Into<String>);\n        bind_oper!(pub lte, lte, trait Into<String>);\n\n        bind_oper_2!(pub between, between, trait Into<String>);\n        bind_oper_2!(pub not_between, not_between, trait Into<String>);\n\n        bind_oper!(pub like, like, trait Into<String>);\n        bind_oper!(pub not_like, not_like, trait Into<String>);\n        bind_oper!(pub ilike, ilike, trait Into<String>);\n        bind_oper!(pub not_ilike, not_ilike, trait Into<String>);\n        bind_oper!(pub starts_with, starts_with, trait Into<String>);\n        bind_oper!(pub ends_with, ends_with, trait Into<String>);\n        bind_oper!(pub contains, contains, trait Into<String>);\n\n        bind_oper_0!(pub count, count);\n        bind_oper_0!(pub is_null, is_null);\n        bind_oper_0!(pub is_not_null, is_not_null);\n\n        bind_oper!(pub if_null, if_null, trait $trait);\n\n        bind_vec_func!(pub is_in, is_in, trait $trait);\n        bind_vec_func!(pub is_not_in, is_not_in, trait $trait);\n\n        /// `= ANY(..)` operator. Postgres only.\n        #[cfg(feature = \"postgres-array\")]\n        pub fn eq_any<V, I>(&self, v: I) -> Expr\n        where\n            V: Into<Value> + Into<String> + sea_query::postgres_array::NotU8,\n            I: IntoIterator<Item = V>,\n        {\n            self.0.eq_any(v)\n        }\n\n        bind_subquery_func!(pub in_subquery);\n        bind_subquery_func!(pub not_in_subquery);\n    }\n};}\n\nimpl IntoOption<String> for Cow<'_, str> {\n    fn into_option(self) -> Option<String> {\n        Some(self.into())\n    }\n}\nimpl IntoOption<String> for &'_ str {\n    fn into_option(self) -> Option<String> {\n        Some(self.into())\n    }\n}\nimpl IntoOption<String> for String {\n    fn into_option(self) -> Option<String> {\n        Some(self)\n    }\n}\nimpl IntoOption<String> for Option<&'_ str> {\n    fn into_option(self) -> Option<String> {\n        self.map(Into::into)\n    }\n}\nimpl IntoOption<String> for Option<Cow<'_, str>> {\n    fn into_option(self) -> Option<String> {\n        self.map(Into::into)\n    }\n}\nimpl IntoOption<String> for Option<String> {\n    fn into_option(self) -> Option<String> {\n        self\n    }\n}\n\nimpl_string_column!(StringColumn, Into<String>);\nimpl_string_column!(StringColumnNullable, IntoOption<String>);\n\nimpl<E: EntityTrait> BytesColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait Into<Vec<u8>>);\n    bind_oper!(pub ne, ne, trait Into<Vec<u8>>);\n\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait Into<Vec<u8>>);\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/column.rs",
    "content": "use crate::{\n    ColumnDef, ColumnType, DbBackend, EntityName, Iden, IdenStatic, IntoSimpleExpr, Iterable,\n};\nuse sea_query::{\n    BinOper, DynIden, Expr, ExprTrait, IntoIden, IntoLikeExpr, SeaRc, SelectStatement, Value,\n};\nuse std::{borrow::Cow, str::FromStr};\n\nmod types;\npub use types::*;\n\npub(crate) mod macros {\n    macro_rules! bind_oper {\n        ($vis:vis $op:ident, $bin_op:ident) => {\n            #[allow(missing_docs)]\n            $vis fn $op<V>(&self, v: V) -> Expr\n            where\n                V: Into<Value>,\n            {\n                let expr = self.save_as(Expr::val(v));\n                Expr::col(self.as_column_ref()).binary(BinOper::$bin_op, expr)\n            }\n        };\n    }\n\n    macro_rules! bind_func_no_params {\n        ($vis:vis $func:ident) => {\n            /// See also SeaQuery's method with same name.\n            $vis fn $func(&self) -> Expr {\n                Expr::col(self.as_column_ref()).$func()\n            }\n        };\n    }\n\n    macro_rules! bind_vec_func {\n        ($vis:vis $func:ident) => {\n            #[allow(missing_docs)]\n            #[allow(clippy::wrong_self_convention)]\n            $vis fn $func<V, I>(&self, v: I) -> Expr\n            where\n                V: Into<Value>,\n                I: IntoIterator<Item = V>,\n            {\n                let v_with_enum_cast = v.into_iter().map(|v| self.save_as(Expr::val(v)));\n                Expr::col(self.as_column_ref()).$func(v_with_enum_cast)\n            }\n        };\n    }\n\n    macro_rules! bind_subquery_func {\n        ($vis:vis $func:ident) => {\n            #[allow(clippy::wrong_self_convention)]\n            #[allow(missing_docs)]\n            $vis fn $func(&self, s: SelectStatement) -> Expr {\n                Expr::col(self.as_column_ref()).$func(s)\n            }\n        };\n    }\n\n    macro_rules! bind_array_oper {\n        ($vis:vis $op:ident, $oper:ident) => {\n            #[cfg(feature = \"postgres-array\")]\n            /// Array operator. Postgres only.\n            $vis fn $op<V, I>(&self, v: I) -> Expr\n            where\n                V: Into<Value> + sea_query::ValueType + sea_query::postgres_array::NotU8,\n                I: IntoIterator<Item = V>,\n            {\n                use sea_query::extension::postgres::PgBinOper;\n\n                let vec: Vec<_> = v.into_iter().collect();\n                Expr::col(self.as_column_ref()).binary(PgBinOper::$oper, self.save_as(Expr::val(vec)))\n            }\n        };\n    }\n\n    pub(crate) use bind_array_oper;\n    pub(crate) use bind_func_no_params;\n    pub(crate) use bind_oper;\n    pub(crate) use bind_subquery_func;\n    pub(crate) use bind_vec_func;\n}\n\nuse macros::*;\n\n/// API for working with a `Column`. Mostly a wrapper of the identically named methods in [`sea_query::Expr`]\npub trait ColumnTrait: IdenStatic + Iterable + FromStr {\n    #[allow(missing_docs)]\n    type EntityName: EntityName;\n\n    /// Get the column definition with SQL attributes\n    fn def(&self) -> ColumnDef;\n\n    /// Get the enum type name if this is a enum column\n    fn enum_type_name(&self) -> Option<&'static str> {\n        None\n    }\n\n    /// Get the name of the entity the column belongs to\n    fn entity_name(&self) -> DynIden {\n        SeaRc::new(Self::EntityName::default())\n    }\n\n    /// Get the table.column reference\n    fn as_column_ref(&self) -> (DynIden, DynIden) {\n        (self.entity_name(), SeaRc::new(*self))\n    }\n\n    /// Perform equality against a Value. `None` will be converted to `IS NULL`.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .filter(fruit::COLUMN.cake_id.eq(2))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`cake_id` = 2\"\n    /// );\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .filter(fruit::COLUMN.cake_id.eq(Option::<i32>::None))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`cake_id` IS NULL\"\n    /// );\n    /// ```\n    fn eq<V>(&self, v: V) -> Expr\n    where\n        V: Into<Value>,\n    {\n        let v = v.into();\n        if v == v.as_null() {\n            Expr::col(self.as_column_ref()).is_null()\n        } else {\n            let expr = self.save_as(Expr::val(v));\n            Expr::col(self.as_column_ref()).eq(expr)\n        }\n    }\n\n    /// Perform inequality against a Value. `None` will be converted to `IS NOT NULL`.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .filter(fruit::COLUMN.cake_id.ne(2))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`cake_id` <> 2\"\n    /// );\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .filter(fruit::COLUMN.cake_id.ne(Option::<i32>::None))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`cake_id` IS NOT NULL\"\n    /// );\n    /// ```\n    fn ne<V>(&self, v: V) -> Expr\n    where\n        V: Into<Value>,\n    {\n        let v = v.into();\n        if v == v.as_null() {\n            Expr::col(self.as_column_ref()).is_not_null()\n        } else {\n            let expr = self.save_as(Expr::val(v));\n            Expr::col(self.as_column_ref()).ne(expr)\n        }\n    }\n\n    bind_oper!(gt, GreaterThan);\n    bind_oper!(gte, GreaterThanOrEqual);\n    bind_oper!(lt, SmallerThan);\n    bind_oper!(lte, SmallerThanOrEqual);\n\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.between(2, 3))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` BETWEEN 2 AND 3\"\n    /// );\n    /// ```\n    fn between<V>(&self, a: V, b: V) -> Expr\n    where\n        V: Into<Value>,\n    {\n        Expr::col(self.as_column_ref()).between(a, b)\n    }\n\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.not_between(2, 3))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` NOT BETWEEN 2 AND 3\"\n    /// );\n    /// ```\n    fn not_between<V>(&self, a: V, b: V) -> Expr\n    where\n        V: Into<Value>,\n    {\n        Expr::col(self.as_column_ref()).not_between(a, b)\n    }\n\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.like(\"cheese\"))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE 'cheese'\"\n    /// );\n    /// ```\n    fn like<T>(&self, s: T) -> Expr\n    where\n        T: IntoLikeExpr,\n    {\n        Expr::col(self.as_column_ref()).like(s)\n    }\n\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.not_like(\"cheese\"))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` NOT LIKE 'cheese'\"\n    /// );\n    /// ```\n    fn not_like<T>(&self, s: T) -> Expr\n    where\n        T: IntoLikeExpr,\n    {\n        Expr::col(self.as_column_ref()).not_like(s)\n    }\n\n    /// Postgres Only.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.ilike(\"cheese\"))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"name\" ILIKE 'cheese'\"#\n    /// );\n    /// ```\n    fn ilike<T>(&self, s: T) -> Expr\n    where\n        T: IntoLikeExpr,\n    {\n        use sea_query::extension::postgres::PgExpr;\n\n        Expr::col(self.as_column_ref()).ilike(s)\n    }\n\n    /// Postgres Only.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.not_ilike(\"cheese\"))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"name\" NOT ILIKE 'cheese'\"#\n    /// );\n    /// ```\n    fn not_ilike<T>(&self, s: T) -> Expr\n    where\n        T: IntoLikeExpr,\n    {\n        use sea_query::extension::postgres::PgExpr;\n\n        Expr::col(self.as_column_ref()).not_ilike(s)\n    }\n\n    /// This is a simplified shorthand for a more general `like` method.\n    /// Use `like` if you need something more complex, like specifying an escape character.\n    ///\n    /// ## Examples\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.starts_with(\"cheese\"))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE 'cheese%'\"\n    /// );\n    /// ```\n    fn starts_with<T>(&self, s: T) -> Expr\n    where\n        T: Into<String>,\n    {\n        let pattern = format!(\"{}%\", s.into());\n        Expr::col(self.as_column_ref()).like(pattern)\n    }\n\n    /// This is a simplified shorthand for a more general `like` method.\n    /// Use `like` if you need something more complex, like specifying an escape character.\n    ///\n    /// ## Examples\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.ends_with(\"cheese\"))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE '%cheese'\"\n    /// );\n    /// ```\n    fn ends_with<T>(&self, s: T) -> Expr\n    where\n        T: Into<String>,\n    {\n        let pattern = format!(\"%{}\", s.into());\n        Expr::col(self.as_column_ref()).like(pattern)\n    }\n\n    /// This is a simplified shorthand for a more general `like` method.\n    /// Use `like` if you need something more complex, like specifying an escape character.\n    ///\n    /// ## Examples\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.contains(\"cheese\"))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE '%cheese%'\"\n    /// );\n    /// ```\n    fn contains<T>(&self, s: T) -> Expr\n    where\n        T: Into<String>,\n    {\n        let pattern = format!(\"%{}%\", s.into());\n        Expr::col(self.as_column_ref()).like(pattern)\n    }\n\n    bind_func_no_params!(max);\n    bind_func_no_params!(min);\n    bind_func_no_params!(sum);\n    bind_func_no_params!(avg);\n    bind_func_no_params!(count);\n    bind_func_no_params!(is_null);\n    bind_func_no_params!(is_not_null);\n\n    /// Provide fallback value if the column is null (null coalescing)\n    fn if_null<V>(&self, v: V) -> Expr\n    where\n        V: Into<Value>,\n    {\n        Expr::col(self.as_column_ref()).if_null(v)\n    }\n\n    bind_vec_func!(is_in);\n    bind_vec_func!(is_not_in);\n\n    /// Postgres only.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// // Compare with MySQL\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.is_in(std::iter::empty::<i32>()))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE 1 = 2\"\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.is_in(vec![4, 5]))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` IN (4, 5)\"\n    /// );\n    /// // Postgres Array\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.eq_any(std::iter::empty::<i32>()))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE 1 = 2\"#\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.eq_any(vec![4, 5]))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = ANY(ARRAY [4,5])\"#\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.eq_any(&[\"Apple\".to_owned(), \"Chocolate\".to_owned()]))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"name\" = ANY(ARRAY ['Apple','Chocolate'])\"#\n    /// );\n    /// ```\n    #[cfg(feature = \"postgres-array\")]\n    fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        use sea_query::extension::postgres::PgFunc;\n\n        let values: Vec<Value> = v.into_iter().map(|v| v.into()).collect();\n\n        if let Some(first) = values.first() {\n            Expr::col(self.as_column_ref()).eq(PgFunc::any(Value::Array(\n                first.array_type(),\n                Some(Box::new(values)),\n            )))\n        } else {\n            Expr::col(self.as_column_ref()).is_in(std::iter::empty::<V>())\n        }\n    }\n\n    /// Postgres only. Opposite of `eq_any` (equivalent to `is_not_in`).\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.ne_all(std::iter::empty::<i32>()))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE 1 = 1\"#\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.ne_all(vec![4, 5]))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" <> ALL(ARRAY [4,5])\"#\n    /// );\n    /// ```\n    #[cfg(feature = \"postgres-array\")]\n    fn ne_all<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        use sea_query::extension::postgres::PgFunc;\n\n        let values: Vec<Value> = v.into_iter().map(|v| v.into()).collect();\n\n        if let Some(first) = values.first() {\n            Expr::col(self.as_column_ref()).ne(PgFunc::all(Value::Array(\n                first.array_type(),\n                Some(Box::new(values)),\n            )))\n        } else {\n            Expr::col(self.as_column_ref()).is_not_in(std::iter::empty::<V>())\n        }\n    }\n\n    bind_subquery_func!(in_subquery);\n    bind_subquery_func!(not_in_subquery);\n\n    bind_array_oper!(array_contains, Contains);\n    bind_array_oper!(array_contained, Contained);\n    bind_array_oper!(array_overlap, Overlap);\n\n    /// Construct a [`Expr::Column`] wrapped in [`Expr`].\n    fn into_expr(self) -> Expr {\n        self.into_simple_expr()\n    }\n\n    /// Construct a returning [`Expr`].\n    #[allow(clippy::match_single_binding)]\n    fn into_returning_expr(self, db_backend: DbBackend) -> Expr {\n        match db_backend {\n            _ => Expr::col(self),\n        }\n    }\n\n    /// Cast column expression used in select statement.\n    /// It only cast database enum as text if it's an enum column.\n    fn select_as(&self, expr: Expr) -> Expr {\n        self.select_enum_as(expr)\n    }\n\n    /// Cast enum column as text; do nothing if `self` is not an enum.\n    fn select_enum_as(&self, expr: Expr) -> Expr {\n        cast_enum_as(expr, &self.def(), select_enum_as)\n    }\n\n    /// Cast value of a column into the correct type for database storage.\n    /// By default, it only cast text as enum type if it's an enum column.\n    fn save_as(&self, val: Expr) -> Expr {\n        self.save_enum_as(val)\n    }\n\n    /// Cast value of an enum column as enum type; do nothing if `self` is not an enum.\n    fn save_enum_as(&self, val: Expr) -> Expr {\n        cast_enum_as(val, &self.def(), save_enum_as)\n    }\n\n    /// Get the JSON key for deserialization.\n    #[cfg(feature = \"with-json\")]\n    fn json_key(&self) -> &'static str {\n        self.as_str()\n    }\n}\n\n/// SeaORM's utility methods that act on [ColumnType]\npub trait ColumnTypeTrait {\n    /// Instantiate a new [ColumnDef]\n    fn def(self) -> ColumnDef;\n\n    /// Get the name of the enum if this is a enum column\n    fn get_enum_name(&self) -> Option<&DynIden>;\n}\n\nimpl ColumnTypeTrait for ColumnType {\n    fn def(self) -> ColumnDef {\n        ColumnDef {\n            col_type: self,\n            null: false,\n            unique: false,\n            indexed: false,\n            default: None,\n            comment: None,\n            unique_key: None,\n            renamed_from: None,\n            extra: None,\n            seaography: Default::default(),\n        }\n    }\n\n    fn get_enum_name(&self) -> Option<&DynIden> {\n        enum_name(self)\n    }\n}\n\nimpl ColumnTypeTrait for ColumnDef {\n    fn def(self) -> ColumnDef {\n        self\n    }\n\n    fn get_enum_name(&self) -> Option<&DynIden> {\n        enum_name(&self.col_type)\n    }\n}\n\nfn enum_name(col_type: &ColumnType) -> Option<&DynIden> {\n    match col_type {\n        ColumnType::Enum { name, .. } => Some(name),\n        ColumnType::Array(col_type) => enum_name(col_type),\n        _ => None,\n    }\n}\n\nstruct Text;\nstruct TextArray;\n\nimpl Iden for Text {\n    fn quoted(&self) -> Cow<'static, str> {\n        Cow::Borrowed(\"text\")\n    }\n\n    fn unquoted(&self) -> &str {\n        match self.quoted() {\n            Cow::Borrowed(s) => s,\n            _ => unreachable!(),\n        }\n    }\n}\n\nimpl Iden for TextArray {\n    fn quoted(&self) -> Cow<'static, str> {\n        // This is Postgres only and it has a special handling for quoting this\n        Cow::Borrowed(\"text[]\")\n    }\n\n    fn unquoted(&self) -> &str {\n        match self.quoted() {\n            Cow::Borrowed(s) => s,\n            _ => unreachable!(),\n        }\n    }\n}\n\npub(crate) fn select_enum_as(col: Expr, _: DynIden, col_type: &ColumnType) -> Expr {\n    let type_name = match col_type {\n        ColumnType::Array(_) => TextArray.into_iden(),\n        _ => Text.into_iden(),\n    };\n    col.as_enum(type_name)\n}\n\npub(crate) fn save_enum_as(col: Expr, enum_name: DynIden, col_type: &ColumnType) -> Expr {\n    let type_name = match col_type {\n        ColumnType::Array(_) => format!(\"{enum_name}[]\").into_iden(),\n        _ => enum_name,\n    };\n    col.as_enum(type_name)\n}\n\npub(crate) fn cast_enum_as<F>(expr: Expr, col_def: &ColumnDef, f: F) -> Expr\nwhere\n    F: Fn(Expr, DynIden, &ColumnType) -> Expr,\n{\n    let col_type = col_def.get_column_type();\n\n    match col_type {\n        #[cfg(all(feature = \"with-json\", feature = \"postgres-array\"))]\n        ColumnType::Json | ColumnType::JsonBinary => {\n            use sea_query::ArrayType;\n            use serde_json::Value as Json;\n\n            match expr {\n                Expr::Value(Value::Array(ArrayType::Json, Some(json_vec))) => {\n                    // flatten Array(Vec<Json>) into Json\n                    let json_vec: Vec<Json> = json_vec\n                        .into_iter()\n                        .filter_map(|val| match val {\n                            Value::Json(Some(json)) => Some(*json),\n                            _ => None,\n                        })\n                        .collect();\n                    Expr::Value(Value::Json(Some(Box::new(json_vec.into()))))\n                }\n                Expr::Value(Value::Array(ArrayType::Json, None)) => Expr::Value(Value::Json(None)),\n                _ => expr,\n            }\n        }\n        _ => match col_type.get_enum_name() {\n            Some(enum_name) => f(expr, enum_name.clone(), col_type),\n            None => expr,\n        },\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        ColumnTrait, Condition, DbBackend, EntityTrait, QueryFilter, QueryTrait, tests_cfg::*,\n    };\n    use sea_query::Query;\n\n    #[test]\n    fn test_in_subquery_1() {\n        assert_eq!(\n            cake::Entity::find()\n                .filter(\n                    Condition::any().add(\n                        cake::Column::Id.in_subquery(\n                            Query::select()\n                                .expr(cake::Column::Id.max())\n                                .from(cake::Entity)\n                                .to_owned()\n                        )\n                    )\n                )\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"WHERE `cake`.`id` IN (SELECT MAX(`cake`.`id`) FROM `cake`)\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn test_in_subquery_2() {\n        assert_eq!(\n            cake::Entity::find()\n                .filter(\n                    Condition::any().add(\n                        cake::Column::Id.in_subquery(\n                            Query::select()\n                                .column(cake_filling::Column::CakeId)\n                                .from(cake_filling::Entity)\n                                .to_owned()\n                        )\n                    )\n                )\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"WHERE `cake`.`id` IN (SELECT `cake_id` FROM `cake_filling`)\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn select_as_1() {\n        use crate::{ActiveModelTrait, ActiveValue, Update};\n\n        mod hello_expanded {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n            use crate::sea_query::{Expr, ExprTrait};\n\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n\n            impl EntityName for Entity {\n                fn table_name(&self) -> &'static str {\n                    \"hello\"\n                }\n            }\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n            pub struct Model {\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            pub enum Column {\n                Id,\n                One1,\n                Two,\n                Three3,\n            }\n\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        Column::Id => ColumnType::Integer.def(),\n                        Column::One1 => ColumnType::Integer.def(),\n                        Column::Two => ColumnType::Integer.def(),\n                        Column::Three3 => ColumnType::Integer.def(),\n                    }\n                }\n\n                fn select_as(&self, expr: Expr) -> Expr {\n                    match self {\n                        Self::Two => expr.cast_as(\"integer\"),\n                        _ => self.select_enum_as(expr),\n                    }\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                Id,\n            }\n\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = i32;\n\n                fn auto_increment() -> bool {\n                    true\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        #[allow(clippy::enum_variant_names)]\n        mod hello_compact {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                #[sea_orm(select_as = \"integer\")]\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        fn assert_it<E, A>(active_model: A)\n        where\n            E: EntityTrait,\n            A: ActiveModelTrait<Entity = E>,\n        {\n            assert_eq!(\n                E::find().build(DbBackend::Postgres).to_string(),\n                r#\"SELECT \"hello\".\"id\", \"hello\".\"one1\", CAST(\"hello\".\"two\" AS integer), \"hello\".\"three3\" FROM \"hello\"\"#,\n            );\n            assert_eq!(\n                Update::one(active_model)\n                    .validate()\n                    .unwrap()\n                    .build(DbBackend::Postgres)\n                    .to_string(),\n                r#\"UPDATE \"hello\" SET \"one1\" = 1, \"two\" = 2, \"three3\" = 3 WHERE \"hello\".\"id\" = 1\"#,\n            );\n        }\n\n        assert_it(hello_expanded::ActiveModel {\n            id: ActiveValue::set(1),\n            one: ActiveValue::set(1),\n            two: ActiveValue::set(2),\n            three: ActiveValue::set(3),\n        });\n        assert_it(hello_compact::ActiveModel {\n            id: ActiveValue::set(1),\n            one: ActiveValue::set(1),\n            two: ActiveValue::set(2),\n            three: ActiveValue::set(3),\n        });\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn save_as_1() {\n        use crate::{ActiveModelTrait, ActiveValue, Update};\n\n        mod hello_expanded {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n            use crate::sea_query::{Expr, ExprTrait};\n\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n\n            impl EntityName for Entity {\n                fn table_name(&self) -> &'static str {\n                    \"hello\"\n                }\n            }\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n            pub struct Model {\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            pub enum Column {\n                Id,\n                One1,\n                Two,\n                Three3,\n            }\n\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        Column::Id => ColumnType::Integer.def(),\n                        Column::One1 => ColumnType::Integer.def(),\n                        Column::Two => ColumnType::Integer.def(),\n                        Column::Three3 => ColumnType::Integer.def(),\n                    }\n                }\n\n                fn save_as(&self, val: Expr) -> Expr {\n                    match self {\n                        Self::Two => val.cast_as(\"text\"),\n                        _ => self.save_enum_as(val),\n                    }\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                Id,\n            }\n\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = i32;\n\n                fn auto_increment() -> bool {\n                    true\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        #[allow(clippy::enum_variant_names)]\n        mod hello_compact {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                #[sea_orm(save_as = \"text\")]\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        fn assert_it<E, A>(active_model: A)\n        where\n            E: EntityTrait,\n            A: ActiveModelTrait<Entity = E>,\n        {\n            assert_eq!(\n                E::find().build(DbBackend::Postgres).to_string(),\n                r#\"SELECT \"hello\".\"id\", \"hello\".\"one1\", \"hello\".\"two\", \"hello\".\"three3\" FROM \"hello\"\"#,\n            );\n            assert_eq!(\n                Update::one(active_model)\n                    .validate()\n                    .unwrap()\n                    .build(DbBackend::Postgres)\n                    .to_string(),\n                r#\"UPDATE \"hello\" SET \"one1\" = 1, \"two\" = CAST(2 AS text), \"three3\" = 3 WHERE \"hello\".\"id\" = 1\"#,\n            );\n        }\n\n        assert_it(hello_expanded::ActiveModel {\n            id: ActiveValue::set(1),\n            one: ActiveValue::set(1),\n            two: ActiveValue::set(2),\n            three: ActiveValue::set(3),\n        });\n        assert_it(hello_compact::ActiveModel {\n            id: ActiveValue::set(1),\n            one: ActiveValue::set(1),\n            two: ActiveValue::set(2),\n            three: ActiveValue::set(3),\n        });\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn select_as_and_value_1() {\n        use crate::{ActiveModelTrait, ActiveValue, Update};\n\n        mod hello_expanded {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n            use crate::sea_query::{Expr, ExprTrait};\n\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n\n            impl EntityName for Entity {\n                fn table_name(&self) -> &'static str {\n                    \"hello\"\n                }\n            }\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n            pub struct Model {\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            pub enum Column {\n                Id,\n                One1,\n                Two,\n                Three3,\n            }\n\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        Column::Id => ColumnType::Integer.def(),\n                        Column::One1 => ColumnType::Integer.def(),\n                        Column::Two => ColumnType::Integer.def(),\n                        Column::Three3 => ColumnType::Integer.def(),\n                    }\n                }\n\n                fn select_as(&self, expr: Expr) -> Expr {\n                    match self {\n                        Self::Two => expr.cast_as(\"integer\"),\n                        _ => self.select_enum_as(expr),\n                    }\n                }\n\n                fn save_as(&self, val: Expr) -> Expr {\n                    match self {\n                        Self::Two => val.cast_as(\"text\"),\n                        _ => self.save_enum_as(val),\n                    }\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                Id,\n            }\n\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = i32;\n\n                fn auto_increment() -> bool {\n                    true\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        #[allow(clippy::enum_variant_names)]\n        mod hello_compact {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                #[sea_orm(select_as = \"integer\", save_as = \"text\")]\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        fn assert_it<E, A>(active_model: A)\n        where\n            E: EntityTrait,\n            A: ActiveModelTrait<Entity = E>,\n        {\n            assert_eq!(\n                E::find().build(DbBackend::Postgres).to_string(),\n                r#\"SELECT \"hello\".\"id\", \"hello\".\"one1\", CAST(\"hello\".\"two\" AS integer), \"hello\".\"three3\" FROM \"hello\"\"#,\n            );\n            assert_eq!(\n                Update::one(active_model)\n                    .validate()\n                    .unwrap()\n                    .build(DbBackend::Postgres)\n                    .to_string(),\n                r#\"UPDATE \"hello\" SET \"one1\" = 1, \"two\" = CAST(2 AS text), \"three3\" = 3 WHERE \"hello\".\"id\" = 1\"#,\n            );\n        }\n\n        assert_it(hello_expanded::ActiveModel {\n            id: ActiveValue::set(1),\n            one: ActiveValue::set(1),\n            two: ActiveValue::set(2),\n            three: ActiveValue::set(3),\n        });\n        assert_it(hello_compact::ActiveModel {\n            id: ActiveValue::set(1),\n            one: ActiveValue::set(1),\n            two: ActiveValue::set(2),\n            three: ActiveValue::set(3),\n        });\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/column_def.rs",
    "content": "use sea_query::{SimpleExpr, Value};\n\n// The original `sea_orm::ColumnType` enum was dropped since 0.11.0\n// It was replaced by `sea_query::ColumnType`, we reexport it here to keep the `ColumnType` symbol\npub use sea_query::ColumnType;\n\n/// Defines a Column for an Entity\n#[derive(Debug, Clone, PartialEq)]\npub struct ColumnDef {\n    pub(crate) col_type: ColumnType,\n    pub(crate) null: bool,\n    pub(crate) unique: bool,\n    pub(crate) indexed: bool,\n    pub(crate) default: Option<SimpleExpr>,\n    pub(crate) comment: Option<String>,\n    pub(crate) unique_key: Option<String>,\n    pub(crate) renamed_from: Option<String>,\n    pub(crate) extra: Option<String>,\n    pub(crate) seaography: SeaographyColumnAttr,\n}\n\n/// Seaography specific attributes\n#[non_exhaustive]\n#[derive(Debug, Default, Clone, PartialEq)]\npub struct SeaographyColumnAttr {\n    /// Ignore this column in seaography\n    pub ignore: bool,\n}\n\nimpl ColumnDef {\n    /// Marks the column as `UNIQUE`\n    pub fn unique(mut self) -> Self {\n        self.unique = true;\n        self\n    }\n\n    /// Set Seaography ignore\n    pub fn seaography_ignore(mut self) -> Self {\n        self.seaography.ignore = true;\n        self\n    }\n\n    /// This column belongs to a unique key\n    pub fn unique_key(mut self, key: &str) -> Self {\n        self.unique_key = Some(key.into());\n        self\n    }\n\n    /// This column is renamed from a previous name\n    pub fn renamed_from(mut self, col: &str) -> Self {\n        self.renamed_from = Some(col.into());\n        self\n    }\n\n    /// Set column comment\n    pub fn comment(mut self, v: &str) -> Self {\n        self.comment = Some(v.into());\n        self\n    }\n\n    /// Mark the column as nullable\n    pub fn null(self) -> Self {\n        self.nullable()\n    }\n\n    /// Mark the column as nullable\n    pub fn nullable(mut self) -> Self {\n        self.null = true;\n        self\n    }\n\n    /// Set the `indexed` field  to `true`\n    pub fn indexed(mut self) -> Self {\n        self.indexed = true;\n        self\n    }\n\n    /// Set the default value\n    pub fn default_value<T>(mut self, value: T) -> Self\n    where\n        T: Into<Value>,\n    {\n        self.default = Some(value.into().into());\n        self\n    }\n\n    /// Set the default value or expression of a column\n    pub fn default<T>(mut self, default: T) -> Self\n    where\n        T: Into<SimpleExpr>,\n    {\n        self.default = Some(default.into());\n        self\n    }\n\n    /// Set the extra SQL string for the column (e.g. \"COLLATE NOCASE\")\n    pub fn extra(mut self, value: &str) -> Self {\n        self.extra = Some(value.into());\n        self\n    }\n\n    /// Get [ColumnType] as reference\n    pub fn get_column_type(&self) -> &ColumnType {\n        &self.col_type\n    }\n\n    /// Get [Option<SimpleExpr>] as reference\n    pub fn get_column_default(&self) -> Option<&SimpleExpr> {\n        self.default.as_ref()\n    }\n\n    /// Returns true if the column is nullable\n    pub fn is_null(&self) -> bool {\n        self.null\n    }\n\n    /// Returns true if the column is unique\n    pub fn is_unique(&self) -> bool {\n        self.unique\n    }\n\n    /// Get Seaography attribute\n    pub fn seaography(&self) -> &SeaographyColumnAttr {\n        &self.seaography\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::*;\n\n    #[test]\n    fn test_col_from_str() {\n        use crate::IdenStatic;\n        use std::str::FromStr;\n\n        assert!(matches!(\n            fruit::Column::from_str(\"id\"),\n            Ok(fruit::Column::Id)\n        ));\n        assert!(matches!(\n            fruit::Column::from_str(\"name\"),\n            Ok(fruit::Column::Name)\n        ));\n        assert!(matches!(\n            fruit::Column::from_str(\"cake_id\"),\n            Ok(fruit::Column::CakeId)\n        ));\n        assert!(matches!(\n            fruit::Column::from_str(\"cakeId\"),\n            Ok(fruit::Column::CakeId)\n        ));\n        assert!(matches!(\n            fruit::Column::from_str(\"CakeId\"),\n            Err(crate::ColumnFromStrErr(_))\n        ));\n        assert!(matches!(\n            fruit::Column::from_str(\"does_not_exist\"),\n            Err(crate::ColumnFromStrErr(_))\n        ));\n        assert!(matches!(fruit::Column::CakeId.as_str(), \"cake_id\"));\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn entity_model_column_1() {\n        use crate::prelude::*;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                pub one: i32,\n                #[sea_orm(unique)]\n                pub two: i8,\n                #[sea_orm(indexed)]\n                pub three: i16,\n                #[sea_orm(nullable)]\n                pub four: i32,\n                #[sea_orm(unique, indexed, nullable)]\n                pub five: i64,\n                #[sea_orm(unique)]\n                pub six: u8,\n                #[sea_orm(indexed)]\n                pub seven: u16,\n                #[sea_orm(nullable)]\n                pub eight: u32,\n                #[sea_orm(unique, indexed, nullable)]\n                pub nine: u64,\n                #[sea_orm(default_expr = \"Expr::current_timestamp()\")]\n                pub ten: DateTimeUtc,\n                #[sea_orm(default_value = 7)]\n                pub eleven: u8,\n                #[sea_orm(default_value = \"twelve_value\")]\n                pub twelve: String,\n                #[sea_orm(default_expr = \"\\\"twelve_value\\\"\")]\n                pub twelve_two: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::One.def(), ColumnType::Integer.def());\n        assert_eq!(\n            hello::Column::Two.def(),\n            ColumnType::TinyInteger.def().unique()\n        );\n        assert_eq!(\n            hello::Column::Three.def(),\n            ColumnType::SmallInteger.def().indexed()\n        );\n        assert_eq!(\n            hello::Column::Four.def(),\n            ColumnType::Integer.def().nullable()\n        );\n        assert_eq!(\n            hello::Column::Five.def(),\n            ColumnType::BigInteger.def().unique().indexed().nullable()\n        );\n        assert_eq!(\n            hello::Column::Six.def(),\n            ColumnType::TinyUnsigned.def().unique()\n        );\n        assert_eq!(\n            hello::Column::Seven.def(),\n            ColumnType::SmallUnsigned.def().indexed()\n        );\n        assert_eq!(\n            hello::Column::Eight.def(),\n            ColumnType::Unsigned.def().nullable()\n        );\n        assert_eq!(\n            hello::Column::Nine.def(),\n            ColumnType::BigUnsigned.def().unique().indexed().nullable()\n        );\n        assert_eq!(\n            hello::Column::Ten.def(),\n            ColumnType::TimestampWithTimeZone\n                .def()\n                .default(Expr::current_timestamp())\n        );\n        assert_eq!(\n            hello::Column::Eleven.def(),\n            ColumnType::TinyUnsigned.def().default(7)\n        );\n        assert_eq!(\n            hello::Column::Twelve.def(),\n            ColumnType::String(StringLen::None)\n                .def()\n                .default(\"twelve_value\")\n        );\n        assert_eq!(\n            hello::Column::TwelveTwo.def(),\n            ColumnType::String(StringLen::None)\n                .def()\n                .default(\"twelve_value\")\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_name_1() {\n        use crate::ColumnTrait;\n        use sea_query::Iden;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                #[sea_orm(column_name = \"ONE\")]\n                pub one: i32,\n                #[seaography(ignore)]\n                pub two: i32,\n                #[sea_orm(column_name = \"3\")]\n                #[seaography(ignore)]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::One.to_string().as_str(), \"ONE\");\n        assert_eq!(hello::Column::Two.to_string().as_str(), \"two\");\n        assert_eq!(hello::Column::Three.to_string().as_str(), \"3\");\n\n        assert!(!hello::Column::One.def().seaography().ignore);\n        assert!(hello::Column::Two.def().seaography().ignore);\n        assert!(hello::Column::Three.def().seaography().ignore);\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_name_2() {\n        use sea_query::Iden;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n\n            impl EntityName for Entity {\n                fn table_name(&self) -> &'static str {\n                    \"hello\"\n                }\n            }\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n            pub struct Model {\n                pub id: i32,\n                pub one: i32,\n                pub two: i32,\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            pub enum Column {\n                Id,\n                #[sea_orm(column_name = \"ONE\")]\n                One,\n                Two,\n                #[sea_orm(column_name = \"3\")]\n                Three,\n            }\n\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        Column::Id => ColumnType::Integer.def(),\n                        Column::One => ColumnType::Integer.def(),\n                        Column::Two => ColumnType::Integer.def(),\n                        Column::Three => ColumnType::Integer.def(),\n                    }\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                Id,\n            }\n\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = i32;\n\n                fn auto_increment() -> bool {\n                    true\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::One.to_string().as_str(), \"ONE\");\n        assert_eq!(hello::Column::Two.to_string().as_str(), \"two\");\n        assert_eq!(hello::Column::Three.to_string().as_str(), \"3\");\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn enum_name_1() {\n        use sea_query::Iden;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::One1.to_string().as_str(), \"one1\");\n        assert_eq!(hello::Column::Two.to_string().as_str(), \"two\");\n        assert_eq!(hello::Column::Three3.to_string().as_str(), \"three3\");\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn enum_name_2() {\n        use sea_query::Iden;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n\n            impl EntityName for Entity {\n                fn table_name(&self) -> &'static str {\n                    \"hello\"\n                }\n            }\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n            pub struct Model {\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            pub enum Column {\n                Id,\n                One1,\n                Two,\n                Three3,\n            }\n\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        Column::Id => ColumnType::Integer.def(),\n                        Column::One1 => ColumnType::Integer.def(),\n                        Column::Two => ColumnType::Integer.def(),\n                        Column::Three3 => ColumnType::Integer.def(),\n                    }\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                Id,\n            }\n\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = i32;\n\n                fn auto_increment() -> bool {\n                    true\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::One1.to_string().as_str(), \"one1\");\n        assert_eq!(hello::Column::Two.to_string().as_str(), \"two\");\n        assert_eq!(hello::Column::Three3.to_string().as_str(), \"three3\");\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_name_enum_name_1() {\n        use sea_query::Iden;\n\n        #[allow(clippy::enum_variant_names)]\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key, column_name = \"ID\", enum_name = \"IdentityColumn\")]\n                pub id: i32,\n                #[sea_orm(column_name = \"ONE\", enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(column_name = \"THREE\", enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::IdentityColumn.to_string().as_str(), \"ID\");\n        assert_eq!(hello::Column::One1.to_string().as_str(), \"ONE\");\n        assert_eq!(hello::Column::Two.to_string().as_str(), \"two\");\n        assert_eq!(hello::Column::Three3.to_string().as_str(), \"THREE\");\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_name_enum_name_2() {\n        use sea_query::Iden;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n\n            impl EntityName for Entity {\n                fn table_name(&self) -> &'static str {\n                    \"hello\"\n                }\n            }\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n            pub struct Model {\n                #[sea_orm(enum_name = \"IdentityCol\")]\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            pub enum Column {\n                #[sea_orm(column_name = \"ID\")]\n                IdentityCol,\n                #[sea_orm(column_name = \"ONE\")]\n                One1,\n                Two,\n                #[sea_orm(column_name = \"THREE\")]\n                Three3,\n            }\n\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        Column::IdentityCol => ColumnType::Integer.def(),\n                        Column::One1 => ColumnType::Integer.def(),\n                        Column::Two => ColumnType::Integer.def(),\n                        Column::Three3 => ColumnType::Integer.def(),\n                    }\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                IdentityCol,\n            }\n\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = i32;\n\n                fn auto_increment() -> bool {\n                    true\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::IdentityCol.to_string().as_str(), \"ID\");\n        assert_eq!(hello::Column::One1.to_string().as_str(), \"ONE\");\n        assert_eq!(hello::Column::Two.to_string().as_str(), \"two\");\n        assert_eq!(hello::Column::Three3.to_string().as_str(), \"THREE\");\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_name_enum_name_3() {\n        use sea_query::Iden;\n\n        mod my_entity {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"my_entity\")]\n            pub struct Model {\n                #[sea_orm(primary_key, enum_name = \"IdentityColumn\", column_name = \"id\")]\n                pub id: i32,\n                #[sea_orm(column_name = \"type\")]\n                pub type_: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(my_entity::Column::IdentityColumn.to_string().as_str(), \"id\");\n        assert_eq!(my_entity::Column::Type.to_string().as_str(), \"type\");\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_def_unique_key() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"my_entity\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(column_name = \"my_a\", unique_key = \"my_unique\")]\n            pub a: String,\n            #[sea_orm(unique_key = \"my_unique\")]\n            pub b: String,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n\n        assert_eq!(\n            Column::A.def(),\n            ColumnType::string(None).def().unique_key(\"my_unique\")\n        );\n        assert_eq!(\n            Column::B.def(),\n            ColumnType::string(None).def().unique_key(\"my_unique\")\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_def_renamed_from() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"my_entity\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(column_name = \"new_a\", renamed_from = \"old_a\")]\n            pub a: String,\n            #[sea_orm(renamed_from = \"old_b\")]\n            pub b: String,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n\n        assert_eq!(Column::A.to_string(), \"new_a\");\n        assert_eq!(Column::B.to_string(), \"b\");\n\n        assert_eq!(\n            Column::A.def(),\n            ColumnType::string(None).def().renamed_from(\"old_a\")\n        );\n        assert_eq!(\n            Column::B.def(),\n            ColumnType::string(None).def().renamed_from(\"old_b\")\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/compound/has_many.rs",
    "content": "use crate::HasManyModel;\nuse core::ops::Index;\nuse std::hash::{Hash, Hasher};\nuse std::slice;\n\nuse super::super::EntityTrait;\n\n#[derive(Debug, Default, Clone)]\npub enum HasMany<E: EntityTrait> {\n    #[default]\n    Unloaded,\n    Loaded(Vec<E::ModelEx>),\n}\n\nimpl<E> PartialEq for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq,\n{\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (HasMany::Unloaded, HasMany::Unloaded) => true,\n            (HasMany::Loaded(a), HasMany::Loaded(b)) => a == b,\n            _ => false,\n        }\n    }\n}\n\nimpl<E> Eq for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: Eq,\n{\n}\n\nimpl<E: EntityTrait> HasMany<E> {\n    /// Return true if variant is `Loaded`\n    pub fn is_loaded(&self) -> bool {\n        matches!(self, HasMany::Loaded(_))\n    }\n\n    /// Return true if variant is `Unloaded`\n    pub fn is_unloaded(&self) -> bool {\n        matches!(self, HasMany::Unloaded)\n    }\n\n    /// Return true if variant is `Unloaded` or underlying vector is empty\n    pub fn is_empty(&self) -> bool {\n        match self {\n            HasMany::Unloaded => true,\n            HasMany::Loaded(models) => models.is_empty(),\n        }\n    }\n\n    /// Like `Vec::get`\n    pub fn get(&self, index: usize) -> Option<&E::ModelEx> {\n        match self {\n            HasMany::Loaded(models) => models.get(index),\n            HasMany::Unloaded => None,\n        }\n    }\n\n    /// Length of underlying vector\n    pub fn len(&self) -> usize {\n        match self {\n            HasMany::Loaded(models) => models.len(),\n            HasMany::Unloaded => 0,\n        }\n    }\n}\n\nimpl<E> HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: From<E::ModelEx>,\n{\n    pub fn into_active_model(self) -> HasManyModel<E> {\n        match self {\n            HasMany::Loaded(models) => {\n                HasManyModel::Append(models.into_iter().map(Into::into).collect())\n            }\n            HasMany::Unloaded => HasManyModel::NotSet,\n        }\n    }\n}\n\nimpl<E: EntityTrait> From<HasMany<E>> for Option<Vec<E::ModelEx>> {\n    fn from(value: HasMany<E>) -> Self {\n        match value {\n            HasMany::Loaded(models) => Some(models),\n            HasMany::Unloaded => None,\n        }\n    }\n}\n\nimpl<E: EntityTrait> Index<usize> for HasMany<E> {\n    type Output = E::ModelEx;\n\n    fn index(&self, index: usize) -> &Self::Output {\n        match self {\n            HasMany::Unloaded => {\n                panic!(\"index out of bounds: the HasMany is Unloaded (index: {index})\")\n            }\n            HasMany::Loaded(items) => items.index(index),\n        }\n    }\n}\n\nimpl<E: EntityTrait> IntoIterator for HasMany<E> {\n    type Item = E::ModelEx;\n    type IntoIter = std::vec::IntoIter<E::ModelEx>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        match self {\n            HasMany::Loaded(models) => models.into_iter(),\n            HasMany::Unloaded => Vec::new().into_iter(),\n        }\n    }\n}\n\nimpl<E: EntityTrait> From<Vec<E::ModelEx>> for HasMany<E> {\n    fn from(value: Vec<E::ModelEx>) -> Self {\n        HasMany::Loaded(value)\n    }\n}\n\nimpl<E, const N: usize> PartialEq<[<E as EntityTrait>::Model; N]> for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq<<E as EntityTrait>::Model>,\n    <E as EntityTrait>::Model: PartialEq<E::ModelEx>,\n{\n    fn eq(&self, other: &[<E as EntityTrait>::Model; N]) -> bool {\n        match self {\n            HasMany::Loaded(models) => models.as_slice() == other.as_slice(),\n            HasMany::Unloaded => false,\n        }\n    }\n}\n\nimpl<E, const N: usize> PartialEq<HasMany<E>> for [<E as EntityTrait>::Model; N]\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq<<E as EntityTrait>::Model>,\n    <E as EntityTrait>::Model: PartialEq<E::ModelEx>,\n{\n    fn eq(&self, other: &HasMany<E>) -> bool {\n        other == self\n    }\n}\n\nimpl<E> PartialEq<[<E as EntityTrait>::Model]> for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq<<E as EntityTrait>::Model>,\n    <E as EntityTrait>::Model: PartialEq<E::ModelEx>,\n{\n    fn eq(&self, other: &[<E as EntityTrait>::Model]) -> bool {\n        match self {\n            HasMany::Loaded(models) => models.as_slice() == other,\n            HasMany::Unloaded => false,\n        }\n    }\n}\n\nimpl<E> PartialEq<HasMany<E>> for [<E as EntityTrait>::Model]\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq<<E as EntityTrait>::Model>,\n    <E as EntityTrait>::Model: PartialEq<E::ModelEx>,\n{\n    fn eq(&self, other: &HasMany<E>) -> bool {\n        other == self\n    }\n}\n\n#[derive(Debug, Clone)]\npub struct Iter<'a, E: EntityTrait> {\n    inner: Option<slice::Iter<'a, E::ModelEx>>,\n}\n\nimpl<E: EntityTrait> HasMany<E> {\n    pub fn iter(&self) -> Iter<'_, E> {\n        Iter {\n            inner: match self {\n                HasMany::Loaded(models) => Some(models.iter()),\n                HasMany::Unloaded => None,\n            },\n        }\n    }\n}\n\nimpl<'a, E: EntityTrait> Iterator for Iter<'a, E> {\n    type Item = &'a E::ModelEx;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.inner.as_mut().and_then(|iter| iter.next())\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.inner\n            .as_ref()\n            .map(|iter| iter.size_hint())\n            .unwrap_or((0, Some(0)))\n    }\n\n    fn count(self) -> usize\n    where\n        Self: Sized,\n    {\n        self.inner.map(|iter| iter.count()).unwrap_or(0)\n    }\n\n    fn last(self) -> Option<Self::Item>\n    where\n        Self: Sized,\n    {\n        self.inner.and_then(|iter| iter.last())\n    }\n}\n\nimpl<'a, E: EntityTrait> ExactSizeIterator for Iter<'a, E> {\n    fn len(&self) -> usize {\n        self.inner.as_ref().map(|iter| iter.len()).unwrap_or(0)\n    }\n}\n\nimpl<'a, E: EntityTrait> DoubleEndedIterator for Iter<'a, E> {\n    fn next_back(&mut self) -> Option<Self::Item> {\n        self.inner.as_mut().and_then(|iter| iter.next_back())\n    }\n}\n\nimpl<'a, E: EntityTrait> IntoIterator for &'a HasMany<E> {\n    type Item = &'a E::ModelEx;\n    type IntoIter = Iter<'a, E>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        Iter {\n            inner: match self {\n                HasMany::Loaded(models) => Some(models.iter()),\n                HasMany::Unloaded => None,\n            },\n        }\n    }\n}\n\nimpl<E> Hash for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: Hash,\n{\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        std::mem::discriminant(self).hash(state);\n        match self {\n            HasMany::Loaded(model) => model.hash(state),\n            HasMany::Unloaded => {}\n        }\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl<E> serde::Serialize for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: serde::Serialize,\n{\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        match self {\n            HasMany::Unloaded => None,\n            HasMany::Loaded(models) => Some(models.as_slice()),\n        }\n        .serialize(serializer)\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl<'de, E> serde::Deserialize<'de> for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: serde::Deserialize<'de>,\n{\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        match <Option<Vec<E::ModelEx>>>::deserialize(deserializer)? {\n            Some(models) => Ok(HasMany::Loaded(models)),\n            None => Ok(HasMany::Unloaded),\n        }\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use crate::compound::{HasMany, HasOne};\n    use crate::tests_cfg::{cake, filling, fruit};\n\n    #[test]\n    fn test_serde_compound() {\n        let cake = cake::ModelEx {\n            id: 1,\n            name: \"A\".into(),\n            fruit: Default::default(),\n            fillings: Default::default(),\n        };\n\n        assert_eq!(\n            filling::Model {\n                id: 2,\n                name: \"C\".into(),\n                vendor_id: None,\n                ignored_attr: 3,\n            }\n            .into_ex(),\n            filling::ModelEx {\n                id: 2,\n                name: \"C\".into(),\n                vendor_id: None,\n                ignored_attr: 3,\n                ingredients: HasMany::Unloaded,\n            }\n        );\n\n        assert_eq!(\n            serde_json::to_string(&cake).unwrap(),\n            r#\"{\"id\":1,\"name\":\"A\",\"fruit\":null,\"fillings\":null}\"#\n        );\n        assert_eq!(\n            serde_json::from_str::<cake::ModelEx>(&serde_json::to_string(&cake).unwrap()).unwrap(),\n            cake\n        );\n\n        let cake = cake::ModelEx {\n            id: 1,\n            name: \"A\".into(),\n            fruit: Default::default(),\n            fillings: HasMany::Loaded(vec![]),\n        };\n\n        assert_eq!(\n            serde_json::to_string(&cake).unwrap(),\n            r#\"{\"id\":1,\"name\":\"A\",\"fruit\":null,\"fillings\":[]}\"#\n        );\n        assert_eq!(\n            serde_json::from_str::<cake::ModelEx>(&serde_json::to_string(&cake).unwrap()).unwrap(),\n            cake\n        );\n\n        let mut cake = cake::ModelEx {\n            id: 1,\n            name: \"A\".into(),\n            fruit: HasOne::Loaded(\n                fruit::ModelEx {\n                    id: 2,\n                    name: \"B\".into(),\n                    cake_id: None,\n                }\n                .into(),\n            ),\n            fillings: HasMany::Unloaded,\n        };\n\n        assert_eq!(\n            serde_json::to_string(&cake).unwrap(),\n            r#\"{\"id\":1,\"name\":\"A\",\"fruit\":{\"id\":2,\"name\":\"B\",\"cake_id\":null},\"fillings\":null}\"#\n        );\n        // fruit has skip_deserializing on id\n        cake.fruit.as_mut().unwrap().id = 0;\n        assert_eq!(\n            serde_json::from_str::<cake::ModelEx>(&serde_json::to_string(&cake).unwrap()).unwrap(),\n            cake\n        );\n\n        let cake = cake::ModelEx {\n            id: 1,\n            name: \"A\".into(),\n            fruit: HasOne::Loaded(\n                fruit::ModelEx {\n                    id: 0,\n                    name: \"B\".into(),\n                    cake_id: None,\n                }\n                .into(),\n            ),\n            fillings: HasMany::Loaded(vec![\n                filling::Model {\n                    id: 2,\n                    name: \"C\".into(),\n                    vendor_id: None,\n                    ignored_attr: 3,\n                }\n                .into_ex(),\n            ]),\n        };\n\n        assert_eq!(\n            serde_json::to_string(&cake).unwrap(),\n            r#\"{\"id\":1,\"name\":\"A\",\"fruit\":{\"id\":0,\"name\":\"B\",\"cake_id\":null},\"fillings\":[{\"id\":2,\"name\":\"C\",\"vendor_id\":null,\"ignored_attr\":3,\"ingredients\":null}]}\"#\n        );\n        assert_eq!(\n            serde_json::from_str::<cake::ModelEx>(&serde_json::to_string(&cake).unwrap()).unwrap(),\n            cake\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/compound/has_one.rs",
    "content": "use crate::{EntityTrait, HasOneModel};\nuse std::hash::{Hash, Hasher};\n\n#[derive(Debug, Default, Clone)]\npub enum HasOne<E: EntityTrait> {\n    #[default]\n    Unloaded,\n    NotFound,\n    Loaded(Box<E::ModelEx>),\n}\n\nimpl<E: EntityTrait> HasOne<E> {\n    /// Construct a `HasOne::Loaded` value\n    pub fn loaded<M: Into<E::ModelEx>>(model: M) -> Self {\n        Self::Loaded(Box::new(model.into()))\n    }\n\n    /// Return true if variant is `Unloaded`\n    pub fn is_unloaded(&self) -> bool {\n        matches!(self, HasOne::Unloaded)\n    }\n\n    /// Return true if variant is `NotFound`\n    pub fn is_not_found(&self) -> bool {\n        matches!(self, HasOne::NotFound)\n    }\n\n    /// Return true if variant is `Loaded`\n    pub fn is_loaded(&self) -> bool {\n        matches!(self, HasOne::Loaded(_))\n    }\n\n    /// True if variant is `Unloaded` or `NotFound`\n    pub fn is_none(&self) -> bool {\n        matches!(self, HasOne::Unloaded | HasOne::NotFound)\n    }\n\n    /// Get a reference, if loaded\n    pub fn as_ref(&self) -> Option<&E::ModelEx> {\n        match self {\n            HasOne::Loaded(model) => Some(model.as_ref()),\n            HasOne::Unloaded | HasOne::NotFound => None,\n        }\n    }\n\n    /// Get a mutable reference, if loaded\n    pub fn as_mut(&mut self) -> Option<&mut E::ModelEx> {\n        match self {\n            HasOne::Loaded(model) => Some(model),\n            HasOne::Unloaded | HasOne::NotFound => None,\n        }\n    }\n\n    /// Convert into an `Option<ModelEx>`\n    pub fn into_option(self) -> Option<E::ModelEx> {\n        match self {\n            HasOne::Loaded(model) => Some(*model),\n            HasOne::Unloaded | HasOne::NotFound => None,\n        }\n    }\n\n    /// Take ownership of the contained Model, leaving `Unloaded` in place.\n    pub fn take(&mut self) -> Option<E::ModelEx> {\n        std::mem::take(self).into_option()\n    }\n\n    /// # Panics\n    ///\n    /// Panics if called on `Unloaded` or `NotFound` values.\n    pub fn unwrap(self) -> E::ModelEx {\n        match self {\n            HasOne::Loaded(model) => *model,\n            HasOne::Unloaded => panic!(\"called `HasOne::unwrap()` on an `Unloaded` value\"),\n            HasOne::NotFound => panic!(\"called `HasOne::unwrap()` on a `NotFound` value\"),\n        }\n    }\n}\n\nimpl<E> HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: From<E::ModelEx>,\n{\n    pub fn into_active_model(self) -> HasOneModel<E> {\n        match self {\n            HasOne::Loaded(_) => {\n                let model = self.unwrap();\n                let active_model: E::ActiveModelEx = model.into();\n                HasOneModel::Set(active_model.into())\n            }\n            HasOne::Unloaded => HasOneModel::NotSet,\n            HasOne::NotFound => HasOneModel::NotSet,\n        }\n    }\n}\n\nimpl<E> PartialEq for HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq,\n{\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (HasOne::Unloaded, HasOne::Unloaded) => true,\n            (HasOne::NotFound, HasOne::NotFound) => true,\n            (HasOne::Loaded(a), HasOne::Loaded(b)) => a == b,\n            _ => false,\n        }\n    }\n}\n\nimpl<E> Eq for HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: Eq,\n{\n}\n\n// Option<Box<ModelEx<E>>> <-> HasOne<E> conversions and comparisons\nimpl<E: EntityTrait> From<HasOne<E>> for Option<Box<E::ModelEx>> {\n    fn from(value: HasOne<E>) -> Self {\n        match value {\n            HasOne::Loaded(model) => Some(model),\n            HasOne::Unloaded | HasOne::NotFound => None,\n        }\n    }\n}\n\nimpl<E: EntityTrait> From<Option<Box<E::ModelEx>>> for HasOne<E> {\n    fn from(value: Option<Box<E::ModelEx>>) -> Self {\n        match value {\n            Some(model) => HasOne::Loaded(model),\n            None => HasOne::NotFound,\n        }\n    }\n}\n\nimpl<E> PartialEq<Option<Box<E::ModelEx>>> for HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq,\n{\n    fn eq(&self, other: &Option<Box<E::ModelEx>>) -> bool {\n        match (self, other) {\n            (HasOne::Loaded(a), Some(b)) => a.as_ref() == b.as_ref(),\n            (HasOne::Unloaded | HasOne::NotFound, None) => true,\n            _ => false,\n        }\n    }\n}\n\nimpl<E> PartialEq<HasOne<E>> for Option<Box<E::ModelEx>>\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq,\n{\n    fn eq(&self, other: &HasOne<E>) -> bool {\n        other == self\n    }\n}\n\nimpl<E> Hash for HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: Hash,\n{\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        std::mem::discriminant(self).hash(state);\n        match self {\n            Self::Loaded(model) => model.hash(state),\n            Self::Unloaded => {}\n            Self::NotFound => {}\n        }\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl<E> serde::Serialize for HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: serde::Serialize,\n{\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        match self {\n            HasOne::Unloaded => None,\n            HasOne::NotFound => None,\n            HasOne::Loaded(model) => Some(model),\n        }\n        .serialize(serializer)\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl<'de, E> serde::Deserialize<'de> for HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: serde::Deserialize<'de>,\n{\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        match <Option<E::ModelEx>>::deserialize(deserializer)? {\n            Some(model) => Ok(HasOne::Loaded(Box::new(model))),\n            None => Ok(HasOne::Unloaded),\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/compound.rs",
    "content": "#![allow(missing_docs)]\nuse super::{ColumnTrait, EntityTrait, PrimaryKeyToColumn, PrimaryKeyTrait};\nuse crate::{\n    ConnectionTrait, DbErr, IntoSimpleExpr, ItemsAndPagesNumber, Iterable, ModelTrait, QueryFilter,\n    QueryOrder,\n};\nuse sea_query::{IntoValueTuple, Order, TableRef};\nuse std::marker::PhantomData;\n\nmod has_many;\nmod has_one;\n\npub use has_many::{HasMany, Iter as HasManyIter};\npub use has_one::HasOne;\n\npub trait EntityLoaderTrait<E: EntityTrait>: QueryFilter + QueryOrder + Clone {\n    /// The return type of this loader\n    type ModelEx: ModelTrait<Entity = E>;\n\n    /// Find a model by primary key\n    fn filter_by_id<T>(mut self, values: T) -> Self\n    where\n        T: Into<<E::PrimaryKey as PrimaryKeyTrait>::ValueType>,\n    {\n        let mut keys = E::PrimaryKey::iter();\n        for v in values.into().into_value_tuple() {\n            if let Some(key) = keys.next() {\n                let col = key.into_column();\n                self.filter_mut(col.eq(v));\n            } else {\n                unreachable!(\"primary key arity mismatch\");\n            }\n        }\n        self\n    }\n\n    /// Apply order by primary key to the query statement\n    fn order_by_id_asc(self) -> Self {\n        self.order_by_id(Order::Asc)\n    }\n\n    /// Apply order by primary key to the query statement\n    fn order_by_id_desc(self) -> Self {\n        self.order_by_id(Order::Desc)\n    }\n\n    /// Apply order by primary key to the query statement\n    fn order_by_id(mut self, order: Order) -> Self {\n        for key in E::PrimaryKey::iter() {\n            let col = key.into_column();\n            <Self as QueryOrder>::query(&mut self)\n                .order_by_expr(col.into_simple_expr(), order.clone());\n        }\n        self\n    }\n\n    /// Paginate query.\n    fn paginate<'db, C: ConnectionTrait>(\n        self,\n        db: &'db C,\n        page_size: u64,\n    ) -> EntityLoaderPaginator<'db, C, E, Self> {\n        EntityLoaderPaginator {\n            loader: self,\n            page: 0,\n            page_size,\n            db,\n            phantom: PhantomData,\n        }\n    }\n\n    #[doc(hidden)]\n    fn fetch<C: ConnectionTrait>(\n        self,\n        db: &C,\n        page: u64,\n        page_size: u64,\n    ) -> Result<Vec<Self::ModelEx>, DbErr>;\n\n    #[doc(hidden)]\n    fn num_items<C: ConnectionTrait>(self, db: &C, page_size: u64) -> Result<u64, DbErr>;\n}\n\n#[derive(Debug)]\npub struct EntityLoaderPaginator<'db, C, E, L>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait,\n    L: EntityLoaderTrait<E>,\n{\n    pub(crate) loader: L,\n    pub(crate) page: u64,\n    pub(crate) page_size: u64,\n    pub(crate) db: &'db C,\n    pub(crate) phantom: PhantomData<E>,\n}\n\n/// Just a marker trait on EntityReverse\npub trait EntityReverse {\n    type Entity: EntityTrait;\n}\n\n/// Subject to change, not yet stable\n#[derive(Debug, Copy, Clone, PartialEq)]\npub struct EntityLoaderWithSelf<R: EntityTrait, S: EntityTrait>(pub R, pub S);\n\n/// Subject to change, not yet stable\n#[derive(Debug, Copy, Clone, PartialEq)]\npub struct EntityLoaderWithSelfRev<R: EntityTrait, S: EntityReverse>(pub R, pub S);\n\n#[derive(Debug, Clone, PartialEq)]\npub enum LoadTarget {\n    TableRef(TableRef),\n    TableRefRev(TableRef),\n    Relation(String),\n}\n\nimpl<'db, C, E, L> EntityLoaderPaginator<'db, C, E, L>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait,\n    L: EntityLoaderTrait<E>,\n{\n    /// Fetch a specific page; page index starts from zero\n    pub fn fetch_page(&self, page: u64) -> Result<Vec<L::ModelEx>, DbErr> {\n        self.loader.clone().fetch(self.db, page, self.page_size)\n    }\n\n    /// Fetch the current page\n    pub fn fetch(&self) -> Result<Vec<L::ModelEx>, DbErr> {\n        self.fetch_page(self.page)\n    }\n\n    /// Get the total number of items\n    pub fn num_items(&self) -> Result<u64, DbErr> {\n        self.loader.clone().num_items(self.db, self.page_size)\n    }\n\n    /// Get the total number of pages\n    pub fn num_pages(&self) -> Result<u64, DbErr> {\n        let num_items = self.num_items()?;\n        let num_pages = self.compute_pages_number(num_items);\n        Ok(num_pages)\n    }\n\n    /// Get the total number of items and pages\n    pub fn num_items_and_pages(&self) -> Result<ItemsAndPagesNumber, DbErr> {\n        let number_of_items = self.num_items()?;\n        let number_of_pages = self.compute_pages_number(number_of_items);\n\n        Ok(ItemsAndPagesNumber {\n            number_of_items,\n            number_of_pages,\n        })\n    }\n\n    /// Compute the number of pages for the current page\n    fn compute_pages_number(&self, num_items: u64) -> u64 {\n        (num_items / self.page_size) + (num_items % self.page_size > 0) as u64\n    }\n\n    /// Increment the page counter\n    pub fn next(&mut self) {\n        self.page += 1;\n    }\n\n    /// Get current page number\n    pub fn cur_page(&self) -> u64 {\n        self.page\n    }\n\n    /// Fetch one page and increment the page counter\n    pub fn fetch_and_next(&mut self) -> Result<Option<Vec<L::ModelEx>>, DbErr> {\n        let vec = self.fetch()?;\n        self.next();\n        let opt = if !vec.is_empty() { Some(vec) } else { None };\n        Ok(opt)\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use crate::ModelTrait;\n    use crate::tests_cfg::cake;\n\n    #[test]\n    fn test_model_ex_convert() {\n        let cake = cake::Model {\n            id: 12,\n            name: \"hello\".into(),\n        };\n        let cake_ex: cake::ModelEx = cake.clone().into();\n\n        assert_eq!(cake, cake_ex);\n        assert_eq!(cake_ex, cake);\n        assert_eq!(cake.id, cake_ex.id);\n        assert_eq!(cake.name, cake_ex.name);\n\n        assert_eq!(cake_ex.get(cake::Column::Id), 12i32.into());\n        assert_eq!(cake_ex.get(cake::Column::Name), \"hello\".into());\n\n        assert_eq!(cake::Model::from(cake_ex), cake);\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/identity.rs",
    "content": "use crate::{ColumnTrait, EntityTrait, IdenStatic};\nuse sea_query::{Alias, DynIden, Iden, IntoIden, SeaRc};\nuse std::{borrow::Cow, fmt::Write};\n\n/// List of column identifier\n#[derive(Debug, Clone, PartialEq, Eq, Hash)]\npub enum Identity {\n    /// Column identifier consists of 1 column\n    Unary(DynIden),\n    /// Column identifier consists of 2 columns\n    Binary(DynIden, DynIden),\n    /// Column identifier consists of 3 columns\n    Ternary(DynIden, DynIden, DynIden),\n    /// Column identifier consists of more than 3 columns\n    Many(Vec<DynIden>),\n}\n\nimpl Identity {\n    /// Get arity for this value\n    pub fn arity(&self) -> usize {\n        match self {\n            Self::Unary(_) => 1,\n            Self::Binary(_, _) => 2,\n            Self::Ternary(_, _, _) => 3,\n            Self::Many(vec) => vec.len(),\n        }\n    }\n\n    /// Iterate components of Identity\n    pub fn iter(&self) -> BorrowedIdentityIter<'_> {\n        BorrowedIdentityIter {\n            identity: self,\n            index: 0,\n        }\n    }\n\n    /// Check if this identity contains a component column\n    pub fn contains(&self, col: &DynIden) -> bool {\n        self.iter().any(|c| c == col)\n    }\n\n    /// Check if this identity is a superset of another identity\n    pub fn fully_contains(&self, other: &Identity) -> bool {\n        for col in other.iter() {\n            if !self.contains(col) {\n                return false;\n            }\n        }\n        true\n    }\n}\n\nimpl IntoIterator for Identity {\n    type Item = DynIden;\n    type IntoIter = OwnedIdentityIter;\n\n    fn into_iter(self) -> Self::IntoIter {\n        OwnedIdentityIter {\n            identity: self,\n            index: 0,\n        }\n    }\n}\n\nimpl Iden for Identity {\n    fn quoted(&self) -> Cow<'static, str> {\n        match self {\n            Identity::Unary(iden) => iden.inner(),\n            Identity::Binary(iden1, iden2) => Cow::Owned(format!(\"{iden1}{iden2}\")),\n            Identity::Ternary(iden1, iden2, iden3) => Cow::Owned(format!(\"{iden1}{iden2}{iden3}\")),\n            Identity::Many(vec) => {\n                let mut s = String::new();\n                for iden in vec.iter() {\n                    write!(&mut s, \"{iden}\").expect(\"Infallible\");\n                }\n                Cow::Owned(s)\n            }\n        }\n    }\n\n    fn to_string(&self) -> String {\n        match self.quoted() {\n            Cow::Borrowed(s) => s.to_owned(),\n            Cow::Owned(s) => s,\n        }\n    }\n\n    fn unquoted(&self) -> &str {\n        panic!(\"Should not call this\")\n    }\n}\n\n/// Iterator for [`Identity`]\n#[derive(Debug)]\npub struct BorrowedIdentityIter<'a> {\n    identity: &'a Identity,\n    index: usize,\n}\n\n/// Iterator for [`Identity`]\n#[derive(Debug)]\npub struct OwnedIdentityIter {\n    identity: Identity,\n    index: usize,\n}\n\nimpl<'a> Iterator for BorrowedIdentityIter<'a> {\n    type Item = &'a DynIden;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let result = match self.identity {\n            Identity::Unary(iden1) => {\n                if self.index == 0 {\n                    Some(iden1)\n                } else {\n                    None\n                }\n            }\n            Identity::Binary(iden1, iden2) => match self.index {\n                0 => Some(iden1),\n                1 => Some(iden2),\n                _ => None,\n            },\n            Identity::Ternary(iden1, iden2, iden3) => match self.index {\n                0 => Some(iden1),\n                1 => Some(iden2),\n                2 => Some(iden3),\n                _ => None,\n            },\n            Identity::Many(vec) => vec.get(self.index),\n        };\n        self.index += 1;\n        result\n    }\n}\n\nimpl Iterator for OwnedIdentityIter {\n    type Item = DynIden;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let result = match &self.identity {\n            Identity::Unary(iden1) => {\n                if self.index == 0 {\n                    Some(iden1.clone())\n                } else {\n                    None\n                }\n            }\n            Identity::Binary(iden1, iden2) => match self.index {\n                0 => Some(iden1.clone()),\n                1 => Some(iden2.clone()),\n                _ => None,\n            },\n            Identity::Ternary(iden1, iden2, iden3) => match self.index {\n                0 => Some(iden1.clone()),\n                1 => Some(iden2.clone()),\n                2 => Some(iden3.clone()),\n                _ => None,\n            },\n            Identity::Many(vec) => vec.get(self.index).cloned(),\n        };\n        self.index += 1;\n        result\n    }\n}\n\n/// Performs a conversion into an [Identity]\npub trait IntoIdentity {\n    /// Method to perform the conversion\n    fn into_identity(self) -> Identity;\n}\n\n/// Check the [Identity] of an Entity\npub trait IdentityOf<E>\nwhere\n    E: EntityTrait,\n{\n    /// Method to call to perform this check\n    fn identity_of(self) -> Identity;\n}\n\nimpl IntoIdentity for Identity {\n    fn into_identity(self) -> Identity {\n        self\n    }\n}\n\nimpl IntoIdentity for String {\n    fn into_identity(self) -> Identity {\n        self.as_str().into_identity()\n    }\n}\n\nimpl IntoIdentity for &str {\n    fn into_identity(self) -> Identity {\n        Identity::Unary(SeaRc::new(Alias::new(self)))\n    }\n}\n\nimpl<T> IntoIdentity for T\nwhere\n    T: IdenStatic,\n{\n    fn into_identity(self) -> Identity {\n        Identity::Unary(self.into_iden())\n    }\n}\n\nimpl<T, C> IntoIdentity for (T, C)\nwhere\n    T: IdenStatic,\n    C: IdenStatic,\n{\n    fn into_identity(self) -> Identity {\n        Identity::Binary(self.0.into_iden(), self.1.into_iden())\n    }\n}\n\nimpl<T, C, R> IntoIdentity for (T, C, R)\nwhere\n    T: IdenStatic,\n    C: IdenStatic,\n    R: IdenStatic,\n{\n    fn into_identity(self) -> Identity {\n        Identity::Ternary(self.0.into_iden(), self.1.into_iden(), self.2.into_iden())\n    }\n}\n\nmacro_rules! impl_into_identity {\n    ( $($T:ident : $N:tt),+ $(,)? ) => {\n        impl< $($T),+ > IntoIdentity for ( $($T),+ )\n        where\n            $($T: IdenStatic),+\n        {\n            fn into_identity(self) -> Identity {\n                Identity::Many(vec![\n                    $(self.$N.into_iden()),+\n                ])\n            }\n        }\n    };\n}\n\n#[rustfmt::skip]\nmod impl_into_identity {\n    use super::*;\n\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9, T10:10);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9, T10:10, T11:11);\n}\n\nimpl<E, C> IdentityOf<E> for C\nwhere\n    E: EntityTrait<Column = C>,\n    C: ColumnTrait,\n{\n    fn identity_of(self) -> Identity {\n        self.into_identity()\n    }\n}\n\nmacro_rules! impl_identity_of {\n    ( $($T:ident),+ $(,)? ) => {\n        impl<E, C> IdentityOf<E> for ( $($T),+ )\n        where\n            E: EntityTrait<Column = C>,\n            C: ColumnTrait,\n        {\n            fn identity_of(self) -> Identity {\n                self.into_identity()\n            }\n        }\n    };\n}\n\n#[rustfmt::skip]\nmod impl_identity_of {\n    use super::*;\n\n    impl_identity_of!(C, C);\n    impl_identity_of!(C, C, C);\n    impl_identity_of!(C, C, C, C);\n    impl_identity_of!(C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C, C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C, C, C, C, C, C, C);\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn test_identity_contains() {\n        let abc = Identity::Ternary(\"a\".into(), \"b\".into(), \"c\".into());\n        let a = Identity::Unary(\"a\".into());\n        let ab = Identity::Binary(\"a\".into(), \"b\".into());\n        let bc = Identity::Binary(\"b\".into(), \"c\".into());\n        let d = Identity::Unary(\"d\".into());\n        let bcd = Identity::Ternary(\"b\".into(), \"c\".into(), \"d\".into());\n\n        assert!(abc.contains(&\"a\".into()));\n        assert!(abc.contains(&\"b\".into()));\n        assert!(abc.contains(&\"c\".into()));\n        assert!(!abc.contains(&\"d\".into()));\n\n        assert!(abc.fully_contains(&a));\n        assert!(abc.fully_contains(&ab));\n        assert!(abc.fully_contains(&bc));\n        assert!(!abc.fully_contains(&d));\n        assert!(!abc.fully_contains(&bcd));\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/link.rs",
    "content": "use crate::{EntityTrait, QuerySelect, RelationDef, Select, join_tbl_on_condition};\nuse sea_query::{\n    Alias, CommonTableExpression, Condition, IntoIden, IntoTableRef, JoinType, UnionType,\n};\n\n/// Same as [RelationDef]\npub type LinkDef = RelationDef;\n\n/// A Trait for links between Entities\npub trait Linked {\n    #[allow(missing_docs)]\n    type FromEntity: EntityTrait;\n\n    #[allow(missing_docs)]\n    type ToEntity: EntityTrait;\n\n    /// Link for an Entity\n    fn link(&self) -> Vec<LinkDef>;\n\n    /// Find all the Entities that are linked to the Entity\n    fn find_linked(&self) -> Select<Self::ToEntity> {\n        find_linked(self.link().into_iter().rev(), JoinType::InnerJoin)\n    }\n}\n\npub(crate) fn find_linked<I, E>(links: I, join: JoinType) -> Select<E>\nwhere\n    I: Iterator<Item = LinkDef>,\n    E: EntityTrait,\n{\n    let mut select = Select::new();\n    for (i, mut rel) in links.enumerate() {\n        let from_tbl = format!(\"r{i}\").into_iden();\n        let to_tbl = if i > 0 {\n            format!(\"r{}\", i - 1).into_iden()\n        } else {\n            rel.to_tbl.sea_orm_table().clone()\n        };\n        let table_ref = rel.from_tbl;\n\n        let mut condition = Condition::all().add(join_tbl_on_condition(\n            from_tbl.clone(),\n            to_tbl.clone(),\n            rel.from_col,\n            rel.to_col,\n        ));\n        if let Some(f) = rel.on_condition.take() {\n            condition = condition.add(f(from_tbl.clone(), to_tbl.clone()));\n        }\n\n        select.query().join_as(join, table_ref, from_tbl, condition);\n    }\n    select\n}\n\npub(crate) fn find_linked_recursive<E>(\n    mut initial_query: Select<E>,\n    mut link: Vec<LinkDef>,\n) -> Select<E>\nwhere\n    E: EntityTrait,\n{\n    let cte_name = Alias::new(\"cte\");\n\n    let Some(first) = link.first_mut() else {\n        return initial_query;\n    };\n    first.from_tbl = cte_name.clone().into_table_ref();\n    let mut recursive_query: Select<E> =\n        find_linked(link.into_iter().rev(), JoinType::InnerJoin).select_only();\n    initial_query.query.exprs_mut_for_each(|expr| {\n        recursive_query.query.expr(expr.clone());\n    });\n\n    let mut cte_query = initial_query.query.clone();\n    cte_query.union(UnionType::All, recursive_query.query);\n\n    let cte = CommonTableExpression::new()\n        .table_name(cte_name.clone())\n        .query(cte_query)\n        .to_owned();\n\n    let mut select = E::find().select_only();\n    initial_query.query.exprs_mut_for_each(|expr| {\n        select.query.expr(expr.clone());\n    });\n    select\n        .query\n        .from_clear()\n        .from_as(cte_name, E::default())\n        .with_cte(cte);\n    select\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/mod.rs",
    "content": "/// This modules contains types and traits for an  Entity, ActiveMode, Model, PrimaryKey, ForeignKey and Relations.\n///\n/// // An Entity\n/// A unit struct implements [EntityTrait](crate::EntityTrait) representing a table in the database.\n///\n/// This trait contains the properties of an entity including\n///\n/// - The Table Name which is implemented by [EntityName](crate::EntityName)\n/// - The Column which is implemented by [ColumnTrait](crate::ColumnTrait)\n/// - A Relation which is implemented by [RelationTrait](crate::RelationTrait)\n/// - The Primary Key which is implemented by [PrimaryKeyTrait](crate::PrimaryKeyTrait)\n///   and [PrimaryKeyToColumn](crate::PrimaryKeyToColumn)\n///\n/// This trait also provides an API for CRUD actions\n///\n/// #### Example for creating an Entity, Model and ActiveModel\n/// ```\n/// #[cfg(feature = \"macros\")]\n/// # use sea_orm::entity::prelude::*;\n/// use sea_orm::ActiveModelBehavior;\n/// use sea_orm::ColumnDef;\n/// use sea_orm::ColumnTrait;\n/// use sea_orm::ColumnType;\n/// use sea_orm::EntityName;\n/// use sea_orm::PrimaryKeyTrait;\n/// use sea_orm::RelationDef;\n/// use sea_orm::RelationTrait;\n///\n/// // Use [DeriveEntity] to derive the EntityTrait automatically\n/// #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n/// pub struct Entity;\n///\n/// /// The [EntityName] describes the name of a table\n/// impl EntityName for Entity {\n///     fn table_name(&self) -> &'static str {\n///         \"filling\"\n///     }\n/// }\n///\n/// // Create a Model for the Entity through [DeriveModel].\n/// // The `Model` handles `READ` operations on a table in a database.\n/// // The [DeriveActiveModel] creates a way to perform `CREATE` , `READ` and `UPDATE` operations\n/// // in a database\n/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\n/// pub struct Model {\n///     pub id: i32,\n///     pub name: String,\n/// }\n///\n/// // Use the [DeriveColumn] to create a Column for an the table called Entity\n/// // The [EnumIter] which creates a new type that iterates of the variants of a Column.\n/// #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n/// pub enum Column {\n///     Id,\n///     Name,\n/// }\n///\n/// // Create a PrimaryKey for the Entity using the [PrimaryKeyTrait]\n/// // The [EnumIter] which creates a new type that iterates of the variants of a PrimaryKey.\n/// #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n/// pub enum PrimaryKey {\n///     Id,\n/// }\n///\n/// // Or implement the [PrimaryKeyTrait] manually instead of using the macro [DerivePrimaryKey]\n/// impl PrimaryKeyTrait for PrimaryKey {\n///     type ValueType = i32;\n///\n///     fn auto_increment() -> bool {\n///         true\n///     }\n/// }\n///\n/// #[derive(Copy, Clone, Debug, EnumIter)]\n/// pub enum Relation {}\n///\n/// impl ColumnTrait for Column {\n///     type EntityName = Entity;\n///\n///     fn def(&self) -> ColumnDef {\n///         match self {\n///             Self::Id => ColumnType::Integer.def(),\n///             Self::Name => ColumnType::String(StringLen::None).def(),\n///         }\n///     }\n/// }\n///\n/// // Create a Relation for the Entity\n/// impl RelationTrait for Relation {\n///     fn def(&self) -> RelationDef {\n///         unimplemented!()\n///     }\n/// }\n///\n/// // Implement user defined operations for CREATE, UPDATE and DELETE operations\n/// // to create an ActiveModel using the [ActiveModelBehavior]\n/// impl ActiveModelBehavior for ActiveModel {}\n/// ```\nmod active_enum;\nmod active_model;\nmod active_model_ex;\nmod active_value;\n#[cfg(feature = \"with-arrow\")]\nmod arrow_schema;\nmod base_entity;\npub(crate) mod column;\nmod column_def;\npub mod compound;\nmod identity;\nmod link;\nmod model;\nmod partial_model;\n/// Re-export common types from the entity\npub mod prelude;\nmod primary_key;\n#[cfg(feature = \"entity-registry\")]\nmod registry;\nmod relation;\n#[cfg(feature = \"with-arrow\")]\npub(crate) mod with_arrow;\n\npub use active_enum::*;\npub use active_model::*;\npub use active_model_ex::*;\npub use active_value::*;\n#[cfg(feature = \"with-arrow\")]\npub use arrow_schema::*;\npub use base_entity::*;\npub use column::*;\npub use column_def::*;\npub use compound::EntityLoaderTrait;\npub use identity::*;\npub use link::*;\npub use model::*;\npub use partial_model::*;\npub use primary_key::*;\n#[cfg(feature = \"entity-registry\")]\npub use registry::*;\npub use relation::*;\n"
  },
  {
    "path": "sea-orm-sync/src/entity/model.rs",
    "content": "use crate::{\n    ActiveModelBehavior, ActiveModelTrait, ColumnTrait, ConnectionTrait, DbErr, DeleteResult,\n    EntityTrait, IntoActiveModel, Iterable, Linked, PrimaryKeyArity, PrimaryKeyToColumn,\n    PrimaryKeyTrait, QueryFilter, QueryResult, Related, Select, SelectModel, SelectorRaw,\n    Statement, TryGetError, find_linked_recursive,\n};\npub use sea_query::Value;\nuse sea_query::{ArrayType, ValueTuple};\nuse std::fmt::Debug;\n\n/// The interface for Model, implemented by data structs\npub trait ModelTrait: Clone + Debug {\n    #[allow(missing_docs)]\n    type Entity: EntityTrait;\n\n    /// Get the [Value] of a column from a Model\n    fn get(&self, c: <Self::Entity as EntityTrait>::Column) -> Value;\n\n    /// Get the Value Type of a column from the Model\n    fn get_value_type(c: <Self::Entity as EntityTrait>::Column) -> ArrayType;\n\n    /// Set the Value of a Model field, panic if failed\n    fn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) {\n        self.try_set(c, v)\n            .unwrap_or_else(|e| panic!(\"Failed to set value for {:?}: {e:?}\", c.as_column_ref()))\n    }\n\n    /// Set the Value of a Model field, return error if failed\n    fn try_set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) -> Result<(), DbErr>;\n\n    /// Find related Models belonging to self\n    fn find_related<R>(&self, _: R) -> Select<R>\n    where\n        R: EntityTrait,\n        Self::Entity: Related<R>,\n    {\n        <Self::Entity as Related<R>>::find_related().belongs_to(self)\n    }\n\n    /// Find linked Models belonging to self\n    fn find_linked<L>(&self, l: L) -> Select<L::ToEntity>\n    where\n        L: Linked<FromEntity = Self::Entity>,\n    {\n        let tbl_alias = &format!(\"r{}\", l.link().len() - 1);\n        l.find_linked().belongs_to_tbl_alias(self, tbl_alias)\n    }\n\n    #[doc(hidden)]\n    /// Find linked Models with a recursive CTE for self-referencing relation chains\n    fn find_linked_recursive<L>(&self, l: L) -> Select<L::ToEntity>\n    where\n        L: Linked<FromEntity = Self::Entity, ToEntity = Self::Entity>,\n    {\n        // Have to do this because L is not Clone\n        let link = l.link();\n        let initial_query = self.find_linked(l);\n        find_linked_recursive(initial_query, link)\n    }\n\n    /// Delete a model\n    fn delete<'a, A, C>(self, db: &'a C) -> Result<DeleteResult, DbErr>\n    where\n        Self: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: ActiveModelTrait<Entity = Self::Entity> + ActiveModelBehavior + 'a,\n    {\n        self.into_active_model().delete(db)\n    }\n\n    /// Get the primary key value of the Model\n    fn get_primary_key_value(&self) -> ValueTuple {\n        let mut cols = <Self::Entity as EntityTrait>::PrimaryKey::iter();\n        macro_rules! next {\n            () => {\n                self.get(cols.next().expect(\"Already checked arity\").into_column())\n            };\n        }\n        match <<<Self::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n            1 => {\n                let s1 = next!();\n                ValueTuple::One(s1)\n            }\n            2 => {\n                let s1 = next!();\n                let s2 = next!();\n                ValueTuple::Two(s1, s2)\n            }\n            3 => {\n                let s1 = next!();\n                let s2 = next!();\n                let s3 = next!();\n                ValueTuple::Three(s1, s2, s3)\n            }\n            len => {\n                let mut vec = Vec::with_capacity(len);\n                for _ in 0..len {\n                    let s = next!();\n                    vec.push(s);\n                }\n                ValueTuple::Many(vec)\n            }\n        }\n    }\n}\n\n/// A Trait for implementing a [QueryResult]\npub trait FromQueryResult: Sized {\n    /// Instantiate a Model from a [QueryResult]\n    ///\n    /// NOTE: Please also override `from_query_result_nullable` when manually implementing.\n    ///       The future default implementation will be along the lines of:\n    ///\n    /// ```rust,ignore\n    /// fn from_query_result(res: &QueryResult, pre: &str) -> Result<Self, DbErr> {\n    ///     (Self::from_query_result_nullable(res, pre)?)\n    /// }\n    /// ```\n    fn from_query_result(res: &QueryResult, pre: &str) -> Result<Self, DbErr>;\n\n    /// Transform the error from instantiating a Model from a [QueryResult]\n    /// and converting it to an [Option]\n    fn from_query_result_optional(res: &QueryResult, pre: &str) -> Result<Option<Self>, DbErr> {\n        Ok(Self::from_query_result(res, pre).ok())\n\n        // would really like to do the following, but can't without version bump:\n        // match Self::from_query_result_nullable(res, pre) {\n        //     Ok(v) => Ok(Some(v)),\n        //     Err(TryGetError::Null(_)) => Ok(None),\n        //     Err(TryGetError::DbErr(err)) => Err(err),\n        // }\n    }\n\n    /// Transform the error from instantiating a Model from a [QueryResult]\n    /// and converting it to an [Option]\n    ///\n    /// NOTE: This will most likely stop being a provided method in the next major version!\n    fn from_query_result_nullable(res: &QueryResult, pre: &str) -> Result<Self, TryGetError> {\n        Self::from_query_result(res, pre).map_err(TryGetError::DbErr)\n    }\n\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(2),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{FromQueryResult, query::*};\n    ///\n    /// #[derive(Debug, PartialEq, FromQueryResult)]\n    /// struct SelectResult {\n    ///     name: String,\n    ///     num_of_cakes: i32,\n    /// }\n    ///\n    /// let res: Vec<SelectResult> = SelectResult::find_by_statement(Statement::from_sql_and_values(\n    ///     DbBackend::Postgres,\n    ///     r#\"SELECT \"name\", COUNT(*) AS \"num_of_cakes\" FROM \"cake\" GROUP BY(\"name\")\"#,\n    ///     [],\n    /// ))\n    /// .all(&db)\n    /// ?;\n    ///\n    /// assert_eq!(\n    ///     res,\n    ///     [SelectResult {\n    ///         name: \"Chocolate Forest\".to_owned(),\n    ///         num_of_cakes: 2,\n    ///     },]\n    /// );\n    /// #\n    /// # assert_eq!(\n    /// #     db.into_transaction_log(),\n    /// #     [Transaction::from_sql_and_values(\n    /// #         DbBackend::Postgres,\n    /// #         r#\"SELECT \"name\", COUNT(*) AS \"num_of_cakes\" FROM \"cake\" GROUP BY(\"name\")\"#,\n    /// #         []\n    /// #     ),]\n    /// # );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn find_by_statement(stmt: Statement) -> SelectorRaw<SelectModel<Self>> {\n        SelectorRaw::<SelectModel<Self>>::from_statement(stmt)\n    }\n}\n\nimpl<T: FromQueryResult> FromQueryResult for Option<T> {\n    fn from_query_result(res: &QueryResult, pre: &str) -> Result<Self, DbErr> {\n        Ok(Self::from_query_result_nullable(res, pre)?)\n    }\n\n    fn from_query_result_optional(res: &QueryResult, pre: &str) -> Result<Option<Self>, DbErr> {\n        match Self::from_query_result_nullable(res, pre) {\n            Ok(v) => Ok(Some(v)),\n            Err(TryGetError::Null(_)) => Ok(None),\n            Err(TryGetError::DbErr(err)) => Err(err),\n        }\n    }\n\n    fn from_query_result_nullable(res: &QueryResult, pre: &str) -> Result<Self, TryGetError> {\n        match T::from_query_result_nullable(res, pre) {\n            Ok(v) => Ok(Some(v)),\n            Err(TryGetError::Null(_)) => Ok(None),\n            Err(err @ TryGetError::DbErr(_)) => Err(err),\n        }\n    }\n}\n\n/// A Trait for any type that can be converted into an Model\npub trait TryIntoModel<M>\nwhere\n    M: ModelTrait,\n{\n    /// Method to call to perform the conversion\n    fn try_into_model(self) -> Result<M, DbErr>;\n}\n\nimpl<M> TryIntoModel<M> for M\nwhere\n    M: ModelTrait,\n{\n    fn try_into_model(self) -> Result<M, DbErr> {\n        Ok(self)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        IntoActiveModel, Unchanged,\n        prelude::*,\n        tests_cfg::{cake, filling, fruit, post},\n    };\n\n    #[test]\n    fn test_model() {\n        fn filter_by_column(col: post::Column) -> Expr {\n            col.eq(\"attribute\")\n        }\n\n        fn get_value_from(model: &post::Model, col: post::Column) {\n            let value: i32 = model.get(col).unwrap();\n            assert_eq!(value, 12);\n        }\n\n        let model = post::Model {\n            id: 12,\n            user_id: 14,\n            title: \"hello\".into(),\n        };\n\n        get_value_from(&model, post::COLUMN.id.0);\n        filter_by_column(post::COLUMN.title.0);\n\n        let filling = filling::Model {\n            id: 12,\n            name: \"\".into(),\n            vendor_id: None,\n            ignored_attr: 24,\n        };\n\n        let filling_am = filling::ActiveModel {\n            id: Unchanged(12),\n            name: Unchanged(\"\".into()),\n            vendor_id: Unchanged(None),\n        };\n\n        assert_eq!(filling.into_active_model(), filling_am);\n\n        let filling_ex = filling::ActiveModelEx {\n            id: Unchanged(12),\n            name: Unchanged(\"\".into()),\n            vendor_id: Unchanged(None),\n            ingredients: HasManyModel::NotSet,\n        };\n\n        assert_eq!(filling_am.into_ex(), filling_ex);\n\n        let cake_ex = cake::ModelEx {\n            id: 12,\n            name: \"C\".into(),\n            fruit: HasOne::loaded(fruit::Model {\n                id: 13,\n                name: \"F\".into(),\n                cake_id: Some(12),\n            }),\n            fillings: HasMany::Loaded(vec![\n                filling::Model {\n                    id: 14,\n                    name: \"FF\".into(),\n                    vendor_id: None,\n                    ignored_attr: 1,\n                }\n                .into(),\n            ]),\n        };\n\n        let cake_am = cake::ActiveModelEx {\n            id: Unchanged(12),\n            name: Unchanged(\"C\".into()),\n            fruit: HasOneModel::Set(\n                fruit::ActiveModelEx {\n                    id: Unchanged(13),\n                    name: Unchanged(\"F\".into()),\n                    cake_id: Unchanged(Some(12)),\n                }\n                .into(),\n            ),\n            fillings: HasManyModel::Append(vec![filling::ActiveModelEx {\n                id: Unchanged(14),\n                name: Unchanged(\"FF\".into()),\n                vendor_id: Unchanged(None),\n                ingredients: HasManyModel::NotSet,\n            }]),\n        };\n\n        assert_eq!(cake_ex.into_active_model(), cake_am);\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/partial_model.rs",
    "content": "use crate::{EntityTrait, FromQueryResult, IdenStatic, Iterable, ModelTrait, QuerySelect};\nuse sea_query::Expr;\n\n/// A trait for a part of [Model](super::model::ModelTrait)\npub trait PartialModelTrait: FromQueryResult {\n    /// Select specific columns this [PartialModel] needs\n    ///\n    /// No need to implement this method, please implement `select_cols_nested` instead.\n    fn select_cols<S: QuerySelect>(select: S) -> S {\n        Self::select_cols_nested(select, None, None)\n    }\n\n    /// Used when nesting these structs into each other.\n    ///\n    /// Example impl\n    ///\n    /// ```ignore\n    /// fn select_cols_nested<S: QuerySelect>(mut select: S, prefix: Option<&str>) -> S {\n    ///     if let Some(prefix) = prefix {\n    ///         for col in <<T::Entity as EntityTrait>::Column as Iterable>::iter() {\n    ///             let alias = format!(\"{prefix}{}\", col.as_str());\n    ///             select = select.column_as(col, alias);\n    ///         }\n    ///     } else {\n    ///         for col in <<T::Entity as EntityTrait>::Column as Iterable>::iter() {\n    ///             select = select.column(col);\n    ///         }\n    ///     }\n    ///     select\n    /// }\n    /// ```\n    fn select_cols_nested<S: QuerySelect>(\n        select: S,\n        prefix: Option<&str>,\n        alias: Option<&'static str>,\n    ) -> S;\n}\n\nimpl<T: PartialModelTrait> PartialModelTrait for Option<T> {\n    fn select_cols_nested<S: QuerySelect>(\n        select: S,\n        prefix: Option<&str>,\n        alias: Option<&'static str>,\n    ) -> S {\n        T::select_cols_nested(select, prefix, alias)\n    }\n}\n\nimpl<T: ModelTrait + FromQueryResult> PartialModelTrait for T {\n    fn select_cols_nested<S: QuerySelect>(\n        mut select: S,\n        prefix: Option<&str>,\n        alias: Option<&'static str>,\n    ) -> S {\n        match (prefix, alias) {\n            (Some(prefix), Some(alias)) => {\n                for col in <<T::Entity as EntityTrait>::Column as Iterable>::iter() {\n                    let select_as = format!(\"{prefix}{}\", col.as_str());\n                    select = select.column_as(Expr::col((alias, col)), select_as);\n                }\n            }\n            (Some(prefix), None) => {\n                for col in <<T::Entity as EntityTrait>::Column as Iterable>::iter() {\n                    let select_as = format!(\"{prefix}{}\", col.as_str());\n                    select = select.column_as(col, select_as);\n                }\n            }\n            (None, Some(alias)) => {\n                for col in <<T::Entity as EntityTrait>::Column as Iterable>::iter() {\n                    select = select.column_as(Expr::col((alias, col)), col.as_str());\n                }\n            }\n            (None, None) => {\n                for col in <<T::Entity as EntityTrait>::Column as Iterable>::iter() {\n                    select = select.column(col);\n                }\n            }\n        }\n        select\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/prelude.rs",
    "content": "pub use crate::{\n    ActiveEnum, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,\n    ColumnTypeTrait, ConnectionTrait, CursorTrait, DatabaseConnection, DbConn, EntityName,\n    EntityTrait, EnumIter, ForeignKeyAction, Iden, IdenStatic, Linked, LoaderTrait, ModelTrait,\n    PaginatorTrait, PrimaryKeyArity, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult,\n    Related, RelatedSelfVia, RelationDef, RelationTrait, Select, SelectExt, Value,\n    error::*,\n    sea_query::{DynIden, Expr, RcOrArc, SeaRc, StringLen},\n};\n\n#[cfg(feature = \"macros\")]\npub use crate::{\n    DeriveActiveEnum, DeriveActiveModel, DeriveActiveModelBehavior, DeriveActiveModelEx,\n    DeriveArrowSchema, DeriveColumn, DeriveDisplay, DeriveEntity, DeriveEntityModel, DeriveIden,\n    DeriveIntoActiveModel, DeriveModel, DeriveModelEx, DerivePartialModel, DerivePrimaryKey,\n    DeriveRelatedEntity, DeriveRelation, DeriveValueType, FromJsonQueryResult,\n};\n\npub use super::active_model_ex::{HasManyModel, HasOneModel};\npub use super::compound::{HasMany, HasOne};\n\n#[cfg(not(feature = \"sync\"))]\npub use async_trait;\n\n#[cfg(feature = \"with-json\")]\npub use serde_json::Value as Json;\n\n#[cfg(feature = \"with-chrono\")]\npub use chrono::NaiveDate as Date;\n\n#[cfg(feature = \"with-chrono\")]\npub use chrono::NaiveTime as Time;\n\n#[cfg(feature = \"with-chrono\")]\npub use chrono::NaiveDateTime as DateTime;\n\n/// Date time with fixed offset\n#[cfg(feature = \"with-chrono\")]\npub type DateTimeWithTimeZone = chrono::DateTime<chrono::FixedOffset>;\n\n/// Date time represented in UTC\n#[cfg(feature = \"with-chrono\")]\npub type DateTimeUtc = chrono::DateTime<chrono::Utc>;\n\n/// Date time represented in local time\n#[cfg(feature = \"with-chrono\")]\npub type DateTimeLocal = chrono::DateTime<chrono::Local>;\n\n#[cfg(feature = \"with-chrono\")]\npub use chrono::NaiveDate as ChronoDate;\n\n#[cfg(feature = \"with-chrono\")]\npub use chrono::NaiveTime as ChronoTime;\n\n#[cfg(feature = \"with-chrono\")]\npub use chrono::NaiveDateTime as ChronoDateTime;\n\n/// Date time with fixed offset\n#[cfg(feature = \"with-chrono\")]\npub type ChronoDateTimeWithTimeZone = chrono::DateTime<chrono::FixedOffset>;\n\n/// Date time represented in UTC\n#[cfg(feature = \"with-chrono\")]\npub type ChronoDateTimeUtc = chrono::DateTime<chrono::Utc>;\n\n/// The UTC type from chrono\n#[cfg(feature = \"with-chrono\")]\npub type ChronoUtc = chrono::Utc;\n\n/// Date time represented in local time\n#[cfg(feature = \"with-chrono\")]\npub type ChronoDateTimeLocal = chrono::DateTime<chrono::Local>;\n\n#[cfg(feature = \"with-chrono\")]\npub use crate::value::{ChronoUnixTimestamp, ChronoUnixTimestampMillis};\n\n#[cfg(feature = \"with-time\")]\npub use time::Date as TimeDate;\n\n#[cfg(feature = \"with-time\")]\npub use time::Time as TimeTime;\n\n#[cfg(feature = \"with-time\")]\npub use time::PrimitiveDateTime as TimeDateTime;\n\n#[cfg(feature = \"with-time\")]\npub use time::OffsetDateTime as TimeDateTimeWithTimeZone;\n\n#[cfg(feature = \"with-time\")]\npub use crate::value::{TimeUnixTimestamp, TimeUnixTimestampMillis};\n\n#[cfg(feature = \"with-rust_decimal\")]\npub use rust_decimal::Decimal;\n\n#[cfg(feature = \"with-bigdecimal\")]\npub use bigdecimal::BigDecimal;\n\n#[cfg(feature = \"with-uuid\")]\npub use uuid::Uuid;\n\n#[cfg(feature = \"with-uuid\")]\npub use crate::value::TextUuid;\n\n#[cfg(feature = \"postgres-vector\")]\npub use pgvector::Vector as PgVector;\n\n#[cfg(feature = \"with-ipnetwork\")]\npub use ipnetwork::IpNetwork;\n"
  },
  {
    "path": "sea-orm-sync/src/entity/primary_key.rs",
    "content": "use super::{ColumnTrait, IdenStatic, Iterable};\nuse crate::{TryFromU64, TryGetableMany};\nuse sea_query::{FromValueTuple, IntoValueTuple};\nuse std::fmt::Debug;\n\n/// A Trait for to be used to define a Primary Key.\n///\n/// A primary key can be derived manually\n///\n/// ### Example\n/// ```text\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(Copy, Clone, Debug, EnumIter)]\n/// pub enum PrimaryKey {\n///     Id,\n/// }\n/// impl PrimaryKeyTrait for PrimaryKey {\n///     type ValueType = i32;\n///\n///     fn auto_increment() -> bool {\n///         true\n///     }\n/// }\n/// ```\n///\n/// Alternatively, use derive macros to automatically implement the trait for a Primary Key\n///\n/// ### Example\n/// ```text\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n/// pub enum PrimaryKey {\n///     Id,\n/// }\n/// ```\n/// See module level docs [crate::entity] for a full example\npub trait PrimaryKeyTrait: IdenStatic + Iterable {\n    #[allow(missing_docs)]\n    type ValueType: Sized\n        + Debug\n        + PartialEq\n        + IntoValueTuple\n        + FromValueTuple\n        + TryGetableMany\n        + TryFromU64\n        + PrimaryKeyArity;\n\n    /// Method to call to perform `AUTOINCREMENT` operation on a Primary Key\n    fn auto_increment() -> bool;\n}\n\n/// Trait to map a Primary Key to a column\npub trait PrimaryKeyToColumn {\n    #[allow(missing_docs)]\n    type Column: ColumnTrait;\n\n    /// Method to map a primary key to a column in an Entity\n    fn into_column(self) -> Self::Column;\n\n    /// Method to map a primary key from a column in an Entity\n    fn from_column(col: Self::Column) -> Option<Self>\n    where\n        Self: Sized;\n}\n\n/// How many columns this Primary Key comprises\npub trait PrimaryKeyArity {\n    /// Arity of the Primary Key\n    const ARITY: usize;\n}\n\nimpl<V> PrimaryKeyArity for V\nwhere\n    V: crate::TryGetable,\n{\n    const ARITY: usize = 1;\n}\n\nmacro_rules! impl_pk_arity {\n    ($len:expr, $($tuple_arg:ident),*) => {\n        impl<$($tuple_arg: crate::TryGetableMany,)*> PrimaryKeyArity for ($($tuple_arg,)*) {\n            const ARITY: usize = $len;\n        }\n    }\n}\n\nimpl_pk_arity!(1, T1);\nimpl_pk_arity!(2, T1, T2);\nimpl_pk_arity!(3, T1, T2, T3);\nimpl_pk_arity!(4, T1, T2, T3, T4);\nimpl_pk_arity!(5, T1, T2, T3, T4, T5);\nimpl_pk_arity!(6, T1, T2, T3, T4, T5, T6);\nimpl_pk_arity!(7, T1, T2, T3, T4, T5, T6, T7);\nimpl_pk_arity!(8, T1, T2, T3, T4, T5, T6, T7, T8);\nimpl_pk_arity!(9, T1, T2, T3, T4, T5, T6, T7, T8, T9);\nimpl_pk_arity!(10, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);\nimpl_pk_arity!(11, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);\nimpl_pk_arity!(12, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);\n\n#[cfg(test)]\nmod tests {\n    use crate::{EntityTrait, Identity};\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_composite_primary_key() {\n        mod primary_key_of_1 {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"primary_key_of_1\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                pub owner: String,\n                pub name: String,\n                pub description: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        mod primary_key_of_2 {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"primary_key_of_2\")]\n            pub struct Model {\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_1: i32,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_2: String,\n                pub owner: String,\n                pub name: String,\n                pub description: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        mod primary_key_of_3 {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"primary_key_of_3\")]\n            pub struct Model {\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_1: i32,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_2: String,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_3: Uuid,\n                pub owner: String,\n                pub name: String,\n                pub description: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        mod primary_key_of_4 {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"primary_key_of_4\")]\n            pub struct Model {\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_1: TimeDateTimeWithTimeZone,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_2: Uuid,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_3: Json,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_4: Decimal,\n                pub owner: String,\n                pub name: String,\n                pub description: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        mod primary_key_of_11 {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n            #[sea_orm(\n                rs_type = \"String\",\n                db_type = \"String(StringLen::N(1))\",\n                enum_name = \"category\"\n            )]\n            pub enum DeriveCategory {\n                #[sea_orm(string_value = \"B\")]\n                Big,\n                #[sea_orm(string_value = \"S\")]\n                Small,\n            }\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"primary_key_of_11\")]\n            pub struct Model {\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_1: Vec<u8>,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_2: DeriveCategory,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_3: Date,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_4: DateTime,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_5: Time,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_6: TimeTime,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_7: DateTime,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_8: TimeDateTime,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_9: DateTimeLocal,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_10: DateTimeUtc,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_11: DateTimeWithTimeZone,\n                pub owner: String,\n                pub name: String,\n                pub description: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        mod primary_key_of_12 {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"primary_key_of_12\")]\n            pub struct Model {\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_1: String,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_2: i8,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_3: u8,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_4: i16,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_5: u16,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_6: i32,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_7: u32,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_8: i64,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_9: u64,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_10: f32,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_11: f64,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_12: bool,\n                pub owner: String,\n                pub name: String,\n                pub description: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(\n            primary_key_of_3::Entity::primary_key_identity(),\n            Identity::Ternary(\"id_1\".into(), \"id_2\".into(), \"id_3\".into())\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/registry.rs",
    "content": "use crate::{EntitySchemaInfo, Schema, SchemaBuilder};\nuse tracing::debug;\n\n#[derive(derive_more::Debug)]\n/// The data structure submitted by your Entity to the Entity Registry.\npub struct EntityRegistry {\n    /// Please use `module_path!()`.\n    pub module_path: &'static str,\n    /// Function that returns schema info for the Entity.\n    #[debug(skip)]\n    pub schema_info: fn(&Schema) -> EntitySchemaInfo,\n}\n\ninventory::collect!(EntityRegistry);\n\n/// Macro to register an Entity\npub use inventory::submit as register_entity;\n\nimpl EntityRegistry {\n    /// Builds a schema from all the registered entities, filtering by prefix.\n    pub fn build_schema(schema: Schema, prefix: &str) -> SchemaBuilder {\n        let mut schema = SchemaBuilder::new(schema);\n        let mut string;\n        let mut prefix = prefix.trim_end_matches(\"*\");\n        if !prefix.contains(\"::\") {\n            string = format!(\"{prefix}::\");\n            prefix = &string;\n        }\n        if let Some((left, right)) = prefix.split_once(\"::\") {\n            if left.contains(\"-\") {\n                // convert crate name to module path\n                let left = left.replace('-', \"_\");\n                string = format!(\"{left}::{right}\");\n                prefix = &string;\n            }\n        }\n        debug!(\"Registering entities with prefix `{prefix}`\");\n        for entity in inventory::iter::<crate::EntityRegistry>() {\n            if entity.module_path.starts_with(prefix) {\n                schema.register_entity((entity.schema_info)(schema.helper()));\n                debug!(\"Registered {}\", entity.module_path);\n            } else {\n                debug!(\"Skipped {}\", entity.module_path);\n            }\n        }\n        schema\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/relation.rs",
    "content": "use crate::{\n    EntityTrait, Identity, IdentityOf, Iterable, QuerySelect, Select, join_tbl_on_condition,\n};\nuse core::marker::PhantomData;\nuse sea_query::{\n    Condition, ConditionType, DynIden, ForeignKeyCreateStatement, IntoIden, JoinType,\n    TableForeignKey, TableRef,\n};\nuse std::{fmt::Debug, sync::Arc};\n\n/// Defines the type of relationship\n#[derive(Clone, Debug, PartialEq, Eq, Hash)]\npub enum RelationType {\n    /// An Entity has one relationship\n    HasOne,\n    /// An Entity has many relationships\n    HasMany,\n}\n\n/// Action to perform on a foreign key whenever there are changes\n/// to an ActiveModel\npub type ForeignKeyAction = sea_query::ForeignKeyAction;\n\n/// Defines the relations of an Entity\npub trait RelationTrait: Iterable + Debug + 'static {\n    /// Creates a [`RelationDef`]\n    fn def(&self) -> RelationDef;\n\n    /// Name of the relation enum\n    fn name(&self) -> String {\n        format!(\"{self:?}\")\n    }\n}\n\n/// A trait to relate two Entities for them to be joined in queries\npub trait Related<R>\nwhere\n    R: EntityTrait,\n{\n    /// The RelationDef to the related Entity\n    fn to() -> RelationDef;\n\n    /// The RelationDef to the junction table, if any\n    fn via() -> Option<RelationDef> {\n        None\n    }\n\n    /// Find related Entities\n    fn find_related() -> Select<R> {\n        Select::<R>::new().join_join_rev(JoinType::InnerJoin, Self::to(), Self::via())\n    }\n}\n\n/// A trait to relate an Entity to itself through a junction table\npub trait RelatedSelfVia<R>\nwhere\n    R: EntityTrait,\n{\n    /// The RelationDef to the related Entity\n    fn to() -> RelationDef;\n\n    /// The RelationDef to the junction table\n    fn via() -> RelationDef;\n\n    /// Find related Entities\n    fn find_related() -> Select<R> {\n        Select::<R>::new().join_join_rev(JoinType::InnerJoin, Self::to(), Some(Self::via()))\n    }\n}\n\n/// Defines a relationship\n#[derive(derive_more::Debug, Clone)]\npub struct RelationDef {\n    /// The type of relationship defined in [RelationType]\n    pub rel_type: RelationType,\n    /// Reference from another Entity\n    pub from_tbl: TableRef,\n    /// Reference to another Entity\n    pub to_tbl: TableRef,\n    /// Reference to from a Column\n    pub from_col: Identity,\n    /// Reference to another column\n    pub to_col: Identity,\n    /// Defines the owner of the Relation\n    pub is_owner: bool,\n    /// Specifies if the foreign key should be skipped\n    pub skip_fk: bool,\n    /// Defines an operation to be performed on a Foreign Key when a\n    /// `DELETE` Operation is performed\n    pub on_delete: Option<ForeignKeyAction>,\n    /// Defines an operation to be performed on a Foreign Key when a\n    /// `UPDATE` Operation is performed\n    pub on_update: Option<ForeignKeyAction>,\n    /// Custom join ON condition\n    #[debug(\"{}\", on_condition.is_some())]\n    pub on_condition: Option<Arc<dyn Fn(DynIden, DynIden) -> Condition>>,\n    /// The name of foreign key constraint\n    pub fk_name: Option<String>,\n    /// Condition type of join on expression\n    pub condition_type: ConditionType,\n}\n\n/// Idiomatically generate the join condition.\n///\n/// This allows using [RelationDef] directly where [`sea_query`] expects an [`IntoCondition`].\n///\n/// ## Examples\n///\n/// ```\n/// use sea_orm::tests_cfg::{cake, fruit};\n/// use sea_orm::{entity::*, sea_query::*};\n///\n/// let query = Query::select()\n///     .from(fruit::Entity)\n///     .inner_join(cake::Entity, fruit::Relation::Cake.def())\n///     .to_owned();\n///\n/// assert_eq!(\n///     query.to_string(MysqlQueryBuilder),\n///     r#\"SELECT  FROM `fruit` INNER JOIN `cake` ON `fruit`.`cake_id` = `cake`.`id`\"#\n/// );\n/// assert_eq!(\n///     query.to_string(PostgresQueryBuilder),\n///     r#\"SELECT  FROM \"fruit\" INNER JOIN \"cake\" ON \"fruit\".\"cake_id\" = \"cake\".\"id\"\"#\n/// );\n/// assert_eq!(\n///     query.to_string(SqliteQueryBuilder),\n///     r#\"SELECT  FROM \"fruit\" INNER JOIN \"cake\" ON \"fruit\".\"cake_id\" = \"cake\".\"id\"\"#\n/// );\n/// ```\nimpl From<RelationDef> for Condition {\n    fn from(mut rel: RelationDef) -> Condition {\n        // Use table alias (if any) to construct the join condition\n        let from_tbl = match rel.from_tbl.sea_orm_table_alias() {\n            Some(alias) => alias,\n            None => rel.from_tbl.sea_orm_table(),\n        };\n        let to_tbl = match rel.to_tbl.sea_orm_table_alias() {\n            Some(alias) => alias,\n            None => rel.to_tbl.sea_orm_table(),\n        };\n        let owner_keys = rel.from_col;\n        let foreign_keys = rel.to_col;\n\n        let mut condition = match rel.condition_type {\n            ConditionType::All => Condition::all(),\n            ConditionType::Any => Condition::any(),\n        };\n\n        condition = condition.add(join_tbl_on_condition(\n            from_tbl.clone(),\n            to_tbl.clone(),\n            owner_keys,\n            foreign_keys,\n        ));\n        if let Some(f) = rel.on_condition.take() {\n            condition = condition.add(f(from_tbl.clone(), to_tbl.clone()));\n        }\n\n        condition\n    }\n}\n\n/// Defines a helper to build a relation\n#[derive(derive_more::Debug)]\npub struct RelationBuilder<E, R>\nwhere\n    E: EntityTrait,\n    R: EntityTrait,\n{\n    entities: PhantomData<(E, R)>,\n    rel_type: RelationType,\n    from_tbl: TableRef,\n    to_tbl: TableRef,\n    from_col: Option<Identity>,\n    to_col: Option<Identity>,\n    is_owner: bool,\n    skip_fk: bool,\n    on_delete: Option<ForeignKeyAction>,\n    on_update: Option<ForeignKeyAction>,\n    #[debug(\"{}\", on_condition.is_some())]\n    on_condition: Option<Arc<dyn Fn(DynIden, DynIden) -> Condition>>,\n    fk_name: Option<String>,\n    condition_type: ConditionType,\n}\n\nimpl RelationDef {\n    /// Reverse this relation (swap from and to)\n    pub fn rev(self) -> Self {\n        Self {\n            rel_type: self.rel_type,\n            from_tbl: self.to_tbl,\n            to_tbl: self.from_tbl,\n            from_col: self.to_col,\n            to_col: self.from_col,\n            is_owner: !self.is_owner,\n            skip_fk: self.skip_fk,\n            on_delete: self.on_delete,\n            on_update: self.on_update,\n            on_condition: self.on_condition,\n            fk_name: None,\n            condition_type: self.condition_type,\n        }\n    }\n\n    /// Express the relation from a table alias.\n    ///\n    /// This is a shorter and more discoverable equivalent to modifying `from_tbl` field by hand.\n    ///\n    /// # Examples\n    ///\n    /// Here's a short synthetic example.\n    /// In real life you'd use aliases when the table name comes up twice and you need to disambiguate,\n    /// e.g. https://github.com/SeaQL/sea-orm/discussions/2133\n    ///\n    /// ```\n    /// use sea_orm::{\n    ///     DbBackend,\n    ///     entity::*,\n    ///     query::*,\n    ///     tests_cfg::{cake, cake_filling},\n    /// };\n    /// use sea_query::Alias;\n    ///\n    /// let cf = \"cf\";\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .join_as(\n    ///             JoinType::LeftJoin,\n    ///             cake_filling::Relation::Cake.def().rev(),\n    ///             cf.clone()\n    ///         )\n    ///         .join(\n    ///             JoinType::LeftJoin,\n    ///             cake_filling::Relation::Filling.def().from_alias(cf)\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     [\n    ///         \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n    ///         \"LEFT JOIN `cake_filling` AS `cf` ON `cake`.`id` = `cf`.`cake_id`\",\n    ///         \"LEFT JOIN `filling` ON `cf`.`filling_id` = `filling`.`id`\",\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    /// ```\n    pub fn from_alias<A>(mut self, alias: A) -> Self\n    where\n        A: IntoIden,\n    {\n        self.from_tbl = self.from_tbl.alias(alias);\n        self\n    }\n\n    /// Set custom join ON condition.\n    ///\n    /// This method takes a closure with two parameters\n    /// denoting the left-hand side and right-hand side table in the join expression.\n    ///\n    /// This replaces the current condition if it is already set.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use sea_orm::{entity::*, query::*, DbBackend, tests_cfg::{cake, cake_filling}};\n    /// use sea_query::{Expr, ExprTrait, IntoCondition};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .join(\n    ///             JoinType::LeftJoin,\n    ///             cake_filling::Relation::Cake\n    ///                 .def()\n    ///                 .rev()\n    ///                 .on_condition(|_left, right| {\n    ///                     Expr::col((right, cake_filling::Column::CakeId))\n    ///                         .gt(10i32)\n    ///                         .into_condition()\n    ///                 })\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     [\n    ///         \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n    ///         \"LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id` AND `cake_filling`.`cake_id` > 10\",\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    /// ```\n    pub fn on_condition<F>(mut self, f: F) -> Self\n    where\n        F: Fn(DynIden, DynIden) -> Condition + 'static,\n    {\n        self.on_condition = Some(Arc::new(f));\n        self\n    }\n\n    /// Set the condition type of join on expression\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use sea_orm::{entity::*, query::*, DbBackend, tests_cfg::{cake, cake_filling}};\n    /// use sea_query::{Expr, ExprTrait, IntoCondition, ConditionType};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .join(\n    ///             JoinType::LeftJoin,\n    ///             cake_filling::Relation::Cake\n    ///                 .def()\n    ///                 .rev()\n    ///                 .condition_type(ConditionType::Any)\n    ///                 .on_condition(|_left, right| {\n    ///                     Expr::col((right, cake_filling::Column::CakeId))\n    ///                         .gt(10i32)\n    ///                         .into_condition()\n    ///                 })\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     [\n    ///         \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n    ///         \"LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id` OR `cake_filling`.`cake_id` > 10\",\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    /// ```\n    pub fn condition_type(mut self, condition_type: ConditionType) -> Self {\n        self.condition_type = condition_type;\n        self\n    }\n}\n\nimpl<E, R> RelationBuilder<E, R>\nwhere\n    E: EntityTrait,\n    R: EntityTrait,\n{\n    pub(crate) fn new(rel_type: RelationType, from: E, to: R, is_owner: bool) -> Self {\n        Self {\n            entities: PhantomData,\n            rel_type,\n            from_tbl: from.table_ref(),\n            to_tbl: to.table_ref(),\n            from_col: None,\n            to_col: None,\n            is_owner,\n            skip_fk: false,\n            on_delete: None,\n            on_update: None,\n            on_condition: None,\n            fk_name: None,\n            condition_type: ConditionType::All,\n        }\n    }\n\n    pub(crate) fn from_rel(rel_type: RelationType, rel: RelationDef, is_owner: bool) -> Self {\n        Self {\n            entities: PhantomData,\n            rel_type,\n            from_tbl: rel.from_tbl,\n            to_tbl: rel.to_tbl,\n            from_col: Some(rel.from_col),\n            to_col: Some(rel.to_col),\n            is_owner,\n            skip_fk: false,\n            on_delete: None,\n            on_update: None,\n            on_condition: None,\n            fk_name: None,\n            condition_type: ConditionType::All,\n        }\n    }\n\n    /// Build a relationship from an Entity\n    pub fn from<T>(mut self, identifier: T) -> Self\n    where\n        T: IdentityOf<E>,\n    {\n        self.from_col = Some(identifier.identity_of());\n        self\n    }\n\n    /// Build a relationship to an Entity\n    pub fn to<T>(mut self, identifier: T) -> Self\n    where\n        T: IdentityOf<R>,\n    {\n        self.to_col = Some(identifier.identity_of());\n        self\n    }\n\n    /// Force the foreign key to not be created\n    pub fn skip_fk(mut self) -> Self {\n        self.skip_fk = true;\n        self\n    }\n\n    /// An operation to perform on a foreign key when a delete operation occurs\n    pub fn on_delete(mut self, action: ForeignKeyAction) -> Self {\n        self.on_delete = Some(action);\n        self\n    }\n\n    /// An operation to perform on a foreign key when an update operation occurs\n    pub fn on_update(mut self, action: ForeignKeyAction) -> Self {\n        self.on_update = Some(action);\n        self\n    }\n\n    /// Set custom join ON condition.\n    ///\n    /// This method takes a closure with parameters\n    /// denoting the left-hand side and right-hand side table in the join expression.\n    pub fn on_condition<F>(mut self, f: F) -> Self\n    where\n        F: Fn(DynIden, DynIden) -> Condition + 'static,\n    {\n        self.on_condition = Some(Arc::new(f));\n        self\n    }\n\n    /// Set the name of foreign key constraint\n    pub fn fk_name(mut self, fk_name: &str) -> Self {\n        self.fk_name = Some(fk_name.to_owned());\n        self\n    }\n\n    /// Set the condition type of join on expression\n    pub fn condition_type(mut self, condition_type: ConditionType) -> Self {\n        self.condition_type = condition_type;\n        self\n    }\n}\n\nimpl<E, R> From<RelationBuilder<E, R>> for RelationDef\nwhere\n    E: EntityTrait,\n    R: EntityTrait,\n{\n    fn from(b: RelationBuilder<E, R>) -> Self {\n        RelationDef {\n            rel_type: b.rel_type,\n            from_tbl: b.from_tbl,\n            to_tbl: b.to_tbl,\n            from_col: b.from_col.expect(\"Reference column is not set\"),\n            to_col: b.to_col.expect(\"Owner column is not set\"),\n            is_owner: b.is_owner,\n            skip_fk: b.skip_fk,\n            on_delete: b.on_delete,\n            on_update: b.on_update,\n            on_condition: b.on_condition,\n            fk_name: b.fk_name,\n            condition_type: b.condition_type,\n        }\n    }\n}\n\nmacro_rules! set_foreign_key_stmt {\n    ( $relation: ident, $foreign_key: ident ) => {\n        let from_cols: Vec<String> = $relation\n            .from_col\n            .into_iter()\n            .map(|col| {\n                let col_name = col.to_string();\n                $foreign_key.from_col(col);\n                col_name\n            })\n            .collect();\n        for col in $relation.to_col.into_iter() {\n            $foreign_key.to_col(col);\n        }\n        if let Some(action) = $relation.on_delete {\n            $foreign_key.on_delete(action);\n        }\n        if let Some(action) = $relation.on_update {\n            $foreign_key.on_update(action);\n        }\n        let name = if let Some(name) = $relation.fk_name {\n            name\n        } else {\n            let from_tbl = &$relation.from_tbl.sea_orm_table().clone();\n            format!(\"fk-{}-{}\", from_tbl.to_string(), from_cols.join(\"-\"))\n        };\n        $foreign_key.name(&name);\n    };\n}\n\nimpl From<RelationDef> for ForeignKeyCreateStatement {\n    fn from(relation: RelationDef) -> Self {\n        let mut foreign_key_stmt = Self::new();\n        set_foreign_key_stmt!(relation, foreign_key_stmt);\n        foreign_key_stmt\n            .from_tbl(relation.from_tbl)\n            .to_tbl(relation.to_tbl)\n            .take()\n    }\n}\n\n/// Creates a column definition for example to update a table.\n/// ```\n/// use sea_query::{Alias, IntoIden, MysqlQueryBuilder, TableAlterStatement, IntoTableRef, ConditionType};\n/// use sea_orm::{EnumIter, Iden, Identity, PrimaryKeyTrait, RelationDef, RelationTrait, RelationType};\n///\n/// let relation = RelationDef {\n///     rel_type: RelationType::HasOne,\n///     from_tbl: \"foo\".into_table_ref(),\n///     to_tbl: \"bar\".into_table_ref(),\n///     from_col: Identity::Unary(\"bar_id\".into_iden()),\n///     to_col: Identity::Unary(\"bar_id\".into_iden()),\n///     is_owner: false,\n///     on_delete: None,\n///     on_update: None,\n///     on_condition: None,\n///     fk_name: Some(\"foo-bar\".to_string()),\n///     skip_fk: false,\n///     condition_type: ConditionType::All,\n/// };\n///\n/// let mut alter_table = TableAlterStatement::new()\n///     .table(\"foo\")\n///     .add_foreign_key(&mut relation.into()).take();\n/// assert_eq!(\n///     alter_table.to_string(MysqlQueryBuilder::default()),\n///     \"ALTER TABLE `foo` ADD CONSTRAINT `foo-bar` FOREIGN KEY (`bar_id`) REFERENCES `bar` (`bar_id`)\"\n/// );\n/// ```\nimpl From<RelationDef> for TableForeignKey {\n    fn from(relation: RelationDef) -> Self {\n        let mut foreign_key = Self::new();\n        set_foreign_key_stmt!(relation, foreign_key);\n        foreign_key\n            .from_tbl(relation.from_tbl.sea_orm_table().clone())\n            .to_tbl(relation.to_tbl.sea_orm_table().clone())\n            .take()\n    }\n}\n\nimpl std::hash::Hash for RelationDef {\n    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {\n        self.rel_type.hash(state);\n        self.from_tbl.sea_orm_table().hash(state);\n        self.to_tbl.sea_orm_table().hash(state);\n        self.from_col.hash(state);\n        self.to_col.hash(state);\n        self.is_owner.hash(state);\n    }\n}\n\nimpl PartialEq for RelationDef {\n    fn eq(&self, other: &Self) -> bool {\n        self.rel_type.eq(&other.rel_type)\n            && self.from_tbl.eq(&other.from_tbl)\n            && self.to_tbl.eq(&other.to_tbl)\n            && itertools::equal(self.from_col.iter(), other.from_col.iter())\n            && itertools::equal(self.to_col.iter(), other.to_col.iter())\n            && self.is_owner.eq(&other.is_owner)\n    }\n}\n\nimpl Eq for RelationDef {}\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        RelationBuilder, RelationDef,\n        tests_cfg::{cake, fruit},\n    };\n\n    #[cfg(not(feature = \"sync\"))]\n    #[test]\n    fn assert_relation_traits() {\n        fn assert_send_sync<T: Send>() {}\n\n        assert_send_sync::<RelationDef>();\n        assert_send_sync::<RelationBuilder<cake::Entity, fruit::Entity>>();\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/entity/with_arrow.rs",
    "content": "use crate::DbErr;\nuse sea_orm_arrow::arrow::array::Array;\nuse sea_query::{ColumnType, Value};\n\npub use sea_orm_arrow::ArrowError;\n\nimpl From<ArrowError> for DbErr {\n    fn from(e: ArrowError) -> Self {\n        DbErr::Type(e.to_string())\n    }\n}\n\npub(crate) fn arrow_array_to_value(\n    array: &dyn Array,\n    col_type: &ColumnType,\n    row: usize,\n) -> Result<Value, DbErr> {\n    sea_orm_arrow::arrow_array_to_value(array, col_type, row).map_err(Into::into)\n}\n\n#[cfg(all(feature = \"with-chrono\", feature = \"with-time\"))]\npub(crate) fn arrow_array_to_value_alt(\n    array: &dyn Array,\n    col_type: &ColumnType,\n    row: usize,\n) -> Result<Option<Value>, DbErr> {\n    sea_orm_arrow::arrow_array_to_value_alt(array, col_type, row).map_err(Into::into)\n}\n\npub(crate) fn is_datetime_column(col_type: &ColumnType) -> bool {\n    sea_orm_arrow::is_datetime_column(col_type)\n}\n\npub(crate) fn option_values_to_arrow_array(\n    values: &[Option<Value>],\n    data_type: &sea_orm_arrow::arrow::datatypes::DataType,\n) -> Result<std::sync::Arc<dyn Array>, DbErr> {\n    sea_orm_arrow::option_values_to_arrow_array(values, data_type).map_err(Into::into)\n}\n"
  },
  {
    "path": "sea-orm-sync/src/error.rs",
    "content": "#[cfg(feature = \"sqlx-dep\")]\npub use sqlx::error::Error as SqlxError;\n\n#[cfg(feature = \"sqlx-mysql\")]\npub use sqlx::mysql::MySqlDatabaseError as SqlxMySqlError;\n\n#[cfg(feature = \"sqlx-postgres\")]\npub use sqlx::postgres::PgDatabaseError as SqlxPostgresError;\n\n#[cfg(feature = \"sqlx-sqlite\")]\npub use sqlx::sqlite::SqliteError as SqlxSqliteError;\n\nuse std::sync::Arc;\nuse thiserror::Error;\n\n/// An error from unsuccessful database operations\n#[derive(Error, Debug, Clone)]\npub enum DbErr {\n    /// This error can happen when the connection pool is fully-utilized\n    #[error(\"Failed to acquire connection from pool: {0}\")]\n    ConnectionAcquire(#[source] ConnAcquireErr),\n    /// Runtime type conversion error\n    #[error(\"Error converting `{from}` into `{into}`: {source}\")]\n    TryIntoErr {\n        /// From type\n        from: &'static str,\n        /// Into type\n        into: &'static str,\n        /// TryError\n        source: Arc<dyn std::error::Error + Send + Sync>,\n    },\n    /// There was a problem with the database connection\n    #[error(\"Connection Error: {0}\")]\n    Conn(#[source] RuntimeErr),\n    /// An operation did not execute successfully\n    #[error(\"Execution Error: {0}\")]\n    Exec(#[source] RuntimeErr),\n    /// An error occurred while performing a query\n    #[error(\"Query Error: {0}\")]\n    Query(#[source] RuntimeErr),\n    /// Type error: the specified type cannot be converted from u64. This is not a runtime error.\n    #[error(\"Type '{0}' cannot be converted from u64\")]\n    ConvertFromU64(&'static str),\n    /// After an insert statement it was impossible to retrieve the last_insert_id\n    #[error(\"Failed to unpack last_insert_id\")]\n    UnpackInsertId,\n    /// When updating, a model should know its primary key to check\n    /// if the record has been correctly updated, otherwise this error will occur\n    #[error(\"Failed to get primary key from model\")]\n    UpdateGetPrimaryKey,\n    /// The record was not found in the database\n    #[error(\"RecordNotFound Error: {0}\")]\n    RecordNotFound(String),\n    /// Thrown by `TryFrom<ActiveModel>`, which assumes all attributes are set/unchanged\n    #[error(\"Attribute {0} is NotSet\")]\n    AttrNotSet(String),\n    /// A custom error\n    #[error(\"Custom Error: {0}\")]\n    Custom(String),\n    /// Error occurred while parsing value as target type\n    #[error(\"Type Error: {0}\")]\n    Type(String),\n    /// Error occurred while parsing json value as target type\n    #[error(\"Json Error: {0}\")]\n    Json(String),\n    /// A migration error\n    #[error(\"Migration Error: {0}\")]\n    Migration(String),\n    /// None of the records are inserted,\n    /// that probably means all of them conflict with existing records in the table\n    #[error(\"None of the records are inserted\")]\n    RecordNotInserted,\n    /// None of the records are updated, that means a WHERE condition has no matches.\n    /// May be the table is empty or the record does not exist\n    #[error(\"None of the records are updated\")]\n    RecordNotUpdated,\n    /// This operation is not supported by the database backend\n    #[error(\"Operation not supported by backend {db}: {ctx}\")]\n    BackendNotSupported {\n        /// Database backend\n        db: &'static str,\n        /// Context\n        ctx: &'static str,\n    },\n    /// (Primary) Key arity mismatch\n    #[error(\"Key arity mismatch: expected {expected}, received {received}\")]\n    KeyArityMismatch {\n        /// Expected value\n        expected: u8,\n        /// Received value\n        received: u8,\n    },\n    /// Primay key not set for update / delete\n    #[error(\"Primay key not set for {ctx}\")]\n    PrimaryKeyNotSet {\n        /// Context\n        ctx: &'static str,\n    },\n    /// Error while running RBAC checks\n    #[error(\"RBAC error: {0}\")]\n    RbacError(String),\n    /// Access denied after running RBAC checks\n    #[error(\"Access denied: cannot perform `{permission}` on `{resource}`\")]\n    AccessDenied {\n        /// The required permission\n        permission: String,\n        /// The requested resource\n        resource: String,\n    },\n    /// Mutex was poisoned by another thread\n    #[error(\"Mutex poisoned\")]\n    MutexPoisonError,\n}\n\n/// An error from trying to get a row from a Model\n#[derive(Debug)]\npub enum TryGetError {\n    /// A database error was encountered as defined in [crate::DbErr]\n    DbErr(DbErr),\n    /// A null value was encountered\n    Null(String),\n}\n\n/// Connection Acquire error\n#[derive(Error, Debug, PartialEq, Eq, Copy, Clone)]\npub enum ConnAcquireErr {\n    /// Connection pool timed out\n    #[error(\"Connection pool timed out\")]\n    Timeout,\n    /// Connection closed\n    #[error(\"Connection closed\")]\n    ConnectionClosed,\n}\n\n/// Runtime error\n#[derive(Error, Debug, Clone)]\npub enum RuntimeErr {\n    /// SQLx Error\n    #[cfg(feature = \"sqlx-dep\")]\n    #[error(\"{0}\")]\n    SqlxError(Arc<sqlx::error::Error>),\n    /// Rusqlite Error\n    #[cfg(feature = \"rusqlite\")]\n    #[error(\"{0}\")]\n    Rusqlite(Arc<crate::driver::rusqlite::RusqliteError>),\n    /// Error generated from within SeaORM\n    #[error(\"{0}\")]\n    Internal(String),\n}\n\nimpl PartialEq for DbErr {\n    fn eq(&self, other: &Self) -> bool {\n        self.to_string() == other.to_string()\n    }\n}\n\nimpl Eq for DbErr {}\n\n/// Error during `impl FromStr for Entity::Column`\n#[derive(Error, Debug)]\n#[error(\"Failed to match \\\"{0}\\\" as Column\")]\npub struct ColumnFromStrErr(pub String);\n\n#[allow(dead_code)]\npub(crate) fn conn_err<T>(s: T) -> DbErr\nwhere\n    T: ToString,\n{\n    DbErr::Conn(RuntimeErr::Internal(s.to_string()))\n}\n\n#[allow(dead_code)]\npub(crate) fn exec_err<T>(s: T) -> DbErr\nwhere\n    T: ToString,\n{\n    DbErr::Exec(RuntimeErr::Internal(s.to_string()))\n}\n\n#[allow(dead_code)]\npub(crate) fn query_err<T>(s: T) -> DbErr\nwhere\n    T: ToString,\n{\n    DbErr::Query(RuntimeErr::Internal(s.to_string()))\n}\n\n#[allow(dead_code)]\npub(crate) fn type_err<T>(s: T) -> DbErr\nwhere\n    T: ToString,\n{\n    DbErr::Type(s.to_string())\n}\n\n#[allow(dead_code)]\npub(crate) fn json_err<T>(s: T) -> DbErr\nwhere\n    T: ToString,\n{\n    DbErr::Json(s.to_string())\n}\n\n/// An error from unsuccessful SQL query\n#[derive(Error, Debug, Clone, PartialEq, Eq)]\n#[non_exhaustive]\npub enum SqlErr {\n    /// Error for duplicate record in unique field or primary key field\n    #[error(\"Unique Constraint Violated: {0}\")]\n    UniqueConstraintViolation(String),\n    /// Error for Foreign key constraint\n    #[error(\"Foreign Key Constraint Violated: {0}\")]\n    ForeignKeyConstraintViolation(String),\n}\n\n#[allow(dead_code)]\nimpl DbErr {\n    /// Convert generic DbErr by sqlx to SqlErr, return none if the error is not any type of SqlErr\n    pub fn sql_err(&self) -> Option<SqlErr> {\n        #[cfg(any(\n            feature = \"sqlx-mysql\",\n            feature = \"sqlx-postgres\",\n            feature = \"sqlx-sqlite\"\n        ))]\n        {\n            use std::ops::Deref;\n            if let DbErr::Exec(RuntimeErr::SqlxError(e)) | DbErr::Query(RuntimeErr::SqlxError(e)) =\n                self\n            {\n                if let sqlx::Error::Database(e) = e.deref() {\n                    let error_code = e.code().unwrap_or_default();\n                    let _error_code_expanded = error_code.deref();\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    if e.try_downcast_ref::<sqlx::mysql::MySqlDatabaseError>()\n                        .is_some()\n                    {\n                        let error_number = e\n                            .try_downcast_ref::<sqlx::mysql::MySqlDatabaseError>()?\n                            .number();\n                        match error_number {\n                            // 1022 Can't write; duplicate key in table '%s'\n                            // 1062 Duplicate entry '%s' for key %d\n                            // 1169 Can't write, because of unique constraint, to table '%s'\n                            // 1586 Duplicate entry '%s' for key '%s'\n                            1022 | 1062 | 1169 | 1586 => {\n                                return Some(SqlErr::UniqueConstraintViolation(e.message().into()));\n                            }\n                            // 1216 Cannot add or update a child row: a foreign key constraint fails\n                            // 1217 Cannot delete or update a parent row: a foreign key constraint fails\n                            // 1451 Cannot delete or update a parent row: a foreign key constraint fails (%s)\n                            // 1452 Cannot add or update a child row: a foreign key constraint fails (%s)\n                            // 1557 Upholding foreign key constraints for table '%s', entry '%s', key %d would lead to a duplicate entry\n                            // 1761 Foreign key constraint for table '%s', record '%s' would lead to a duplicate entry in table '%s', key '%s'\n                            // 1762 Foreign key constraint for table '%s', record '%s' would lead to a duplicate entry in a child table\n                            1216 | 1217 | 1451 | 1452 | 1557 | 1761 | 1762 => {\n                                return Some(SqlErr::ForeignKeyConstraintViolation(\n                                    e.message().into(),\n                                ));\n                            }\n                            _ => return None,\n                        }\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    if e.try_downcast_ref::<sqlx::postgres::PgDatabaseError>()\n                        .is_some()\n                    {\n                        match _error_code_expanded {\n                            \"23505\" => {\n                                return Some(SqlErr::UniqueConstraintViolation(e.message().into()));\n                            }\n                            \"23503\" => {\n                                return Some(SqlErr::ForeignKeyConstraintViolation(\n                                    e.message().into(),\n                                ));\n                            }\n                            _ => return None,\n                        }\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    if e.try_downcast_ref::<sqlx::sqlite::SqliteError>().is_some() {\n                        match _error_code_expanded {\n                            // error code 1555 refers to the primary key's unique constraint violation\n                            // error code 2067 refers to the UNIQUE unique constraint violation\n                            \"1555\" | \"2067\" => {\n                                return Some(SqlErr::UniqueConstraintViolation(e.message().into()));\n                            }\n                            \"787\" => {\n                                return Some(SqlErr::ForeignKeyConstraintViolation(\n                                    e.message().into(),\n                                ));\n                            }\n                            _ => return None,\n                        }\n                    }\n                }\n            }\n        }\n        #[cfg(feature = \"rusqlite\")]\n        if let DbErr::Exec(RuntimeErr::Rusqlite(err)) | DbErr::Query(RuntimeErr::Rusqlite(err)) =\n            self\n        {\n            use crate::driver::rusqlite::RusqliteError;\n            use std::ops::Deref;\n\n            if let RusqliteError::SqliteFailure(err, msg) = err.deref() {\n                match err.extended_code {\n                    1555 | 2067 => {\n                        return Some(SqlErr::UniqueConstraintViolation(\n                            msg.to_owned().unwrap_or_else(|| err.to_string()),\n                        ));\n                    }\n                    787 => {\n                        return Some(SqlErr::ForeignKeyConstraintViolation(\n                            msg.to_owned().unwrap_or_else(|| err.to_string()),\n                        ));\n                    }\n                    _ => (),\n                }\n            }\n        }\n        None\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/consolidate.rs",
    "content": "#![allow(clippy::type_complexity)]\nuse crate::{\n    EntityTrait, Iterable, ModelTrait, PrimaryKeyArity, PrimaryKeyToColumn, PrimaryKeyTrait,\n};\nuse sea_query::Value;\nuse std::collections::{HashMap, HashSet};\nuse std::hash::Hash;\n\npub(super) fn consolidate_query_result<L, R>(\n    rows: Vec<(L::Model, Option<R::Model>)>,\n) -> Vec<(L::Model, Vec<R::Model>)>\nwhere\n    L: EntityTrait,\n    R: EntityTrait,\n{\n    // given that ARITY is a compile-time const, I hope the other branches can be eliminated as dead code\n    match <<L::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n        1 => consolidate_query_result_of::<L, R, _>(rows, unit_pk::<L>()),\n        2 => consolidate_query_result_of::<L, R, _>(rows, pair_pk::<L>()),\n        _ => consolidate_query_result_of::<L, R, _>(rows, tuple_pk::<L>()),\n    }\n}\n\npub(super) fn consolidate_query_result_tee<L, M, R>(\n    rows: Vec<(L::Model, Option<M::Model>, Option<R::Model>)>,\n) -> Vec<(L::Model, Vec<M::Model>, Vec<R::Model>)>\nwhere\n    L: EntityTrait,\n    M: EntityTrait,\n    R: EntityTrait,\n{\n    match <<L::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n        1 => consolidate_query_result_of_tee::<L, M, R, _>(rows, unit_pk::<L>()),\n        2 => consolidate_query_result_of_tee::<L, M, R, _>(rows, pair_pk::<L>()),\n        _ => consolidate_query_result_of_tee::<L, M, R, _>(rows, tuple_pk::<L>()),\n    }\n}\n\npub(super) fn consolidate_query_result_chain<L, M, R>(\n    rows: Vec<(L::Model, Option<M::Model>, Option<R::Model>)>,\n) -> Vec<(L::Model, Vec<(M::Model, Vec<R::Model>)>)>\nwhere\n    L: EntityTrait,\n    M: EntityTrait,\n    R: EntityTrait,\n{\n    match <<L::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n        1 => consolidate_query_result_of_chain::<L, M, R, _>(rows, unit_pk::<L>()),\n        2 => consolidate_query_result_of_chain::<L, M, R, _>(rows, pair_pk::<L>()),\n        _ => consolidate_query_result_of_chain::<L, M, R, _>(rows, tuple_pk::<L>()),\n    }\n}\n\nfn retain_unique_models<L>(rows: Vec<L::Model>) -> Vec<L::Model>\nwhere\n    L: EntityTrait,\n{\n    match <<L::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n        1 => retain_unique_models_of::<L, _>(rows, unit_pk::<L>()),\n        2 => retain_unique_models_of::<L, _>(rows, pair_pk::<L>()),\n        _ => retain_unique_models_of::<L, _>(rows, tuple_pk::<L>()),\n    }\n}\n\n// This generic here is that we need to support composite primary key,\n// and that we don't want to penalize the unit pk which is the most common.\ntrait ModelKey<E: EntityTrait> {\n    type Type: Hash + PartialEq + Eq;\n    fn get(&self, model: &E::Model) -> Self::Type;\n}\n\n// This could have been an array of [E::Column; <E::PrimaryKey as PrimaryKeyTrait>::ARITY], but it still doesn't compile\nstruct UnitPk<E: EntityTrait>(E::Column);\nstruct PairPk<E: EntityTrait>(E::Column, E::Column);\nstruct TuplePk<E: EntityTrait>(Vec<E::Column>);\n\n#[allow(clippy::unwrap_used)]\nfn unit_pk<E: EntityTrait>() -> UnitPk<E> {\n    let col = <E::PrimaryKey as Iterable>::iter()\n        .next()\n        .unwrap()\n        .into_column();\n    UnitPk(col)\n}\n\n#[allow(clippy::unwrap_used)]\nfn pair_pk<E: EntityTrait>() -> PairPk<E> {\n    let mut iter = <E::PrimaryKey as Iterable>::iter();\n    let col1 = iter.next().unwrap().into_column();\n    let col2 = iter.next().unwrap().into_column();\n    PairPk(col1, col2)\n}\n\nfn tuple_pk<E: EntityTrait>() -> TuplePk<E> {\n    let cols: Vec<_> = <E::PrimaryKey as Iterable>::iter()\n        .map(|pk| pk.into_column())\n        .collect();\n    TuplePk(cols)\n}\n\nimpl<E: EntityTrait> ModelKey<E> for UnitPk<E> {\n    type Type = Value;\n    fn get(&self, model: &E::Model) -> Self::Type {\n        model.get(self.0)\n    }\n}\n\nimpl<E: EntityTrait> ModelKey<E> for PairPk<E> {\n    type Type = (Value, Value);\n    fn get(&self, model: &E::Model) -> Self::Type {\n        (model.get(self.0), model.get(self.1))\n    }\n}\n\nimpl<E: EntityTrait> ModelKey<E> for TuplePk<E> {\n    type Type = Vec<Value>;\n    fn get(&self, model: &E::Model) -> Self::Type {\n        let mut key = Vec::new();\n        for col in self.0.iter() {\n            key.push(model.get(*col));\n        }\n        key\n    }\n}\n\nfn consolidate_query_result_of<L, R, KEY: ModelKey<L>>(\n    mut rows: Vec<(L::Model, Option<R::Model>)>,\n    model_key: KEY,\n) -> Vec<(L::Model, Vec<R::Model>)>\nwhere\n    L: EntityTrait,\n    R: EntityTrait,\n{\n    // group items by unique key on left model\n    let mut hashmap: HashMap<KEY::Type, Vec<R::Model>> =\n        rows.iter_mut().fold(HashMap::new(), |mut acc, row| {\n            let key = model_key.get(&row.0); // keep left model in place\n            if let Some(value) = row.1.take() {\n                // take ownership of right model\n                if let Some(vec) = acc.get_mut(&key) {\n                    vec.push(value)\n                } else {\n                    acc.insert(key, vec![value]);\n                }\n            } else {\n                acc.entry(key).or_default(); // insert empty vec\n            }\n\n            acc\n        });\n\n    // re-iterate so that we keep the same order\n    rows.into_iter()\n        .filter_map(|(l_model, _)| {\n            // right model is empty here already\n            let l_pk = model_key.get(&l_model);\n            // the first time we encounter a left model, the value is taken\n            // subsequently the key will be empty\n            let r_models = hashmap.remove(&l_pk);\n            r_models.map(|r_models| (l_model, r_models))\n        })\n        .collect()\n}\n\n// this consolidate query result of a T topology\n// where L -> M and L -> R\nfn consolidate_query_result_of_tee<L, M, R, KEY: ModelKey<L>>(\n    mut rows: Vec<(L::Model, Option<M::Model>, Option<R::Model>)>,\n    model_key: KEY,\n) -> Vec<(L::Model, Vec<M::Model>, Vec<R::Model>)>\nwhere\n    L: EntityTrait,\n    M: EntityTrait,\n    R: EntityTrait,\n{\n    struct Slot<M, R> {\n        m: Vec<M>,\n        r: Vec<R>,\n    }\n\n    impl<M, R> Default for Slot<M, R> {\n        fn default() -> Self {\n            Self {\n                m: vec![],\n                r: vec![],\n            }\n        }\n    }\n\n    // group items by unique key on left model\n    let mut hashmap: HashMap<KEY::Type, Slot<M::Model, R::Model>> =\n        rows.iter_mut().fold(HashMap::new(), |mut acc, row| {\n            let key = model_key.get(&row.0);\n            match (row.1.take(), row.2.take()) {\n                (Some(m), Some(r)) => {\n                    if let Some(slot) = acc.get_mut(&key) {\n                        slot.m.push(m);\n                        slot.r.push(r);\n                    } else {\n                        acc.insert(\n                            key,\n                            Slot {\n                                m: vec![m],\n                                r: vec![r],\n                            },\n                        );\n                    }\n                }\n                (Some(m), None) => {\n                    if let Some(slot) = acc.get_mut(&key) {\n                        slot.m.push(m);\n                    } else {\n                        acc.insert(\n                            key,\n                            Slot {\n                                m: vec![m],\n                                r: vec![],\n                            },\n                        );\n                    }\n                }\n                (None, Some(r)) => {\n                    if let Some(slot) = acc.get_mut(&key) {\n                        slot.r.push(r);\n                    } else {\n                        acc.insert(\n                            key,\n                            Slot {\n                                m: vec![],\n                                r: vec![r],\n                            },\n                        );\n                    }\n                }\n                (None, None) => {\n                    acc.entry(key).or_default(); // insert empty vec\n                }\n            }\n\n            acc\n        });\n\n    // re-iterate so that we keep the same order\n    rows.into_iter()\n        .filter_map(|(l_model, _, _)| {\n            let l_pk = model_key.get(&l_model);\n            let mr_models = hashmap.remove(&l_pk);\n            // if both L -> M and L -> R is one to many\n            // it's possible for them to have duplicates\n            mr_models.map(|Slot { m, r }| {\n                (\n                    l_model,\n                    retain_unique_models::<M>(m),\n                    retain_unique_models::<R>(r),\n                )\n            })\n        })\n        .collect()\n}\n\n// this consolidate query result of a chained topology\n// where L -> M and M -> R\nfn consolidate_query_result_of_chain<L, M, R, KEY: ModelKey<L>>(\n    mut rows: Vec<(L::Model, Option<M::Model>, Option<R::Model>)>,\n    model_key: KEY,\n) -> Vec<(L::Model, Vec<(M::Model, Vec<R::Model>)>)>\nwhere\n    L: EntityTrait,\n    M: EntityTrait,\n    R: EntityTrait,\n{\n    // group items by unique key on left model\n    let mut hashmap: HashMap<KEY::Type, Vec<(M::Model, Option<R::Model>)>> =\n        rows.iter_mut().fold(HashMap::new(), |mut acc, row| {\n            let key = model_key.get(&row.0);\n            match (row.1.take(), row.2.take()) {\n                (Some(m), Some(r)) => {\n                    if let Some(slot) = acc.get_mut(&key) {\n                        slot.push((m, Some(r)));\n                    } else {\n                        acc.insert(key, vec![(m, Some(r))]);\n                    }\n                }\n                (Some(m), None) => {\n                    if let Some(slot) = acc.get_mut(&key) {\n                        slot.push((m, None));\n                    } else {\n                        acc.insert(key, vec![(m, None)]);\n                    }\n                }\n                (None, Some(_)) => {\n                    panic!(\n                        \"Impossible to have R when M ({}) -> R ({})\",\n                        M::default().as_str(),\n                        R::default().as_str()\n                    )\n                }\n                (None, None) => {\n                    acc.entry(key).or_default(); // insert empty vec\n                }\n            }\n\n            acc\n        });\n\n    // re-iterate so that we keep the same order\n    rows.into_iter()\n        .filter_map(|(l_model, _, _)| {\n            let l_pk = model_key.get(&l_model);\n            let mr_models = hashmap.remove(&l_pk);\n            mr_models.map(|mr_models| (l_model, consolidate_query_result::<M, R>(mr_models)))\n        })\n        .collect()\n}\n\nfn retain_unique_models_of<L, KEY: ModelKey<L>>(\n    mut rows: Vec<L::Model>,\n    model_key: KEY,\n) -> Vec<L::Model>\nwhere\n    L: EntityTrait,\n{\n    let mut seen = HashSet::new();\n\n    rows.retain(|model| seen.insert(model_key.get(model)));\n\n    rows\n}\n\n/// This is the legacy consolidate algorithm. Kept for reference\n#[allow(dead_code)]\nfn consolidate_query_result_of_ordered_rows<L, R>(\n    rows: Vec<(L::Model, Option<R::Model>)>,\n) -> Vec<(L::Model, Vec<R::Model>)>\nwhere\n    L: EntityTrait,\n    R: EntityTrait,\n{\n    let mut acc: Vec<(L::Model, Vec<R::Model>)> = Vec::new();\n    for (l, r) in rows {\n        if let Some((last_l, last_r)) = acc.last_mut() {\n            let mut same_l = true;\n            for pk_col in <L::PrimaryKey as Iterable>::iter() {\n                let col = pk_col.into_column();\n                let val = l.get(col);\n                let last_val = last_l.get(col);\n                if !val.eq(&last_val) {\n                    same_l = false;\n                    break;\n                }\n            }\n            if same_l {\n                if let Some(r) = r {\n                    last_r.push(r);\n                    continue;\n                }\n            }\n        }\n        let rows = match r {\n            Some(r) => vec![r],\n            None => vec![],\n        };\n        acc.push((l, rows));\n    }\n    acc\n}\n\n#[cfg(test)]\nmod tests {\n    use pretty_assertions::assert_eq;\n\n    fn cake_model(id: i32) -> crate::tests_cfg::cake::Model {\n        let name = match id {\n            1 => \"apple cake\",\n            2 => \"orange cake\",\n            3 => \"fruit cake\",\n            4 => \"chocolate cake\",\n            _ => \"\",\n        }\n        .to_string();\n        crate::tests_cfg::cake::Model { id, name }\n    }\n\n    fn filling_model(id: i32) -> crate::tests_cfg::filling::Model {\n        let name = match id {\n            1 => \"apple sauce\",\n            2 => \"orange jam\",\n            3 => \"fruit salad\",\n            4 => \"chocolate chips\",\n            _ => \"\",\n        }\n        .to_string();\n        crate::tests_cfg::filling::Model {\n            id,\n            name,\n            vendor_id: Some(1),\n            ignored_attr: 0,\n        }\n    }\n\n    fn fruit_model(id: i32) -> crate::tests_cfg::fruit::Model {\n        fruit_model_for(id, None)\n    }\n\n    fn fruit_model_for(id: i32, cake_id: Option<i32>) -> crate::tests_cfg::fruit::Model {\n        let name = match id {\n            1 => \"apple\",\n            2 => \"orange\",\n            3 => \"grape\",\n            4 => \"strawberry\",\n            _ => \"\",\n        }\n        .to_string();\n        crate::tests_cfg::fruit::Model { id, name, cake_id }\n    }\n\n    fn vendor_model(id: i32) -> crate::tests_cfg::vendor::Model {\n        let name = match id {\n            1 => \"Apollo\",\n            2 => \"Benny\",\n            3 => \"Christine\",\n            4 => \"David\",\n            _ => \"\",\n        }\n        .to_string();\n        crate::tests_cfg::vendor::Model { id, name }\n    }\n\n    fn cake_with_fruit(\n        cake_id: i32,\n        fruit_id: i32,\n    ) -> (\n        crate::tests_cfg::cake::Model,\n        crate::tests_cfg::fruit::Model,\n    ) {\n        (\n            cake_model(cake_id),\n            fruit_model_for(fruit_id, Some(cake_id)),\n        )\n    }\n\n    fn cake_and_filling(\n        cake_id: i32,\n        filling_id: i32,\n    ) -> (\n        crate::tests_cfg::cake::Model,\n        crate::tests_cfg::filling::Model,\n    ) {\n        (cake_model(cake_id), filling_model(filling_id))\n    }\n\n    fn cake_and_vendor(\n        cake_id: i32,\n        vendor_id: i32,\n    ) -> (\n        crate::tests_cfg::cake::Model,\n        crate::tests_cfg::vendor::Model,\n    ) {\n        (cake_model(cake_id), vendor_model(vendor_id))\n    }\n\n    #[test]\n    fn also_related() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase, Statement, Transaction};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_with_fruit(1, 1)]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_also_related(Fruit).all(&db)?,\n            [(cake_model(1), Some(fruit_model_for(1, Some(1))))]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                []\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn also_related_2() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_with_fruit(1, 1), cake_with_fruit(1, 2)]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_also_related(Fruit).all(&db)?,\n            [\n                (cake_model(1), Some(fruit_model_for(1, Some(1)))),\n                (cake_model(1), Some(fruit_model_for(2, Some(1))))\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn also_related_3() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_with_fruit(1, 1),\n                cake_with_fruit(1, 2),\n                cake_with_fruit(2, 3),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_also_related(Fruit).all(&db)?,\n            [\n                (cake_model(1), Some(fruit_model_for(1, Some(1)))),\n                (cake_model(1), Some(fruit_model_for(2, Some(1)))),\n                (cake_model(2), Some(fruit_model_for(3, Some(2))))\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn also_related_4() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_with_fruit(1, 1).into_mock_row(),\n                cake_with_fruit(1, 2).into_mock_row(),\n                cake_with_fruit(2, 3).into_mock_row(),\n                (cake_model(3), None::<fruit::Model>).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_also_related(Fruit).all(&db)?,\n            [\n                (cake_model(1), Some(fruit_model_for(1, Some(1)))),\n                (cake_model(1), Some(fruit_model_for(2, Some(1)))),\n                (cake_model(2), Some(fruit_model_for(3, Some(2)))),\n                (cake_model(3), None)\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn also_related_many_to_many() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_filling(1, 1).into_mock_row(),\n                cake_and_filling(1, 2).into_mock_row(),\n                cake_and_filling(2, 2).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_also_related(Filling).all(&db)?,\n            [\n                (cake_model(1), Some(filling_model(1))),\n                (cake_model(1), Some(filling_model(2))),\n                (cake_model(2), Some(filling_model(2))),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn also_related_many_to_many_2() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_filling(1, 1).into_mock_row(),\n                cake_and_filling(1, 2).into_mock_row(),\n                cake_and_filling(2, 2).into_mock_row(),\n                (cake_model(3), None::<filling::Model>).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_also_related(Filling).all(&db)?,\n            [\n                (cake_model(1), Some(filling_model(1))),\n                (cake_model(1), Some(filling_model(2))),\n                (cake_model(2), Some(filling_model(2))),\n                (cake_model(3), None)\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn with_related() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase, Statement, Transaction};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_with_fruit(1, 1),\n                cake_with_fruit(2, 2),\n                cake_with_fruit(2, 3),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_with_related(Fruit).all(&db)?,\n            [\n                (cake_model(1), vec![fruit_model_for(1, Some(1))]),\n                (\n                    cake_model(2),\n                    vec![fruit_model_for(2, Some(2)), fruit_model_for(3, Some(2))]\n                )\n            ]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                    r#\"ORDER BY \"cake\".\"id\" ASC\"#\n                ]\n                .join(\" \")\n                .as_str(),\n                []\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn with_related_2() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_with_fruit(1, 1).into_mock_row(),\n                cake_with_fruit(2, 2).into_mock_row(),\n                cake_with_fruit(2, 3).into_mock_row(),\n                cake_with_fruit(2, 4).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_with_related(Fruit).all(&db)?,\n            [\n                (cake_model(1), vec![fruit_model_for(1, Some(1)),]),\n                (\n                    cake_model(2),\n                    vec![\n                        fruit_model_for(2, Some(2)),\n                        fruit_model_for(3, Some(2)),\n                        fruit_model_for(4, Some(2)),\n                    ]\n                ),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn with_related_empty() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_with_fruit(1, 1).into_mock_row(),\n                cake_with_fruit(2, 2).into_mock_row(),\n                cake_with_fruit(2, 3).into_mock_row(),\n                cake_with_fruit(2, 4).into_mock_row(),\n                (cake_model(3), None::<fruit::Model>).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_with_related(Fruit).all(&db)?,\n            [\n                (cake_model(1), vec![fruit_model_for(1, Some(1)),]),\n                (\n                    cake_model(2),\n                    vec![\n                        fruit_model_for(2, Some(2)),\n                        fruit_model_for(3, Some(2)),\n                        fruit_model_for(4, Some(2)),\n                    ]\n                ),\n                (cake_model(3), vec![])\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn with_related_many_to_many() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_filling(1, 1).into_mock_row(),\n                cake_and_filling(1, 2).into_mock_row(),\n                cake_and_filling(2, 2).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_with_related(Filling).all(&db)?,\n            [\n                (cake_model(1), vec![filling_model(1), filling_model(2)]),\n                (cake_model(2), vec![filling_model(2)]),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn with_related_many_to_many_2() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_filling(1, 1).into_mock_row(),\n                cake_and_filling(1, 2).into_mock_row(),\n                cake_and_filling(2, 2).into_mock_row(),\n                (cake_model(3), None::<filling::Model>).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_with_related(Filling).all(&db)?,\n            [\n                (cake_model(1), vec![filling_model(1), filling_model(2)]),\n                (cake_model(2), vec![filling_model(2)]),\n                (cake_model(3), vec![])\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn also_linked_base() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase, Statement, Transaction};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_and_vendor(1, 1)]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)?,\n            [(cake_model(1), Some(vendor_model(1)))]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"r2\".\"id\" AS \"B_id\", \"r2\".\"name\" AS \"B_name\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"cake_filling\" AS \"r0\" ON \"cake\".\"id\" = \"r0\".\"cake_id\"\"#,\n                    r#\"LEFT JOIN \"filling\" AS \"r1\" ON \"r0\".\"filling_id\" = \"r1\".\"id\"\"#,\n                    r#\"LEFT JOIN \"vendor\" AS \"r2\" ON \"r1\".\"vendor_id\" = \"r2\".\"id\"\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                []\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn also_linked_same_cake() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1),\n                cake_and_vendor(1, 2),\n                cake_and_vendor(2, 3),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)?,\n            [\n                (cake_model(1), Some(vendor_model(1))),\n                (cake_model(1), Some(vendor_model(2))),\n                (cake_model(2), Some(vendor_model(3)))\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn also_linked_same_vendor() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(2, 1).into_mock_row(),\n                cake_and_vendor(3, 2).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)?,\n            [\n                (cake_model(1), Some(vendor_model(1))),\n                (cake_model(2), Some(vendor_model(1))),\n                (cake_model(3), Some(vendor_model(2))),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn also_linked_many_to_many() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(1, 2).into_mock_row(),\n                cake_and_vendor(1, 3).into_mock_row(),\n                cake_and_vendor(2, 1).into_mock_row(),\n                cake_and_vendor(2, 2).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)?,\n            [\n                (cake_model(1), Some(vendor_model(1))),\n                (cake_model(1), Some(vendor_model(2))),\n                (cake_model(1), Some(vendor_model(3))),\n                (cake_model(2), Some(vendor_model(1))),\n                (cake_model(2), Some(vendor_model(2))),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn also_linked_empty() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(2, 2).into_mock_row(),\n                cake_and_vendor(3, 3).into_mock_row(),\n                (cake_model(4), None::<vendor::Model>).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)?,\n            [\n                (cake_model(1), Some(vendor_model(1))),\n                (cake_model(2), Some(vendor_model(2))),\n                (cake_model(3), Some(vendor_model(3))),\n                (cake_model(4), None)\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn with_linked_base() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase, Statement, Transaction};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1),\n                cake_and_vendor(2, 2),\n                cake_and_vendor(2, 3),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_with_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)?,\n            [\n                (cake_model(1), vec![vendor_model(1)]),\n                (cake_model(2), vec![vendor_model(2), vendor_model(3)])\n            ]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"r2\".\"id\" AS \"B_id\", \"r2\".\"name\" AS \"B_name\" FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"cake_filling\" AS \"r0\" ON \"cake\".\"id\" = \"r0\".\"cake_id\"\"#,\n                    r#\"LEFT JOIN \"filling\" AS \"r1\" ON \"r0\".\"filling_id\" = \"r1\".\"id\"\"#,\n                    r#\"LEFT JOIN \"vendor\" AS \"r2\" ON \"r1\".\"vendor_id\" = \"r2\".\"id\"\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                []\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn with_linked_same_vendor() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(2, 2).into_mock_row(),\n                cake_and_vendor(3, 2).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_with_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)?,\n            [\n                (cake_model(1), vec![vendor_model(1)]),\n                (cake_model(2), vec![vendor_model(2)]),\n                (cake_model(3), vec![vendor_model(2)])\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn with_linked_empty() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(2, 1).into_mock_row(),\n                cake_and_vendor(2, 2).into_mock_row(),\n                (cake_model(3), None::<vendor::Model>).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_with_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)?,\n            [\n                (cake_model(1), vec![vendor_model(1)]),\n                (cake_model(2), vec![vendor_model(1), vendor_model(2)]),\n                (cake_model(3), vec![])\n            ]\n        );\n\n        Ok(())\n    }\n\n    // normally would not happen\n    #[test]\n    fn with_linked_repeated() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(2, 1).into_mock_row(),\n                cake_and_vendor(2, 2).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_with_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)?,\n            [\n                (cake_model(1), vec![vendor_model(1), vendor_model(1)]),\n                (cake_model(2), vec![vendor_model(1), vendor_model(2)]),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_retain_unique_models() {\n        use crate::tests_cfg::Cake;\n        assert_eq!(\n            super::retain_unique_models::<Cake>(vec![\n                cake_model(1),\n                cake_model(1),\n                cake_model(2),\n                cake_model(2),\n                cake_model(3),\n            ]),\n            [cake_model(1), cake_model(2), cake_model(3)]\n        );\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_consolidate_tee() {\n        use crate::tests_cfg::{Cake, Filling, Fruit};\n\n        assert_eq!(\n            super::consolidate_query_result_tee::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n            ]),\n            vec![(cake_model(1), vec![fruit_model(1)], vec![filling_model(1)])]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_tee::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), None),\n            ]),\n            vec![(cake_model(1), vec![fruit_model(1)], vec![])]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_tee::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), None, Some(filling_model(1))),\n            ]),\n            vec![(cake_model(1), vec![], vec![filling_model(1)])]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_tee::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![fruit_model(1)],\n                vec![filling_model(1), filling_model(2)]\n            )]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_tee::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(3))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(3))),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![fruit_model(1), fruit_model(2)],\n                vec![filling_model(1), filling_model(2), filling_model(3)]\n            )]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_tee::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(3))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(3))),\n                (cake_model(2), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(2), Some(fruit_model(2)), Some(filling_model(2))),\n                (cake_model(3), Some(fruit_model(3)), None),\n                (cake_model(4), None, None),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![fruit_model(1), fruit_model(2)],\n                vec![filling_model(1), filling_model(2), filling_model(3)]\n            ), (\n                cake_model(2),\n                vec![fruit_model(1), fruit_model(2)],\n                vec![filling_model(2)]\n            ), (\n                cake_model(3),\n                vec![fruit_model(3)],\n                vec![]\n            ), (\n                cake_model(4),\n                vec![],\n                vec![]\n            )]\n        );\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_consolidate_chain() {\n        use crate::tests_cfg::{Cake, Filling, Fruit};\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n            ]),\n            vec![(cake_model(1), vec![(fruit_model(1), vec![filling_model(1)])])]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), None),\n            ]),\n            vec![(cake_model(1), vec![(fruit_model(1), vec![])])]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), None, None),\n            ]),\n            vec![(cake_model(1), vec![])]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![(fruit_model(1), vec![filling_model(1), filling_model(2)])]\n            )]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(3))),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![(fruit_model(1), vec![filling_model(1), filling_model(2), filling_model(3)])]\n            )]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(3))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(3))),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![\n                    (fruit_model(1), vec![filling_model(1), filling_model(2), filling_model(3)]),\n                    (fruit_model(2), vec![filling_model(2), filling_model(3)]),\n                ]\n            )]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(3))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(3))),\n                (cake_model(2), Some(fruit_model(3)), Some(filling_model(4))),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![\n                    (fruit_model(1), vec![filling_model(1), filling_model(2), filling_model(3)]),\n                    (fruit_model(2), vec![filling_model(2), filling_model(3)]),\n                ]\n            ), (\n                cake_model(2),\n                vec![(fruit_model(3), vec![filling_model(4)])]\n            )]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(3))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(3))),\n                (cake_model(2), Some(fruit_model(3)), Some(filling_model(3))),\n                (cake_model(2), Some(fruit_model(3)), Some(filling_model(4))),\n                (cake_model(3), Some(fruit_model(4)), None),\n                (cake_model(4), None, None),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![\n                    (fruit_model(1), vec![filling_model(1), filling_model(2), filling_model(3)]),\n                    (fruit_model(2), vec![filling_model(2), filling_model(3)]),\n                ]\n            ), (\n                cake_model(2),\n                vec![(fruit_model(3), vec![filling_model(3), filling_model(4)])]\n            ), (\n                cake_model(3),\n                vec![(fruit_model(4), vec![])]\n            ), (\n                cake_model(4),\n                vec![]\n            )]\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/cursor.rs",
    "content": "use crate::{\n    ConnectionTrait, DbErr, EntityTrait, FromQueryResult, Identity, IdentityOf, IntoIdentity,\n    PartialModelTrait, PrimaryKeyToColumn, QuerySelect, Select, SelectModel, SelectThree,\n    SelectThreeModel, SelectTwo, SelectTwoModel, SelectorTrait, Topology,\n};\nuse sea_query::{\n    Condition, DynIden, Expr, ExprTrait, IntoValueTuple, Order, SeaRc, SelectStatement, SimpleExpr,\n    Value, ValueTuple,\n};\nuse std::marker::PhantomData;\nuse strum::IntoEnumIterator as Iterable;\n\n#[cfg(feature = \"with-json\")]\nuse crate::JsonValue;\n\n/// Cursor pagination\n#[derive(Debug, Clone)]\npub struct Cursor<S>\nwhere\n    S: SelectorTrait,\n{\n    query: SelectStatement,\n    table: DynIden,\n    order_columns: Identity,\n    secondary_order_by: Vec<(DynIden, Identity)>,\n    first: Option<u64>,\n    last: Option<u64>,\n    before: Option<ValueTuple>,\n    after: Option<ValueTuple>,\n    sort_asc: bool,\n    is_result_reversed: bool,\n    phantom: PhantomData<S>,\n}\n\nimpl<S> Cursor<S>\nwhere\n    S: SelectorTrait,\n{\n    pub(crate) fn new<C>(query: SelectStatement, table: DynIden, order_columns: C) -> Self\n    where\n        C: IntoIdentity,\n    {\n        Self {\n            query,\n            table,\n            order_columns: order_columns.into_identity(),\n            secondary_order_by: Default::default(),\n            last: None,\n            first: None,\n            after: None,\n            before: None,\n            sort_asc: true,\n            is_result_reversed: false,\n            phantom: PhantomData,\n        }\n    }\n\n    /// Filter paginated result with corresponding column less than the input value\n    pub fn before<V>(&mut self, values: V) -> &mut Self\n    where\n        V: IntoValueTuple,\n    {\n        self.before = Some(values.into_value_tuple());\n        self\n    }\n\n    /// Filter paginated result with corresponding column greater than the input value\n    pub fn after<V>(&mut self, values: V) -> &mut Self\n    where\n        V: IntoValueTuple,\n    {\n        self.after = Some(values.into_value_tuple());\n        self\n    }\n\n    fn apply_filters(&mut self) -> Result<&mut Self, DbErr> {\n        if let Some(values) = self.after.clone() {\n            if self.order_columns.arity() != values.arity() {\n                return Err(DbErr::KeyArityMismatch {\n                    expected: self.order_columns.arity() as u8,\n                    received: values.arity() as u8,\n                });\n            }\n            let condition = self.apply_filter(values, |c, v| {\n                let exp = Expr::col((self.table.clone(), c.clone()));\n                if self.sort_asc { exp.gt(v) } else { exp.lt(v) }\n            });\n            self.query.cond_where(condition);\n        }\n\n        if let Some(values) = self.before.clone() {\n            if self.order_columns.arity() != values.arity() {\n                return Err(DbErr::KeyArityMismatch {\n                    expected: self.order_columns.arity() as u8,\n                    received: values.arity() as u8,\n                });\n            }\n            let condition = self.apply_filter(values, |c, v| {\n                let exp = Expr::col((self.table.clone(), c.clone()));\n                if self.sort_asc { exp.lt(v) } else { exp.gt(v) }\n            });\n            self.query.cond_where(condition);\n        }\n\n        Ok(self)\n    }\n\n    fn apply_filter<F>(&self, values: ValueTuple, f: F) -> Condition\n    where\n        F: Fn(&DynIden, Value) -> SimpleExpr,\n    {\n        match (&self.order_columns, values) {\n            (Identity::Unary(c1), ValueTuple::One(v1)) => Condition::all().add(f(c1, v1)),\n            (Identity::Binary(c1, c2), ValueTuple::Two(v1, v2)) => Condition::any()\n                .add(\n                    Condition::all()\n                        .add(Expr::col((self.table.clone(), c1.clone())).eq(v1.clone()))\n                        .add(f(c2, v2)),\n                )\n                .add(f(c1, v1)),\n            (Identity::Ternary(c1, c2, c3), ValueTuple::Three(v1, v2, v3)) => Condition::any()\n                .add(\n                    Condition::all()\n                        .add(Expr::col((self.table.clone(), c1.clone())).eq(v1.clone()))\n                        .add(Expr::col((self.table.clone(), c2.clone())).eq(v2.clone()))\n                        .add(f(c3, v3)),\n                )\n                .add(\n                    Condition::all()\n                        .add(Expr::col((self.table.clone(), c1.clone())).eq(v1.clone()))\n                        .add(f(c2, v2)),\n                )\n                .add(f(c1, v1)),\n            (Identity::Many(col_vec), ValueTuple::Many(val_vec))\n                if col_vec.len() == val_vec.len() =>\n            {\n                // The length of `col_vec` and `val_vec` should be equal and is denoted by \"n\".\n                //\n                // The elements of `col_vec` and `val_vec` are denoted by:\n                //   - `col_vec`: \"col_1\", \"col_2\", ..., \"col_n-1\", \"col_n\"\n                //   - `val_vec`: \"val_1\", \"val_2\", ..., \"val_n-1\", \"val_n\"\n                //\n                // The general form of the where condition should have \"n\" number of inner-AND-condition chained by an outer-OR-condition.\n                // The \"n\"-th inner-AND-condition should have exactly \"n\" number of column value expressions,\n                // to construct the expression we take the first \"n\" number of column and value from the respected vector.\n                //   - if it's not the last element, then we construct a \"col_1 = val_1\" equal expression\n                //   - otherwise, for the last element, we should construct a \"col_n > val_n\" greater than or \"col_n < val_n\" less than expression.\n                // i.e.\n                // WHERE\n                //   (col_1 = val_1 AND col_2 = val_2 AND ... AND col_n > val_n)\n                //   OR (col_1 = val_1 AND col_2 = val_2 AND ... AND col_n-1 > val_n-1)\n                //   OR (col_1 = val_1 AND col_2 = val_2 AND ... AND col_n-2 > val_n-2)\n                //   OR ...\n                //   OR (col_1 = val_1 AND col_2 > val_2)\n                //   OR (col_1 > val_1)\n\n                // Counting from 1 to \"n\" (inclusive) but in reverse, i.e. n, n-1, ..., 2, 1\n                (1..=col_vec.len())\n                    .rev()\n                    .fold(Condition::any(), |cond_any, n| {\n                        // Construct the inner-AND-condition\n                        let inner_cond_all =\n                            // Take the first \"n\" elements from the column and value vector respectively\n                            col_vec.iter().zip(val_vec.iter()).enumerate().take(n).fold(\n                                Condition::all(),\n                                |inner_cond_all, (i, (col, val))| {\n                                    let val = val.clone();\n                                    // Construct a equal expression,\n                                    // except for the last one being greater than or less than expression\n                                    let expr = if i != (n - 1) {\n                                        Expr::col((self.table.clone(), col.clone()))\n                                            .eq(val)\n                                    } else {\n                                        f(col, val)\n                                    };\n                                    // Chain it with AND operator\n                                    inner_cond_all.add(expr)\n                                },\n                            );\n                        // Chain inner-AND-condition with OR operator\n                        cond_any.add(inner_cond_all)\n                    })\n            }\n            _ => unreachable!(\"checked by caller\"),\n        }\n    }\n\n    /// Use ascending sort order\n    pub fn asc(&mut self) -> &mut Self {\n        self.sort_asc = true;\n        self\n    }\n\n    /// Use descending sort order\n    pub fn desc(&mut self) -> &mut Self {\n        self.sort_asc = false;\n        self\n    }\n\n    /// Limit result set to only first N rows in ascending order of the order by column\n    pub fn first(&mut self, num_rows: u64) -> &mut Self {\n        self.last = None;\n        self.first = Some(num_rows);\n        self\n    }\n\n    /// Limit result set to only last N rows in ascending order of the order by column\n    pub fn last(&mut self, num_rows: u64) -> &mut Self {\n        self.first = None;\n        self.last = Some(num_rows);\n        self\n    }\n\n    fn resolve_sort_order(&mut self) -> Order {\n        let should_reverse_order = self.last.is_some();\n        self.is_result_reversed = should_reverse_order;\n\n        if (self.sort_asc && !should_reverse_order) || (!self.sort_asc && should_reverse_order) {\n            Order::Asc\n        } else {\n            Order::Desc\n        }\n    }\n\n    fn apply_limit(&mut self) -> &mut Self {\n        if let Some(num_rows) = self.first {\n            self.query.limit(num_rows);\n        } else if let Some(num_rows) = self.last {\n            self.query.limit(num_rows);\n        }\n\n        self\n    }\n\n    fn apply_order_by(&mut self) -> &mut Self {\n        self.query.clear_order_by();\n        let ord = self.resolve_sort_order();\n\n        let query = &mut self.query;\n        let order = |query: &mut SelectStatement, col: &DynIden| {\n            query.order_by((self.table.clone(), col.clone()), ord.clone());\n        };\n        match &self.order_columns {\n            Identity::Unary(c1) => {\n                order(query, c1);\n            }\n            Identity::Binary(c1, c2) => {\n                order(query, c1);\n                order(query, c2);\n            }\n            Identity::Ternary(c1, c2, c3) => {\n                order(query, c1);\n                order(query, c2);\n                order(query, c3);\n            }\n            Identity::Many(vec) => {\n                for col in vec.iter() {\n                    order(query, col);\n                }\n            }\n        }\n\n        for (tbl, col) in self.secondary_order_by.iter().cloned() {\n            if let Identity::Unary(c1) = col {\n                query.order_by((tbl, c1), ord.clone());\n            }\n        }\n\n        self\n    }\n\n    /// Fetch the paginated result\n    pub fn all<C>(&mut self, db: &C) -> Result<Vec<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.apply_limit();\n        self.apply_order_by();\n        self.apply_filters()?;\n\n        let rows = db.query_all(&self.query)?;\n        let mut buffer = Vec::with_capacity(rows.len());\n        for row in rows.into_iter() {\n            buffer.push(S::from_raw_query_result(row)?);\n        }\n        if self.is_result_reversed {\n            buffer.reverse()\n        }\n        Ok(buffer)\n    }\n\n    /// Construct a [Cursor] that fetch any custom struct\n    pub fn into_model<M>(self) -> Cursor<SelectModel<M>>\n    where\n        M: FromQueryResult,\n    {\n        Cursor {\n            query: self.query,\n            table: self.table,\n            order_columns: self.order_columns,\n            secondary_order_by: self.secondary_order_by,\n            last: self.last,\n            first: self.first,\n            after: self.after,\n            before: self.before,\n            sort_asc: self.sort_asc,\n            is_result_reversed: self.is_result_reversed,\n            phantom: PhantomData,\n        }\n    }\n\n    /// Return a [Selector] from `Self` that wraps a [SelectModel] with a [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M>(self) -> Cursor<SelectModel<M>>\n    where\n        M: PartialModelTrait,\n    {\n        M::select_cols(QuerySelect::select_only(self)).into_model::<M>()\n    }\n\n    /// Construct a [Cursor] that fetch JSON value\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(self) -> Cursor<SelectModel<JsonValue>> {\n        Cursor {\n            query: self.query,\n            table: self.table,\n            order_columns: self.order_columns,\n            secondary_order_by: self.secondary_order_by,\n            last: self.last,\n            first: self.first,\n            after: self.after,\n            before: self.before,\n            sort_asc: self.sort_asc,\n            is_result_reversed: self.is_result_reversed,\n            phantom: PhantomData,\n        }\n    }\n\n    /// Set the cursor ordering for another table when dealing with SelectTwo\n    pub fn set_secondary_order_by(&mut self, tbl_col: Vec<(DynIden, Identity)>) -> &mut Self {\n        self.secondary_order_by = tbl_col;\n        self\n    }\n}\n\nimpl<S> QuerySelect for Cursor<S>\nwhere\n    S: SelectorTrait,\n{\n    type QueryStatement = SelectStatement;\n\n    fn query(&mut self) -> &mut SelectStatement {\n        &mut self.query\n    }\n}\n\n/// A trait for any type that can be turn into a cursor\npub trait CursorTrait {\n    /// Select operation\n    type Selector: SelectorTrait;\n}\n\nimpl<E, M> CursorTrait for Select<E>\nwhere\n    E: EntityTrait<Model = M>,\n    M: FromQueryResult + Sized,\n{\n    type Selector = SelectModel<M>;\n}\n\nimpl<E, M> Select<E>\nwhere\n    E: EntityTrait<Model = M>,\n    M: FromQueryResult + Sized,\n{\n    /// Convert into a cursor\n    pub fn cursor_by<C>(self, order_columns: C) -> Cursor<SelectModel<M>>\n    where\n        C: IntoIdentity,\n    {\n        Cursor::new(self.query, SeaRc::new(E::default()), order_columns)\n    }\n}\n\nimpl<E, F, M, N> CursorTrait for SelectTwo<E, F>\nwhere\n    E: EntityTrait<Model = M>,\n    F: EntityTrait<Model = N>,\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n{\n    type Selector = SelectTwoModel<M, N>;\n}\n\nimpl<E, F, G, M, N, O, TOP> CursorTrait for SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait<Model = M>,\n    F: EntityTrait<Model = N>,\n    G: EntityTrait<Model = O>,\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n    O: FromQueryResult + Sized,\n    TOP: Topology,\n{\n    type Selector = SelectThreeModel<M, N, O>;\n}\n\nimpl<E, F, M, N> SelectTwo<E, F>\nwhere\n    E: EntityTrait<Model = M>,\n    F: EntityTrait<Model = N>,\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n{\n    /// Convert into a cursor using column of first entity\n    pub fn cursor_by<C>(self, order_columns: C) -> Cursor<SelectTwoModel<M, N>>\n    where\n        C: IdentityOf<E>,\n    {\n        let primary_keys: Vec<(DynIden, Identity)> = <F::PrimaryKey as Iterable>::iter()\n            .map(|pk| {\n                (\n                    SeaRc::new(F::default()),\n                    Identity::Unary(SeaRc::new(pk.into_column())),\n                )\n            })\n            .collect();\n        let mut cursor = Cursor::new(\n            self.query,\n            SeaRc::new(E::default()),\n            order_columns.identity_of(),\n        );\n        cursor.set_secondary_order_by(primary_keys);\n        cursor\n    }\n\n    /// Convert into a cursor using column of second entity\n    pub fn cursor_by_other<C>(self, order_columns: C) -> Cursor<SelectTwoModel<M, N>>\n    where\n        C: IdentityOf<F>,\n    {\n        let primary_keys: Vec<(DynIden, Identity)> = <E::PrimaryKey as Iterable>::iter()\n            .map(|pk| {\n                (\n                    SeaRc::new(E::default()),\n                    Identity::Unary(SeaRc::new(pk.into_column())),\n                )\n            })\n            .collect();\n        let mut cursor = Cursor::new(\n            self.query,\n            SeaRc::new(F::default()),\n            order_columns.identity_of(),\n        );\n        cursor.set_secondary_order_by(primary_keys);\n        cursor\n    }\n}\n\nimpl<E, F, G, M, N, O, TOP> SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait<Model = M>,\n    F: EntityTrait<Model = N>,\n    G: EntityTrait<Model = O>,\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n    O: FromQueryResult + Sized,\n    TOP: Topology,\n{\n    /// Convert into a cursor using column of first entity\n    pub fn cursor_by<C>(self, order_columns: C) -> Cursor<SelectThreeModel<M, N, O>>\n    where\n        C: IdentityOf<E>,\n    {\n        let mut cursor = Cursor::new(\n            self.query,\n            SeaRc::new(E::default()),\n            order_columns.identity_of(),\n        );\n        {\n            let primary_keys: Vec<(DynIden, Identity)> = <F::PrimaryKey as Iterable>::iter()\n                .map(|pk| {\n                    (\n                        SeaRc::new(F::default()),\n                        Identity::Unary(SeaRc::new(pk.into_column())),\n                    )\n                })\n                .collect();\n            cursor.set_secondary_order_by(primary_keys);\n        }\n        {\n            let primary_keys: Vec<(DynIden, Identity)> = <G::PrimaryKey as Iterable>::iter()\n                .map(|pk| {\n                    (\n                        SeaRc::new(G::default()),\n                        Identity::Unary(SeaRc::new(pk.into_column())),\n                    )\n                })\n                .collect();\n            cursor.set_secondary_order_by(primary_keys);\n        }\n        cursor\n    }\n}\n\n#[cfg(test)]\n#[cfg(feature = \"mock\")]\nmod tests {\n    use crate::entity::prelude::*;\n    use crate::tests_cfg::*;\n    use crate::{DbBackend, MockDatabase, Statement, Transaction};\n    use pretty_assertions::assert_eq;\n\n    #[test]\n    fn first_2_before_10() -> Result<(), DbErr> {\n        use fruit::*;\n\n        let models = [\n            Model {\n                id: 1,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            },\n            Model {\n                id: 2,\n                name: \"Raspberry\".into(),\n                cake_id: Some(1),\n            },\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            Entity::find()\n                .cursor_by(Column::Id)\n                .before(10)\n                .first(2)\n                .all(&db)?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\"\"#,\n                    r#\"FROM \"fruit\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" < $1\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" ASC\"#,\n                    r#\"LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn last_2_after_10_desc() -> Result<(), DbErr> {\n        use fruit::*;\n\n        let mut models = [\n            Model {\n                id: 1,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            },\n            Model {\n                id: 2,\n                name: \"Raspberry\".into(),\n                cake_id: Some(1),\n            },\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        models.reverse();\n\n        assert_eq!(\n            Entity::find()\n                .cursor_by(Column::Id)\n                .after(10)\n                .last(2)\n                .desc()\n                .all(&db)?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\"\"#,\n                    r#\"FROM \"fruit\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" < $1\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" ASC\"#,\n                    r#\"LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn first_2_before_10_also_related_select() -> Result<(), DbErr> {\n        let models = [\n            (\n                cake::Model {\n                    id: 1,\n                    name: \"Blueberry Cheese Cake\".into(),\n                },\n                Some(fruit::Model {\n                    id: 9,\n                    name: \"Blueberry\".into(),\n                    cake_id: Some(1),\n                }),\n            ),\n            (\n                cake::Model {\n                    id: 2,\n                    name: \"Raspberry Cheese Cake\".into(),\n                },\n                Some(fruit::Model {\n                    id: 10,\n                    name: \"Raspberry\".into(),\n                    cake_id: Some(1),\n                }),\n            ),\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_related(Fruit)\n                .cursor_by(cake::Column::Id)\n                .before(10)\n                .first(2)\n                .all(&db)?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                    r#\"WHERE \"cake\".\"id\" < $1\"#,\n                    r#\"ORDER BY \"cake\".\"id\" ASC, \"fruit\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn last_2_after_10_also_related_select_desc() -> Result<(), DbErr> {\n        let mut models = [\n            (\n                cake::Model {\n                    id: 2,\n                    name: \"Raspberry Cheese Cake\".into(),\n                },\n                Some(fruit::Model {\n                    id: 10,\n                    name: \"Raspberry\".into(),\n                    cake_id: Some(1),\n                }),\n            ),\n            (\n                cake::Model {\n                    id: 1,\n                    name: \"Blueberry Cheese Cake\".into(),\n                },\n                Some(fruit::Model {\n                    id: 9,\n                    name: \"Blueberry\".into(),\n                    cake_id: Some(1),\n                }),\n            ),\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        models.reverse();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_related(Fruit)\n                .cursor_by(cake::Column::Id)\n                .after(10)\n                .last(2)\n                .desc()\n                .all(&db)?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                    r#\"WHERE \"cake\".\"id\" < $1\"#,\n                    r#\"ORDER BY \"cake\".\"id\" ASC, \"fruit\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn first_2_before_10_also_related_select_cursor_other() -> Result<(), DbErr> {\n        let models = [(\n            cake::Model {\n                id: 1,\n                name: \"Blueberry Cheese Cake\".into(),\n            },\n            Some(fruit::Model {\n                id: 9,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            }),\n        )];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_related(Fruit)\n                .cursor_by_other(fruit::Column::Id)\n                .before(10)\n                .first(2)\n                .all(&db)?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" < $1\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" ASC, \"cake\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn last_2_after_10_also_related_select_cursor_other_desc() -> Result<(), DbErr> {\n        let models = [(\n            cake::Model {\n                id: 1,\n                name: \"Blueberry Cheese Cake\".into(),\n            },\n            Some(fruit::Model {\n                id: 9,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            }),\n        )];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_related(Fruit)\n                .cursor_by_other(fruit::Column::Id)\n                .after(10)\n                .last(2)\n                .desc()\n                .all(&db)?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" < $1\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" ASC, \"cake\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn first_2_before_10_also_linked_select() -> Result<(), DbErr> {\n        let models = [\n            (\n                cake::Model {\n                    id: 1,\n                    name: \"Blueberry Cheese Cake\".into(),\n                },\n                Some(vendor::Model {\n                    id: 9,\n                    name: \"Blueberry\".into(),\n                }),\n            ),\n            (\n                cake::Model {\n                    id: 2,\n                    name: \"Raspberry Cheese Cake\".into(),\n                },\n                Some(vendor::Model {\n                    id: 10,\n                    name: \"Raspberry\".into(),\n                }),\n            ),\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .cursor_by(cake::Column::Id)\n                .before(10)\n                .first(2)\n                .all(&db)?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"r2\".\"id\" AS \"B_id\", \"r2\".\"name\" AS \"B_name\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"cake_filling\" AS \"r0\" ON \"cake\".\"id\" = \"r0\".\"cake_id\"\"#,\n                    r#\"LEFT JOIN \"filling\" AS \"r1\" ON \"r0\".\"filling_id\" = \"r1\".\"id\"\"#,\n                    r#\"LEFT JOIN \"vendor\" AS \"r2\" ON \"r1\".\"vendor_id\" = \"r2\".\"id\"\"#,\n                    r#\"WHERE \"cake\".\"id\" < $1 ORDER BY \"cake\".\"id\" ASC, \"vendor\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn last_2_after_10_also_linked_select_desc() -> Result<(), DbErr> {\n        let mut models = [\n            (\n                cake::Model {\n                    id: 2,\n                    name: \"Raspberry Cheese Cake\".into(),\n                },\n                Some(vendor::Model {\n                    id: 10,\n                    name: \"Raspberry\".into(),\n                }),\n            ),\n            (\n                cake::Model {\n                    id: 1,\n                    name: \"Blueberry Cheese Cake\".into(),\n                },\n                Some(vendor::Model {\n                    id: 9,\n                    name: \"Blueberry\".into(),\n                }),\n            ),\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        models.reverse();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .cursor_by(cake::Column::Id)\n                .after(10)\n                .last(2)\n                .desc()\n                .all(&db)?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"r2\".\"id\" AS \"B_id\", \"r2\".\"name\" AS \"B_name\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"cake_filling\" AS \"r0\" ON \"cake\".\"id\" = \"r0\".\"cake_id\"\"#,\n                    r#\"LEFT JOIN \"filling\" AS \"r1\" ON \"r0\".\"filling_id\" = \"r1\".\"id\"\"#,\n                    r#\"LEFT JOIN \"vendor\" AS \"r2\" ON \"r1\".\"vendor_id\" = \"r2\".\"id\"\"#,\n                    r#\"WHERE \"cake\".\"id\" < $1 ORDER BY \"cake\".\"id\" ASC, \"vendor\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn first_2_before_10_also_linked_select_cursor_other() -> Result<(), DbErr> {\n        let models = [(\n            cake::Model {\n                id: 1,\n                name: \"Blueberry Cheese Cake\".into(),\n            },\n            Some(vendor::Model {\n                id: 9,\n                name: \"Blueberry\".into(),\n            }),\n        )];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .cursor_by_other(vendor::Column::Id)\n                .before(10)\n                .first(2)\n                .all(&db)?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"r2\".\"id\" AS \"B_id\", \"r2\".\"name\" AS \"B_name\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"cake_filling\" AS \"r0\" ON \"cake\".\"id\" = \"r0\".\"cake_id\"\"#,\n                    r#\"LEFT JOIN \"filling\" AS \"r1\" ON \"r0\".\"filling_id\" = \"r1\".\"id\"\"#,\n                    r#\"LEFT JOIN \"vendor\" AS \"r2\" ON \"r1\".\"vendor_id\" = \"r2\".\"id\"\"#,\n                    r#\"WHERE \"vendor\".\"id\" < $1 ORDER BY \"vendor\".\"id\" ASC, \"cake\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn last_2_after_10_also_linked_select_cursor_other_desc() -> Result<(), DbErr> {\n        let mut models = [(\n            cake::Model {\n                id: 1,\n                name: \"Blueberry Cheese Cake\".into(),\n            },\n            Some(vendor::Model {\n                id: 9,\n                name: \"Blueberry\".into(),\n            }),\n        )];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        models.reverse();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .cursor_by_other(vendor::Column::Id)\n                .after(10)\n                .last(2)\n                .desc()\n                .all(&db)?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"r2\".\"id\" AS \"B_id\", \"r2\".\"name\" AS \"B_name\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"cake_filling\" AS \"r0\" ON \"cake\".\"id\" = \"r0\".\"cake_id\"\"#,\n                    r#\"LEFT JOIN \"filling\" AS \"r1\" ON \"r0\".\"filling_id\" = \"r1\".\"id\"\"#,\n                    r#\"LEFT JOIN \"vendor\" AS \"r2\" ON \"r1\".\"vendor_id\" = \"r2\".\"id\"\"#,\n                    r#\"WHERE \"vendor\".\"id\" < $1 ORDER BY \"vendor\".\"id\" ASC, \"cake\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn last_2_after_10() -> Result<(), DbErr> {\n        use fruit::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                Model {\n                    id: 22,\n                    name: \"Raspberry\".into(),\n                    cake_id: Some(1),\n                },\n                Model {\n                    id: 21,\n                    name: \"Blueberry\".into(),\n                    cake_id: Some(1),\n                },\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Entity::find()\n                .cursor_by(Column::Id)\n                .after(10)\n                .last(2)\n                .all(&db)?,\n            [\n                Model {\n                    id: 21,\n                    name: \"Blueberry\".into(),\n                    cake_id: Some(1),\n                },\n                Model {\n                    id: 22,\n                    name: \"Raspberry\".into(),\n                    cake_id: Some(1),\n                },\n            ]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\"\"#,\n                    r#\"FROM \"fruit\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" > $1\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" DESC\"#,\n                    r#\"LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn first_2_before_10_desc() -> Result<(), DbErr> {\n        use fruit::*;\n\n        let models = [\n            Model {\n                id: 22,\n                name: \"Raspberry\".into(),\n                cake_id: Some(1),\n            },\n            Model {\n                id: 21,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            },\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            Entity::find()\n                .cursor_by(Column::Id)\n                .before(10)\n                .first(2)\n                .desc()\n                .all(&db)?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\"\"#,\n                    r#\"FROM \"fruit\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" > $1\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" DESC\"#,\n                    r#\"LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn last_2_after_25_before_30() -> Result<(), DbErr> {\n        use fruit::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                Model {\n                    id: 27,\n                    name: \"Raspberry\".into(),\n                    cake_id: Some(1),\n                },\n                Model {\n                    id: 26,\n                    name: \"Blueberry\".into(),\n                    cake_id: Some(1),\n                },\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Entity::find()\n                .cursor_by(Column::Id)\n                .after(25)\n                .before(30)\n                .last(2)\n                .all(&db)?,\n            [\n                Model {\n                    id: 26,\n                    name: \"Blueberry\".into(),\n                    cake_id: Some(1),\n                },\n                Model {\n                    id: 27,\n                    name: \"Raspberry\".into(),\n                    cake_id: Some(1),\n                },\n            ]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\"\"#,\n                    r#\"FROM \"fruit\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" > $1\"#,\n                    r#\"AND \"fruit\".\"id\" < $2\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" DESC\"#,\n                    r#\"LIMIT $3\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [25_i32.into(), 30_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn first_2_after_30_before_25_desc() -> Result<(), DbErr> {\n        use fruit::*;\n\n        let models = [\n            Model {\n                id: 27,\n                name: \"Raspberry\".into(),\n                cake_id: Some(1),\n            },\n            Model {\n                id: 26,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            },\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            Entity::find()\n                .cursor_by(Column::Id)\n                .after(30)\n                .before(25)\n                .first(2)\n                .desc()\n                .all(&db)?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\"\"#,\n                    r#\"FROM \"fruit\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" < $1\"#,\n                    r#\"AND \"fruit\".\"id\" > $2\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" DESC\"#,\n                    r#\"LIMIT $3\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [30_i32.into(), 25_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    mod test_entity {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"example\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(primary_key)]\n            pub category: String,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    mod xyz_entity {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"m\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub x: i32,\n            #[sea_orm(primary_key)]\n            pub y: String,\n            #[sea_orm(primary_key)]\n            pub z: i64,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn composite_keys_1() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::Category, Column::Id))\n                .first(3)\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"example\".\"id\", \"example\".\"category\"\"#,\n                    r#\"FROM \"example\"\"#,\n                    r#\"ORDER BY \"example\".\"category\" ASC, \"example\".\"id\" ASC\"#,\n                    r#\"LIMIT $1\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [3_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn composite_keys_1_desc() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::Category, Column::Id))\n                .last(3)\n                .desc()\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"example\".\"id\", \"example\".\"category\"\"#,\n                    r#\"FROM \"example\"\"#,\n                    r#\"ORDER BY \"example\".\"category\" ASC, \"example\".\"id\" ASC\"#,\n                    r#\"LIMIT $1\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [3_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn composite_keys_2() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::Category, Column::Id))\n                .after((\"A\".to_owned(), 2))\n                .first(3)\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"example\".\"id\", \"example\".\"category\"\"#,\n                    r#\"FROM \"example\"\"#,\n                    r#\"WHERE (\"example\".\"category\" = $1 AND \"example\".\"id\" > $2)\"#,\n                    r#\"OR \"example\".\"category\" > $3\"#,\n                    r#\"ORDER BY \"example\".\"category\" ASC, \"example\".\"id\" ASC\"#,\n                    r#\"LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    \"A\".to_string().into(),\n                    2i32.into(),\n                    \"A\".to_string().into(),\n                    3_u64.into(),\n                ]\n            )])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn composite_keys_error() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        let result = Entity::find()\n            .cursor_by((Column::Category, Column::Id))\n            .after(\"A\".to_owned())\n            .first(3)\n            .all(&db);\n\n        assert!(matches!(\n            result,\n            Err(DbErr::KeyArityMismatch {\n                expected: 2,\n                received: 1,\n            })\n        ));\n\n        Ok(())\n    }\n\n    #[test]\n    fn composite_keys_2_desc() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::Category, Column::Id))\n                .before((\"A\".to_owned(), 2))\n                .last(3)\n                .desc()\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"example\".\"id\", \"example\".\"category\"\"#,\n                    r#\"FROM \"example\"\"#,\n                    r#\"WHERE (\"example\".\"category\" = $1 AND \"example\".\"id\" > $2)\"#,\n                    r#\"OR \"example\".\"category\" > $3\"#,\n                    r#\"ORDER BY \"example\".\"category\" ASC, \"example\".\"id\" ASC\"#,\n                    r#\"LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    \"A\".to_string().into(),\n                    2i32.into(),\n                    \"A\".to_string().into(),\n                    3_u64.into(),\n                ]\n            )])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn composite_keys_3() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::Category, Column::Id))\n                .before((\"A\".to_owned(), 2))\n                .last(3)\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"example\".\"id\", \"example\".\"category\"\"#,\n                    r#\"FROM \"example\"\"#,\n                    r#\"WHERE (\"example\".\"category\" = $1 AND \"example\".\"id\" < $2)\"#,\n                    r#\"OR \"example\".\"category\" < $3\"#,\n                    r#\"ORDER BY \"example\".\"category\" DESC, \"example\".\"id\" DESC\"#,\n                    r#\"LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    \"A\".to_string().into(),\n                    2i32.into(),\n                    \"A\".to_string().into(),\n                    3_u64.into(),\n                ]\n            )])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn composite_keys_3_desc() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::Category, Column::Id))\n                .after((\"A\".to_owned(), 2))\n                .first(3)\n                .desc()\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"example\".\"id\", \"example\".\"category\"\"#,\n                    r#\"FROM \"example\"\"#,\n                    r#\"WHERE (\"example\".\"category\" = $1 AND \"example\".\"id\" < $2)\"#,\n                    r#\"OR \"example\".\"category\" < $3\"#,\n                    r#\"ORDER BY \"example\".\"category\" DESC, \"example\".\"id\" DESC\"#,\n                    r#\"LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    \"A\".to_string().into(),\n                    2i32.into(),\n                    \"A\".to_string().into(),\n                    3_u64.into(),\n                ]\n            )])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn composite_keys_4() -> Result<(), DbErr> {\n        use xyz_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                x: 'x' as i32,\n                y: \"y\".into(),\n                z: 'z' as i64,\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::X, Column::Y, Column::Z))\n                .first(4)\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"m\".\"x\", \"m\".\"y\", \"m\".\"z\"\"#,\n                    r#\"FROM \"m\"\"#,\n                    r#\"ORDER BY \"m\".\"x\" ASC, \"m\".\"y\" ASC, \"m\".\"z\" ASC\"#,\n                    r#\"LIMIT $1\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [4_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn composite_keys_4_desc() -> Result<(), DbErr> {\n        use xyz_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                x: 'x' as i32,\n                y: \"y\".into(),\n                z: 'z' as i64,\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::X, Column::Y, Column::Z))\n                .last(4)\n                .desc()\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"m\".\"x\", \"m\".\"y\", \"m\".\"z\"\"#,\n                    r#\"FROM \"m\"\"#,\n                    r#\"ORDER BY \"m\".\"x\" ASC, \"m\".\"y\" ASC, \"m\".\"z\" ASC\"#,\n                    r#\"LIMIT $1\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [4_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn composite_keys_5() -> Result<(), DbErr> {\n        use xyz_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                x: 'x' as i32,\n                y: \"y\".into(),\n                z: 'z' as i64,\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::X, Column::Y, Column::Z))\n                .after(('x' as i32, \"y\".to_owned(), 'z' as i64))\n                .first(4)\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"m\".\"x\", \"m\".\"y\", \"m\".\"z\"\"#,\n                    r#\"FROM \"m\"\"#,\n                    r#\"WHERE (\"m\".\"x\" = $1 AND \"m\".\"y\" = $2 AND \"m\".\"z\" > $3)\"#,\n                    r#\"OR (\"m\".\"x\" = $4 AND \"m\".\"y\" > $5)\"#,\n                    r#\"OR \"m\".\"x\" > $6\"#,\n                    r#\"ORDER BY \"m\".\"x\" ASC, \"m\".\"y\" ASC, \"m\".\"z\" ASC\"#,\n                    r#\"LIMIT $7\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    ('x' as i32).into(),\n                    \"y\".into(),\n                    ('z' as i64).into(),\n                    ('x' as i32).into(),\n                    \"y\".into(),\n                    ('x' as i32).into(),\n                    4_u64.into(),\n                ]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn composite_keys_5_desc() -> Result<(), DbErr> {\n        use xyz_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                x: 'x' as i32,\n                y: \"y\".into(),\n                z: 'z' as i64,\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::X, Column::Y, Column::Z))\n                .before(('x' as i32, \"y\".to_owned(), 'z' as i64))\n                .last(4)\n                .desc()\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"m\".\"x\", \"m\".\"y\", \"m\".\"z\"\"#,\n                    r#\"FROM \"m\"\"#,\n                    r#\"WHERE (\"m\".\"x\" = $1 AND \"m\".\"y\" = $2 AND \"m\".\"z\" > $3)\"#,\n                    r#\"OR (\"m\".\"x\" = $4 AND \"m\".\"y\" > $5)\"#,\n                    r#\"OR \"m\".\"x\" > $6\"#,\n                    r#\"ORDER BY \"m\".\"x\" ASC, \"m\".\"y\" ASC, \"m\".\"z\" ASC\"#,\n                    r#\"LIMIT $7\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    ('x' as i32).into(),\n                    \"y\".into(),\n                    ('z' as i64).into(),\n                    ('x' as i32).into(),\n                    \"y\".into(),\n                    ('x' as i32).into(),\n                    4_u64.into(),\n                ]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    mod composite_entity {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"t\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub col_1: String,\n            #[sea_orm(primary_key)]\n            pub col_2: String,\n            #[sea_orm(primary_key)]\n            pub col_3: String,\n            #[sea_orm(primary_key)]\n            pub col_4: String,\n            #[sea_orm(primary_key)]\n            pub col_5: String,\n            #[sea_orm(primary_key)]\n            pub col_6: String,\n            #[sea_orm(primary_key)]\n            pub col_7: String,\n            #[sea_orm(primary_key)]\n            pub col_8: String,\n            #[sea_orm(primary_key)]\n            pub col_9: String,\n            #[sea_orm(primary_key)]\n            pub col_10: String,\n            #[sea_orm(primary_key)]\n            pub col_11: String,\n            #[sea_orm(primary_key)]\n            pub col_12: String,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn cursor_by_many() -> Result<(), DbErr> {\n        use composite_entity::*;\n\n        let base_sql = [\n            r#\"SELECT \"t\".\"col_1\", \"t\".\"col_2\", \"t\".\"col_3\", \"t\".\"col_4\", \"t\".\"col_5\", \"t\".\"col_6\", \"t\".\"col_7\", \"t\".\"col_8\", \"t\".\"col_9\", \"t\".\"col_10\", \"t\".\"col_11\", \"t\".\"col_12\"\"#,\n            r#\"FROM \"t\" WHERE\"#,\n        ].join(\" \");\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4))\n                .after((\"val_1\", \"val_2\", \"val_3\", \"val_4\")).apply_limit().apply_order_by().apply_filters()?.query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" > 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" > 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" > 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" > 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" ASC, \"t\".\"col_2\" ASC, \"t\".\"col_3\" ASC, \"t\".\"col_4\" ASC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5))\n                .after((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\")).apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" > 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" > 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" > 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" > 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" > 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" ASC, \"t\".\"col_2\" ASC, \"t\".\"col_3\" ASC, \"t\".\"col_4\" ASC, \"t\".\"col_5\" ASC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6))\n                .after((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\")).apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" > 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" > 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" > 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" > 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" > 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" > 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" ASC, \"t\".\"col_2\" ASC, \"t\".\"col_3\" ASC, \"t\".\"col_4\" ASC, \"t\".\"col_5\" ASC, \"t\".\"col_6\" ASC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6, Column::Col7))\n                .before((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\", \"val_7\")).apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" < 'val_7')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" < 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" < 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" < 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" < 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" < 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" < 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" ASC, \"t\".\"col_2\" ASC, \"t\".\"col_3\" ASC, \"t\".\"col_4\" ASC, \"t\".\"col_5\" ASC, \"t\".\"col_6\" ASC, \"t\".\"col_7\" ASC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6, Column::Col7, Column::Col8))\n                .before((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\", \"val_7\", \"val_8\")).apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" = 'val_7' AND \"t\".\"col_8\" < 'val_8')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" < 'val_7')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" < 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" < 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" < 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" < 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" < 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" < 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" ASC, \"t\".\"col_2\" ASC, \"t\".\"col_3\" ASC, \"t\".\"col_4\" ASC, \"t\".\"col_5\" ASC, \"t\".\"col_6\" ASC, \"t\".\"col_7\" ASC, \"t\".\"col_8\" ASC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6, Column::Col7, Column::Col8, Column::Col9))\n                .before((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\", \"val_7\", \"val_8\", \"val_9\")).apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" = 'val_7' AND \"t\".\"col_8\" = 'val_8' AND \"t\".\"col_9\" < 'val_9')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" = 'val_7' AND \"t\".\"col_8\" < 'val_8')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" < 'val_7')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" < 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" < 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" < 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" < 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" < 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" < 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" ASC, \"t\".\"col_2\" ASC, \"t\".\"col_3\" ASC, \"t\".\"col_4\" ASC, \"t\".\"col_5\" ASC, \"t\".\"col_6\" ASC, \"t\".\"col_7\" ASC, \"t\".\"col_8\" ASC, \"t\".\"col_9\" ASC\"#,\n            ].join(\" \"))\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn cursor_by_many_desc() -> Result<(), DbErr> {\n        use composite_entity::*;\n\n        let base_sql = [\n            r#\"SELECT \"t\".\"col_1\", \"t\".\"col_2\", \"t\".\"col_3\", \"t\".\"col_4\", \"t\".\"col_5\", \"t\".\"col_6\", \"t\".\"col_7\", \"t\".\"col_8\", \"t\".\"col_9\", \"t\".\"col_10\", \"t\".\"col_11\", \"t\".\"col_12\"\"#,\n            r#\"FROM \"t\" WHERE\"#,\n        ].join(\" \");\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4))\n                .before((\"val_1\", \"val_2\", \"val_3\", \"val_4\")).desc().apply_limit().apply_order_by().apply_filters()?.query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" > 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" > 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" > 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" > 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" DESC, \"t\".\"col_2\" DESC, \"t\".\"col_3\" DESC, \"t\".\"col_4\" DESC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5))\n                .before((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\")).desc().apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" > 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" > 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" > 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" > 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" > 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" DESC, \"t\".\"col_2\" DESC, \"t\".\"col_3\" DESC, \"t\".\"col_4\" DESC, \"t\".\"col_5\" DESC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6))\n                .before((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\")).desc().apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" > 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" > 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" > 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" > 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" > 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" > 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" DESC, \"t\".\"col_2\" DESC, \"t\".\"col_3\" DESC, \"t\".\"col_4\" DESC, \"t\".\"col_5\" DESC, \"t\".\"col_6\" DESC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6, Column::Col7))\n                .after((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\", \"val_7\")).desc().apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" < 'val_7')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" < 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" < 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" < 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" < 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" < 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" < 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" DESC, \"t\".\"col_2\" DESC, \"t\".\"col_3\" DESC, \"t\".\"col_4\" DESC, \"t\".\"col_5\" DESC, \"t\".\"col_6\" DESC, \"t\".\"col_7\" DESC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6, Column::Col7, Column::Col8))\n                .after((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\", \"val_7\", \"val_8\")).desc().apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" = 'val_7' AND \"t\".\"col_8\" < 'val_8')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" < 'val_7')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" < 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" < 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" < 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" < 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" < 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" < 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" DESC, \"t\".\"col_2\" DESC, \"t\".\"col_3\" DESC, \"t\".\"col_4\" DESC, \"t\".\"col_5\" DESC, \"t\".\"col_6\" DESC, \"t\".\"col_7\" DESC, \"t\".\"col_8\" DESC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6, Column::Col7, Column::Col8, Column::Col9))\n                .after((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\", \"val_7\", \"val_8\", \"val_9\")).desc().apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" = 'val_7' AND \"t\".\"col_8\" = 'val_8' AND \"t\".\"col_9\" < 'val_9')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" = 'val_7' AND \"t\".\"col_8\" < 'val_8')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" < 'val_7')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" < 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" < 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" < 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" < 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" < 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" < 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" DESC, \"t\".\"col_2\" DESC, \"t\".\"col_3\" DESC, \"t\".\"col_4\" DESC, \"t\".\"col_5\" DESC, \"t\".\"col_6\" DESC, \"t\".\"col_7\" DESC, \"t\".\"col_8\" DESC, \"t\".\"col_9\" DESC\"#,\n            ].join(\" \"))\n        );\n\n        Ok(())\n    }\n\n    mod test_base_entity {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"base\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(primary_key)]\n            pub name: String,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {\n            #[sea_orm(has_many = \"super::test_related_entity::Entity\")]\n            TestRelatedEntity,\n        }\n\n        impl Related<super::test_related_entity::Entity> for Entity {\n            fn to() -> RelationDef {\n                Relation::TestRelatedEntity.def()\n            }\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    mod test_related_entity {\n        use super::test_base_entity;\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"related\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(primary_key)]\n            pub name: String,\n            pub test_id: i32,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {\n            #[sea_orm(\n                belongs_to = \"test_base_entity::Entity\",\n                from = \"Column::TestId\",\n                to = \"super::test_base_entity::Column::Id\"\n            )]\n            TestBaseEntity,\n        }\n\n        impl Related<super::test_base_entity::Entity> for Entity {\n            fn to() -> RelationDef {\n                Relation::TestBaseEntity.def()\n            }\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn related_composite_keys_1() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                test_base_entity::Model {\n                    id: 1,\n                    name: \"CAT\".into(),\n                },\n                test_related_entity::Model {\n                    id: 1,\n                    name: \"CATE\".into(),\n                    test_id: 1,\n                },\n            )]])\n            .into_connection();\n\n        assert!(\n            !test_base_entity::Entity::find()\n                .find_also_related(test_related_entity::Entity)\n                .cursor_by((test_base_entity::Column::Id, test_base_entity::Column::Name))\n                .first(1)\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"base\".\"id\" AS \"A_id\", \"base\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"related\".\"id\" AS \"B_id\", \"related\".\"name\" AS \"B_name\", \"related\".\"test_id\" AS \"B_test_id\"\"#,\n                    r#\"FROM \"base\"\"#,\n                    r#\"LEFT JOIN \"related\" ON \"base\".\"id\" = \"related\".\"test_id\"\"#,\n                    r#\"ORDER BY \"base\".\"id\" ASC, \"base\".\"name\" ASC, \"related\".\"id\" ASC, \"related\".\"name\" ASC LIMIT $1\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [1_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn related_composite_keys_1_desc() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                test_base_entity::Model {\n                    id: 1,\n                    name: \"CAT\".into(),\n                },\n                test_related_entity::Model {\n                    id: 1,\n                    name: \"CATE\".into(),\n                    test_id: 1,\n                },\n            )]])\n            .into_connection();\n\n        assert!(\n            !test_base_entity::Entity::find()\n                .find_also_related(test_related_entity::Entity)\n                .cursor_by((test_base_entity::Column::Id, test_base_entity::Column::Name))\n                .last(1)\n                .desc()\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"base\".\"id\" AS \"A_id\", \"base\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"related\".\"id\" AS \"B_id\", \"related\".\"name\" AS \"B_name\", \"related\".\"test_id\" AS \"B_test_id\"\"#,\n                    r#\"FROM \"base\"\"#,\n                    r#\"LEFT JOIN \"related\" ON \"base\".\"id\" = \"related\".\"test_id\"\"#,\n                    r#\"ORDER BY \"base\".\"id\" ASC, \"base\".\"name\" ASC, \"related\".\"id\" ASC, \"related\".\"name\" ASC LIMIT $1\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [1_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn related_composite_keys_2() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                test_base_entity::Model {\n                    id: 1,\n                    name: \"CAT\".into(),\n                },\n                test_related_entity::Model {\n                    id: 1,\n                    name: \"CATE\".into(),\n                    test_id: 1,\n                },\n            )]])\n            .into_connection();\n\n        assert!(\n            !test_base_entity::Entity::find()\n                .find_also_related(test_related_entity::Entity)\n                .cursor_by((test_base_entity::Column::Id, test_base_entity::Column::Name))\n                .after((1, \"C\".to_string()))\n                .first(2)\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"base\".\"id\" AS \"A_id\", \"base\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"related\".\"id\" AS \"B_id\", \"related\".\"name\" AS \"B_name\", \"related\".\"test_id\" AS \"B_test_id\"\"#,\n                    r#\"FROM \"base\"\"#,\n                    r#\"LEFT JOIN \"related\" ON \"base\".\"id\" = \"related\".\"test_id\"\"#,\n                    r#\"WHERE (\"base\".\"id\" = $1 AND \"base\".\"name\" > $2) OR \"base\".\"id\" > $3\"#,\n                    r#\"ORDER BY \"base\".\"id\" ASC, \"base\".\"name\" ASC, \"related\".\"id\" ASC, \"related\".\"name\" ASC LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    1_i32.into(),\n                    \"C\".into(),\n                    1_i32.into(),\n                    2_u64.into(),\n                ]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn related_composite_keys_2_desc() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                test_base_entity::Model {\n                    id: 1,\n                    name: \"CAT\".into(),\n                },\n                test_related_entity::Model {\n                    id: 1,\n                    name: \"CATE\".into(),\n                    test_id: 1,\n                },\n            )]])\n            .into_connection();\n\n        assert!(\n            !test_base_entity::Entity::find()\n                .find_also_related(test_related_entity::Entity)\n                .cursor_by((test_base_entity::Column::Id, test_base_entity::Column::Name))\n                .before((1, \"C\".to_string()))\n                .last(2)\n                .desc()\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"base\".\"id\" AS \"A_id\", \"base\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"related\".\"id\" AS \"B_id\", \"related\".\"name\" AS \"B_name\", \"related\".\"test_id\" AS \"B_test_id\"\"#,\n                    r#\"FROM \"base\"\"#,\n                    r#\"LEFT JOIN \"related\" ON \"base\".\"id\" = \"related\".\"test_id\"\"#,\n                    r#\"WHERE (\"base\".\"id\" = $1 AND \"base\".\"name\" > $2) OR \"base\".\"id\" > $3\"#,\n                    r#\"ORDER BY \"base\".\"id\" ASC, \"base\".\"name\" ASC, \"related\".\"id\" ASC, \"related\".\"name\" ASC LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    1_i32.into(),\n                    \"C\".into(),\n                    1_i32.into(),\n                    2_u64.into(),\n                ]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn related_composite_keys_3() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                test_base_entity::Model {\n                    id: 1,\n                    name: \"CAT\".into(),\n                },\n                test_related_entity::Model {\n                    id: 1,\n                    name: \"CATE\".into(),\n                    test_id: 1,\n                },\n            )]])\n            .into_connection();\n\n        assert!(\n            !test_base_entity::Entity::find()\n                .find_also_related(test_related_entity::Entity)\n                .cursor_by_other((\n                    test_related_entity::Column::Id,\n                    test_related_entity::Column::Name\n                ))\n                .after((1, \"CAT\".to_string()))\n                .first(2)\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"base\".\"id\" AS \"A_id\", \"base\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"related\".\"id\" AS \"B_id\", \"related\".\"name\" AS \"B_name\", \"related\".\"test_id\" AS \"B_test_id\"\"#,\n                    r#\"FROM \"base\"\"#,\n                    r#\"LEFT JOIN \"related\" ON \"base\".\"id\" = \"related\".\"test_id\"\"#,\n                    r#\"WHERE (\"related\".\"id\" = $1 AND \"related\".\"name\" > $2) OR \"related\".\"id\" > $3\"#,\n                    r#\"ORDER BY \"related\".\"id\" ASC, \"related\".\"name\" ASC, \"base\".\"id\" ASC, \"base\".\"name\" ASC LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    1_i32.into(),\n                    \"CAT\".into(),\n                    1_i32.into(),\n                    2_u64.into(),\n                ]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn related_composite_keys_3_desc() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                test_base_entity::Model {\n                    id: 1,\n                    name: \"CAT\".into(),\n                },\n                test_related_entity::Model {\n                    id: 1,\n                    name: \"CATE\".into(),\n                    test_id: 1,\n                },\n            )]])\n            .into_connection();\n\n        assert!(\n            !test_base_entity::Entity::find()\n                .find_also_related(test_related_entity::Entity)\n                .cursor_by_other((\n                    test_related_entity::Column::Id,\n                    test_related_entity::Column::Name\n                ))\n                .before((1, \"CAT\".to_string()))\n                .last(2)\n                .desc()\n                .all(&db)?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"base\".\"id\" AS \"A_id\", \"base\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"related\".\"id\" AS \"B_id\", \"related\".\"name\" AS \"B_name\", \"related\".\"test_id\" AS \"B_test_id\"\"#,\n                    r#\"FROM \"base\"\"#,\n                    r#\"LEFT JOIN \"related\" ON \"base\".\"id\" = \"related\".\"test_id\"\"#,\n                    r#\"WHERE (\"related\".\"id\" = $1 AND \"related\".\"name\" > $2) OR \"related\".\"id\" > $3\"#,\n                    r#\"ORDER BY \"related\".\"id\" ASC, \"related\".\"name\" ASC, \"base\".\"id\" ASC, \"base\".\"name\" ASC LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    1_i32.into(),\n                    \"CAT\".into(),\n                    1_i32.into(),\n                    2_u64.into(),\n                ]\n            ),])]\n        );\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/delete.rs",
    "content": "use super::{ReturningSelector, SelectModel};\nuse crate::{\n    ColumnTrait, ConnectionTrait, DeleteMany, DeleteOne, EntityTrait, Iterable, ValidatedDeleteOne,\n    error::*,\n};\nuse sea_query::{DeleteStatement, Query};\n\n/// Handles DELETE operations in a ActiveModel using [DeleteStatement]\n#[derive(Clone, Debug)]\npub struct Deleter {\n    query: DeleteStatement,\n}\n\n/// The result of a DELETE operation\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct DeleteResult {\n    /// The number of rows affected by the DELETE operation\n    pub rows_affected: u64,\n}\n\nimpl<E> ValidatedDeleteOne<E>\nwhere\n    E: EntityTrait,\n{\n    /// Execute a DELETE operation on one ActiveModel\n    pub fn exec<C>(self, db: &C) -> Result<DeleteResult, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        exec_delete_only(self.query, db)\n    }\n\n    /// Execute an delete operation and return the deleted model\n    pub fn exec_with_returning<C>(self, db: &C) -> Result<Option<E::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        exec_delete_with_returning_one::<E, _>(self.query, db)\n    }\n}\n\nimpl<E> DeleteOne<E>\nwhere\n    E: EntityTrait,\n{\n    /// Execute a DELETE operation on one ActiveModel\n    pub fn exec<C>(self, db: &C) -> Result<DeleteResult, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.0?.exec(db)\n    }\n\n    /// Execute an delete operation and return the deleted model\n    pub fn exec_with_returning<C>(self, db: &C) -> Result<Option<E::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.0?.exec_with_returning(db)\n    }\n}\n\nimpl<'a, E> DeleteMany<E>\nwhere\n    E: EntityTrait,\n{\n    /// Execute a DELETE operation on many ActiveModels\n    pub fn exec<C>(self, db: &'a C) -> Result<DeleteResult, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        exec_delete_only(self.query, db)\n    }\n\n    /// Execute an delete operation and return the deleted model\n    pub fn exec_with_returning<C>(self, db: &C) -> Result<Vec<E::Model>, DbErr>\n    where\n        E: EntityTrait,\n        C: ConnectionTrait,\n    {\n        exec_delete_with_returning_many::<E, _>(self.query, db)\n    }\n}\n\nimpl Deleter {\n    /// Instantiate a new [Deleter] by passing it a [DeleteStatement]\n    pub fn new(query: DeleteStatement) -> Self {\n        Self { query }\n    }\n\n    /// Execute a DELETE operation\n    pub fn exec<C>(self, db: &C) -> Result<DeleteResult, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        exec_delete(self.query, db)\n    }\n\n    /// Execute an delete operation and return the deleted model\n    pub fn exec_with_returning<E, C>(self, db: &C) -> Result<Vec<E::Model>, DbErr>\n    where\n        E: EntityTrait,\n        C: ConnectionTrait,\n    {\n        exec_delete_with_returning_many::<E, _>(self.query, db)\n    }\n}\n\nimpl DeleteResult {\n    #[doc(hidden)]\n    pub fn empty() -> Self {\n        Self { rows_affected: 0 }\n    }\n\n    #[doc(hidden)]\n    pub fn merge(&mut self, other: DeleteResult) {\n        self.rows_affected += other.rows_affected;\n    }\n}\n\nfn exec_delete_only<C>(query: DeleteStatement, db: &C) -> Result<DeleteResult, DbErr>\nwhere\n    C: ConnectionTrait,\n{\n    Deleter::new(query).exec(db)\n}\n\nfn exec_delete<C>(query: DeleteStatement, db: &C) -> Result<DeleteResult, DbErr>\nwhere\n    C: ConnectionTrait,\n{\n    let result = db.execute(&query)?;\n    Ok(DeleteResult {\n        rows_affected: result.rows_affected(),\n    })\n}\n\nfn exec_delete_with_returning_one<E, C>(\n    mut query: DeleteStatement,\n    db: &C,\n) -> Result<Option<E::Model>, DbErr>\nwhere\n    E: EntityTrait,\n    C: ConnectionTrait,\n{\n    let db_backend = db.get_database_backend();\n    match db.support_returning() {\n        true => {\n            let returning = Query::returning().exprs(\n                E::Column::iter().map(|c| c.select_enum_as(c.into_returning_expr(db_backend))),\n            );\n            query.returning(returning);\n            ReturningSelector::<SelectModel<<E>::Model>, _>::from_query(query).one(db)\n        }\n        false => Err(DbErr::BackendNotSupported {\n            db: db_backend.as_str(),\n            ctx: \"DELETE RETURNING\",\n        }),\n    }\n}\n\nfn exec_delete_with_returning_many<E, C>(\n    mut query: DeleteStatement,\n    db: &C,\n) -> Result<Vec<E::Model>, DbErr>\nwhere\n    E: EntityTrait,\n    C: ConnectionTrait,\n{\n    let db_backend = db.get_database_backend();\n    match db.support_returning() {\n        true => {\n            let returning = Query::returning().exprs(\n                E::Column::iter().map(|c| c.select_enum_as(c.into_returning_expr(db_backend))),\n            );\n            query.returning(returning);\n            ReturningSelector::<SelectModel<<E>::Model>, _>::from_query(query).all(db)\n        }\n        false => Err(DbErr::BackendNotSupported {\n            db: db_backend.as_str(),\n            ctx: \"DELETE RETURNING\",\n        }),\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::cake;\n\n    #[test]\n    fn delete_error() {\n        use crate::{DbBackend, DbErr, Delete, EntityTrait, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::MySql).into_connection();\n\n        assert!(matches!(\n            Delete::one(cake::ActiveModel {\n                ..Default::default()\n            })\n            .exec(&db),\n            Err(DbErr::PrimaryKeyNotSet { .. })\n        ));\n\n        assert!(matches!(\n            cake::Entity::delete(cake::ActiveModel::default()).exec(&db),\n            Err(DbErr::PrimaryKeyNotSet { .. })\n        ));\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/execute.rs",
    "content": "/// Defines the result of executing an operation\n#[derive(Debug)]\npub struct ExecResult {\n    /// The type of result from the execution depending on the feature flag enabled\n    /// to choose a database backend\n    pub(crate) result: ExecResultHolder,\n}\n\n/// Holds a result depending on the database backend chosen by the feature flag\n#[allow(clippy::enum_variant_names)]\n#[derive(Debug)]\npub(crate) enum ExecResultHolder {\n    /// Holds the result of executing an operation on a MySQL database\n    #[cfg(feature = \"sqlx-mysql\")]\n    SqlxMySql(sqlx::mysql::MySqlQueryResult),\n    /// Holds the result of executing an operation on a PostgreSQL database\n    #[cfg(feature = \"sqlx-postgres\")]\n    SqlxPostgres(sqlx::postgres::PgQueryResult),\n    /// Holds the result of executing an operation on a SQLite database\n    #[cfg(feature = \"sqlx-sqlite\")]\n    SqlxSqlite(sqlx::sqlite::SqliteQueryResult),\n    /// Holds the result of executing an operation on a SQLite database\n    #[cfg(feature = \"rusqlite\")]\n    Rusqlite(crate::driver::rusqlite::RusqliteExecResult),\n    /// Holds the result of executing an operation on the Mock database\n    #[cfg(feature = \"mock\")]\n    Mock(crate::MockExecResult),\n    /// Holds the result of executing an operation on the Proxy database\n    #[cfg(feature = \"proxy\")]\n    Proxy(crate::ProxyExecResult),\n}\n\n// ExecResult //\n\nimpl ExecResult {\n    /// Get the last id after `AUTOINCREMENT` is done on the primary key\n    ///\n    /// # Panics\n    ///\n    /// Postgres does not support retrieving last insert id this way except through `RETURNING` clause\n    pub fn last_insert_id(&self) -> u64 {\n        match &self.result {\n            #[cfg(feature = \"sqlx-mysql\")]\n            ExecResultHolder::SqlxMySql(result) => result.last_insert_id(),\n            #[cfg(feature = \"sqlx-postgres\")]\n            ExecResultHolder::SqlxPostgres(_) => {\n                panic!(\"Should not retrieve last_insert_id this way\")\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            ExecResultHolder::SqlxSqlite(result) => {\n                let last_insert_rowid = result.last_insert_rowid();\n                if last_insert_rowid < 0 {\n                    unreachable!(\"negative last_insert_rowid\")\n                } else {\n                    last_insert_rowid as u64\n                }\n            }\n            #[cfg(feature = \"rusqlite\")]\n            ExecResultHolder::Rusqlite(result) => {\n                let last_insert_rowid = result.last_insert_rowid;\n                if last_insert_rowid < 0 {\n                    unreachable!(\"negative last_insert_rowid\")\n                } else {\n                    last_insert_rowid as u64\n                }\n            }\n            #[cfg(feature = \"mock\")]\n            ExecResultHolder::Mock(result) => result.last_insert_id,\n            #[cfg(feature = \"proxy\")]\n            ExecResultHolder::Proxy(result) => result.last_insert_id,\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n\n    /// Get the number of rows affected by the operation\n    pub fn rows_affected(&self) -> u64 {\n        match &self.result {\n            #[cfg(feature = \"sqlx-mysql\")]\n            ExecResultHolder::SqlxMySql(result) => result.rows_affected(),\n            #[cfg(feature = \"sqlx-postgres\")]\n            ExecResultHolder::SqlxPostgres(result) => result.rows_affected(),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            ExecResultHolder::SqlxSqlite(result) => result.rows_affected(),\n            #[cfg(feature = \"rusqlite\")]\n            ExecResultHolder::Rusqlite(result) => result.rows_affected,\n            #[cfg(feature = \"mock\")]\n            ExecResultHolder::Mock(result) => result.rows_affected,\n            #[cfg(feature = \"proxy\")]\n            ExecResultHolder::Proxy(result) => result.rows_affected,\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/insert.rs",
    "content": "use super::ReturningSelector;\nuse crate::{\n    ActiveModelTrait, ColumnTrait, ConnectionTrait, DbBackend, EntityTrait, Insert, InsertMany,\n    IntoActiveModel, Iterable, PrimaryKeyToColumn, PrimaryKeyTrait, SelectModel, TryFromU64,\n    TryInsert, error::*,\n};\nuse sea_query::{FromValueTuple, Iden, InsertStatement, Query, ReturningClause, ValueTuple};\nuse std::marker::PhantomData;\n\ntype PrimaryKey<A> = <<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey;\n\n/// Defines a structure to perform INSERT operations in an ActiveModel\n#[derive(Debug)]\npub struct Inserter<A>\nwhere\n    A: ActiveModelTrait,\n{\n    primary_key: Option<ValueTuple>,\n    query: InsertStatement,\n    model: PhantomData<A>,\n}\n\n/// The result of an INSERT operation on an ActiveModel\n#[derive(Debug)]\n#[non_exhaustive]\npub struct InsertResult<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// The primary key value of the last inserted row\n    pub last_insert_id: <PrimaryKey<A> as PrimaryKeyTrait>::ValueType,\n}\n\n/// The result of an INSERT many operation for a set of ActiveModels\n#[derive(Debug)]\n#[non_exhaustive]\npub struct InsertManyResult<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// The primary key value of the last inserted row\n    pub last_insert_id: Option<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>,\n}\n\n/// The result of executing a [`crate::TryInsert`].\n///\n/// This enum represents no‑op inserts (e.g. conflict `DO NOTHING`) without treating\n/// them as errors.\n#[derive(Debug)]\npub enum TryInsertResult<T> {\n    /// There was nothing to insert, so no SQL was executed.\n    ///\n    /// This typically happens when creating a [`crate::TryInsert`] from an empty iterator or None.\n    Empty,\n    /// The statement was executed, but SeaORM could not get the inserted row / insert id.\n    ///\n    /// This is commonly caused by `ON CONFLICT ... DO NOTHING` (Postgres / SQLite) or the MySQL\n    /// polyfill (`ON DUPLICATE KEY UPDATE pk = pk`).\n    ///\n    /// Note that this variant maps from `DbErr::RecordNotInserted`, so it can also represent other\n    /// situations where the backend/driver reports no inserted row (e.g. an empty `RETURNING`\n    /// result set or a \"no-op\" update in MySQL where `last_insert_id` is reported as `0`). In rare\n    /// cases, this can be a false negative where a row was inserted but the backend did not report\n    /// it.\n    Conflicted,\n    /// Successfully inserted\n    Inserted(T),\n}\n\nimpl<A> TryInsertResult<InsertResult<A>>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Extract the last inserted id.\n    ///\n    /// - [`TryInsertResult::Empty`] => `Ok(None)`\n    /// - [`TryInsertResult::Inserted`] => `Ok(Some(last_insert_id))`\n    /// - [`TryInsertResult::Conflicted`] => `Err(DbErr::RecordNotInserted)`\n    pub fn last_insert_id(\n        self,\n    ) -> Result<Option<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>, DbErr> {\n        match self {\n            Self::Empty => Ok(None),\n            Self::Inserted(v) => Ok(Some(v.last_insert_id)),\n            Self::Conflicted => Err(DbErr::RecordNotInserted),\n        }\n    }\n}\n\nimpl<A> TryInsert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Execute an insert operation\n    pub fn exec<C>(self, db: &C) -> Result<TryInsertResult<InsertResult<A>>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(TryInsertResult::Empty);\n        }\n        let res = self.insert_struct.exec(db);\n        match res {\n            Ok(res) => Ok(TryInsertResult::Inserted(res)),\n            Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),\n            Err(err) => Err(err),\n        }\n    }\n\n    /// Execute an insert operation without returning (don't use `RETURNING` syntax)\n    /// Number of rows affected is returned\n    pub fn exec_without_returning<C>(self, db: &C) -> Result<TryInsertResult<u64>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(TryInsertResult::Empty);\n        }\n        let res = self.insert_struct.exec_without_returning(db);\n        match res {\n            Ok(res) => Ok(TryInsertResult::Inserted(res)),\n            Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),\n            Err(err) => Err(err),\n        }\n    }\n\n    /// Execute an insert operation and return the inserted model (use `RETURNING` syntax if supported)\n    pub fn exec_with_returning<C>(\n        self,\n        db: &C,\n    ) -> Result<TryInsertResult<<A::Entity as EntityTrait>::Model>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(TryInsertResult::Empty);\n        }\n        let res = self.insert_struct.exec_with_returning(db);\n        match res {\n            Ok(res) => Ok(TryInsertResult::Inserted(res)),\n            Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),\n            Err(err) => Err(err),\n        }\n    }\n\n    /// Execute an insert operation and return primary keys of inserted models\n    pub fn exec_with_returning_keys<C>(\n        self,\n        db: &C,\n    ) -> Result<TryInsertResult<Vec<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(TryInsertResult::Empty);\n        }\n\n        let res = self.insert_struct.exec_with_returning_keys(db);\n        match res {\n            Ok(res) => Ok(TryInsertResult::Inserted(res)),\n            Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),\n            Err(err) => Err(err),\n        }\n    }\n\n    /// Execute an insert operation and return all inserted models\n    pub fn exec_with_returning_many<C>(\n        self,\n        db: &C,\n    ) -> Result<TryInsertResult<Vec<<A::Entity as EntityTrait>::Model>>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(TryInsertResult::Empty);\n        }\n\n        let res = self.insert_struct.exec_with_returning_many(db);\n        match res {\n            Ok(res) => Ok(TryInsertResult::Inserted(res)),\n            Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),\n            Err(err) => Err(err),\n        }\n    }\n}\n\nimpl<A> Insert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Execute an insert operation\n    pub fn exec<'a, C>(self, db: &'a C) -> Result<InsertResult<A>, DbErr>\n    where\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        // so that self is dropped before entering await\n        let mut query = self.query;\n        if db.support_returning() {\n            query.returning(returning_pk::<A>(db.get_database_backend()));\n        }\n        Inserter::<A>::new(self.primary_key, query).exec(db)\n    }\n\n    /// Execute an insert operation without returning (don't use `RETURNING` syntax)\n    /// Number of rows affected is returned\n    pub fn exec_without_returning<'a, C>(self, db: &'a C) -> Result<u64, DbErr>\n    where\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        Inserter::<A>::new(self.primary_key, self.query).exec_without_returning(db)\n    }\n\n    /// Execute an insert operation and return the inserted model (use `RETURNING` syntax if supported)\n    ///\n    /// + To get back all inserted models, use [`exec_with_returning_many`].\n    /// + To get back all inserted primary keys, use [`exec_with_returning_keys`].\n    pub fn exec_with_returning<'a, C>(\n        self,\n        db: &'a C,\n    ) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        Inserter::<A>::new(self.primary_key, self.query).exec_with_returning(db)\n    }\n\n    /// Execute an insert operation and return primary keys of inserted models\n    pub fn exec_with_returning_keys<'a, C>(\n        self,\n        db: &'a C,\n    ) -> Result<Vec<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        Inserter::<A>::new(self.primary_key, self.query).exec_with_returning_keys(db)\n    }\n\n    /// Execute an insert operation and return all inserted models\n    pub fn exec_with_returning_many<'a, C>(\n        self,\n        db: &'a C,\n    ) -> Result<Vec<<A::Entity as EntityTrait>::Model>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        Inserter::<A>::new(self.primary_key, self.query).exec_with_returning_many(db)\n    }\n}\n\nimpl<A> InsertMany<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Execute an insert operation\n    pub fn exec<C>(self, db: &C) -> Result<InsertManyResult<A>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(InsertManyResult {\n                last_insert_id: None,\n            });\n        }\n        let res = self.into_one().exec(db);\n        match res {\n            Ok(r) => Ok(InsertManyResult {\n                last_insert_id: Some(r.last_insert_id),\n            }),\n            Err(err) => Err(err),\n        }\n    }\n\n    /// Execute an insert operation without returning (don't use `RETURNING` syntax)\n    /// Number of rows affected is returned\n    pub fn exec_without_returning<C>(self, db: &C) -> Result<u64, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(0);\n        }\n        self.into_one().exec_without_returning(db)\n    }\n\n    /// Execute an insert operation and return all inserted models\n    pub fn exec_with_returning<C>(\n        self,\n        db: &C,\n    ) -> Result<Vec<<A::Entity as EntityTrait>::Model>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(Vec::new());\n        }\n\n        self.into_one().exec_with_returning_many(db)\n    }\n\n    /// Alias to [`InsertMany::exec_with_returning`].\n    #[deprecated(\n        since = \"2.0.0\",\n        note = \"Please use [`InsertMany::exec_with_returning`]\"\n    )]\n    pub fn exec_with_returning_many<C>(\n        self,\n        db: &C,\n    ) -> Result<Vec<<A::Entity as EntityTrait>::Model>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(Vec::new());\n        }\n\n        self.into_one().exec_with_returning_many(db)\n    }\n\n    /// Execute an insert operation and return primary keys of inserted models\n    pub fn exec_with_returning_keys<C>(\n        self,\n        db: &C,\n    ) -> Result<Vec<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(Vec::new());\n        }\n\n        self.into_one().exec_with_returning_keys(db)\n    }\n}\n\nimpl<A> Inserter<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Instantiate a new insert operation\n    pub fn new(primary_key: Option<ValueTuple>, query: InsertStatement) -> Self {\n        Self {\n            primary_key,\n            query,\n            model: PhantomData,\n        }\n    }\n\n    /// Execute an insert operation, returning the last inserted id\n    pub fn exec<'a, C>(self, db: &'a C) -> Result<InsertResult<A>, DbErr>\n    where\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        exec_insert(self.primary_key, self.query, db)\n    }\n\n    /// Execute an insert operation\n    pub fn exec_without_returning<'a, C>(self, db: &'a C) -> Result<u64, DbErr>\n    where\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        exec_insert_without_returning(self.query, db)\n    }\n\n    /// Execute an insert operation and return the inserted model (use `RETURNING` syntax if supported)\n    pub fn exec_with_returning<'a, C>(\n        self,\n        db: &'a C,\n    ) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        exec_insert_with_returning::<A, _>(self.primary_key, self.query, db)\n    }\n\n    /// Execute an insert operation and return primary keys of inserted models\n    pub fn exec_with_returning_keys<'a, C>(\n        self,\n        db: &'a C,\n    ) -> Result<Vec<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        exec_insert_with_returning_keys::<A, _>(self.query, db)\n    }\n\n    /// Execute an insert operation and return all inserted models\n    pub fn exec_with_returning_many<'a, C>(\n        self,\n        db: &'a C,\n    ) -> Result<Vec<<A::Entity as EntityTrait>::Model>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        exec_insert_with_returning_many::<A, _>(self.query, db)\n    }\n}\n\nfn exec_insert<A, C>(\n    primary_key: Option<ValueTuple>,\n    statement: InsertStatement,\n    db: &C,\n) -> Result<InsertResult<A>, DbErr>\nwhere\n    C: ConnectionTrait,\n    A: ActiveModelTrait,\n{\n    type ValueTypeOf<A> = <PrimaryKey<A> as PrimaryKeyTrait>::ValueType;\n\n    let db_backend = db.get_database_backend();\n\n    let last_insert_id = match (primary_key, db.support_returning()) {\n        (_, true) => {\n            let mut rows = db.query_all(&statement)?;\n            let row = match rows.pop() {\n                Some(row) => row,\n                None => return Err(DbErr::RecordNotInserted),\n            };\n            let cols = PrimaryKey::<A>::iter()\n                .map(|col| col.to_string())\n                .collect::<Vec<_>>();\n            row.try_get_many(\"\", cols.as_ref())\n                .map_err(|_| DbErr::UnpackInsertId)?\n        }\n        (Some(value_tuple), false) => {\n            let res = db.execute(&statement)?;\n            if res.rows_affected() == 0 {\n                return Err(DbErr::RecordNotInserted);\n            }\n            FromValueTuple::from_value_tuple(value_tuple)\n        }\n        (None, false) => {\n            let res = db.execute(&statement)?;\n            if res.rows_affected() == 0 {\n                return Err(DbErr::RecordNotInserted);\n            }\n            let last_insert_id = res.last_insert_id();\n            // For MySQL, the affected-rows number:\n            //   - The affected-rows value per row is `1` if the row is inserted as a new row,\n            //   - `2` if an existing row is updated,\n            //   - and `0` if an existing row is set to its current values.\n            // Reference: https://dev.mysql.com/doc/refman/8.4/en/insert-on-duplicate.html\n            if db_backend == DbBackend::MySql && last_insert_id == 0 {\n                return Err(DbErr::RecordNotInserted);\n            }\n            ValueTypeOf::<A>::try_from_u64(last_insert_id).map_err(|_| DbErr::UnpackInsertId)?\n        }\n    };\n\n    Ok(InsertResult { last_insert_id })\n}\n\nfn exec_insert_without_returning<C>(insert_statement: InsertStatement, db: &C) -> Result<u64, DbErr>\nwhere\n    C: ConnectionTrait,\n{\n    let exec_result = db.execute(&insert_statement)?;\n    Ok(exec_result.rows_affected())\n}\n\nfn exec_insert_with_returning<A, C>(\n    primary_key: Option<ValueTuple>,\n    mut insert_statement: InsertStatement,\n    db: &C,\n) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\nwhere\n    <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n    C: ConnectionTrait,\n    A: ActiveModelTrait,\n{\n    let db_backend = db.get_database_backend();\n    let found = match db.support_returning() {\n        true => {\n            let returning = Query::returning().exprs(\n                <A::Entity as EntityTrait>::Column::iter()\n                    .map(|c| c.select_as(c.into_returning_expr(db_backend))),\n            );\n            insert_statement.returning(returning);\n            ReturningSelector::<SelectModel<<A::Entity as EntityTrait>::Model>, _>::from_query(\n                insert_statement,\n            )\n            .one(db)?\n        }\n        false => {\n            let insert_res = exec_insert::<A, _>(primary_key, insert_statement, db)?;\n            <A::Entity as EntityTrait>::find_by_id(insert_res.last_insert_id).one(db)?\n        }\n    };\n    match found {\n        Some(model) => Ok(model),\n        None => Err(DbErr::RecordNotFound(\n            \"Failed to find inserted item\".to_owned(),\n        )),\n    }\n}\n\nfn exec_insert_with_returning_keys<A, C>(\n    mut insert_statement: InsertStatement,\n    db: &C,\n) -> Result<Vec<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>, DbErr>\nwhere\n    <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n    C: ConnectionTrait,\n    A: ActiveModelTrait,\n{\n    let db_backend = db.get_database_backend();\n    match db.support_returning() {\n        true => {\n            insert_statement.returning(returning_pk::<A>(db_backend));\n            let rows = db.query_all(&insert_statement)?;\n            let cols = PrimaryKey::<A>::iter()\n                .map(|col| col.to_string())\n                .collect::<Vec<_>>();\n            let mut keys = Vec::new();\n            for row in rows {\n                keys.push(\n                    row.try_get_many(\"\", cols.as_ref())\n                        .map_err(|_| DbErr::UnpackInsertId)?,\n                );\n            }\n            Ok(keys)\n        }\n        false => Err(DbErr::BackendNotSupported {\n            db: db_backend.as_str(),\n            ctx: \"INSERT RETURNING\",\n        }),\n    }\n}\n\nfn exec_insert_with_returning_many<A, C>(\n    mut insert_statement: InsertStatement,\n    db: &C,\n) -> Result<Vec<<A::Entity as EntityTrait>::Model>, DbErr>\nwhere\n    <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n    C: ConnectionTrait,\n    A: ActiveModelTrait,\n{\n    let db_backend = db.get_database_backend();\n    match db.support_returning() {\n        true => {\n            let returning = Query::returning().exprs(\n                <A::Entity as EntityTrait>::Column::iter()\n                    .map(|c| c.select_as(c.into_returning_expr(db_backend))),\n            );\n            insert_statement.returning(returning);\n            ReturningSelector::<SelectModel<<A::Entity as EntityTrait>::Model>, _>::from_query(\n                insert_statement,\n            )\n            .all(db)\n        }\n        false => Err(DbErr::BackendNotSupported {\n            db: db_backend.as_str(),\n            ctx: \"INSERT RETURNING\",\n        }),\n    }\n}\n\nfn returning_pk<A>(db_backend: DbBackend) -> ReturningClause\nwhere\n    A: ActiveModelTrait,\n{\n    Query::returning().exprs(<A::Entity as EntityTrait>::PrimaryKey::iter().map(|c| {\n        c.into_column()\n            .select_as(c.into_column().into_returning_expr(db_backend))\n    }))\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/mod.rs",
    "content": "mod consolidate;\nmod cursor;\nmod delete;\nmod execute;\nmod insert;\nmod paginator;\nmod query;\nmod returning;\nmod select;\nmod select_ext;\nmod update;\n\nuse consolidate::*;\npub use cursor::*;\npub use delete::*;\npub use execute::*;\npub use insert::*;\npub use paginator::*;\npub use query::*;\nuse returning::*;\npub use select::*;\npub use select_ext::*;\npub use update::*;\n"
  },
  {
    "path": "sea-orm-sync/src/executor/paginator.rs",
    "content": "use crate::{\n    ConnectionTrait, EntityTrait, FromQueryResult, Select, SelectModel, SelectTwo, SelectTwoModel,\n    Selector, SelectorRaw, SelectorTrait, error::*,\n};\nuse sea_query::{Expr, SelectStatement};\nuse std::marker::PhantomData;\n\n#[cfg(not(feature = \"sync\"))]\ntype PinBoxStream<'db, Item> = Pin<Box<dyn Stream<Item = Item> + 'db>>;\n#[cfg(feature = \"sync\")]\ntype PinBoxStream<'db, Item> = Box<dyn Iterator<Item = Item> + 'db>;\n\n/// Defined a structure to handle pagination of a result from a query operation on a Model\n#[derive(Clone, Debug)]\npub struct Paginator<'db, C, S>\nwhere\n    C: ConnectionTrait,\n    S: SelectorTrait + 'db,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) page: u64,\n    pub(crate) page_size: u64,\n    pub(crate) db: &'db C,\n    pub(crate) selector: PhantomData<S>,\n}\n\n/// Define a structure containing the numbers of items and pages of a Paginator\n#[derive(Clone, Debug)]\npub struct ItemsAndPagesNumber {\n    /// The total number of items of a paginator\n    pub number_of_items: u64,\n    /// The total number of pages of a paginator\n    pub number_of_pages: u64,\n}\n\n// LINT: warn if paginator is used without an order by clause\n\nimpl<'db, C, S> Paginator<'db, C, S>\nwhere\n    C: ConnectionTrait,\n    S: SelectorTrait + 'db,\n{\n    /// Fetch a specific page; page index starts from zero\n    pub fn fetch_page(&self, page: u64) -> Result<Vec<S::Item>, DbErr> {\n        let query = self\n            .query\n            .clone()\n            .limit(self.page_size)\n            .offset(self.page_size * page)\n            .to_owned();\n        let rows = self.db.query_all(&query)?;\n        let mut buffer = Vec::with_capacity(rows.len());\n        for row in rows.into_iter() {\n            buffer.push(S::from_raw_query_result(row)?);\n        }\n        Ok(buffer)\n    }\n\n    /// Fetch the current page\n    pub fn fetch(&self) -> Result<Vec<S::Item>, DbErr> {\n        self.fetch_page(self.page)\n    }\n\n    /// Get the total number of items\n    pub fn num_items(&self) -> Result<u64, DbErr> {\n        let query = SelectStatement::new()\n            .expr(Expr::cust(\"COUNT(*) AS num_items\"))\n            .from_subquery(\n                self.query\n                    .clone()\n                    .reset_limit()\n                    .reset_offset()\n                    .clear_order_by()\n                    .to_owned(),\n                \"sub_query\",\n            )\n            .to_owned();\n        let result = match self.db.query_one(&query)? {\n            Some(res) => res,\n            None => return Ok(0),\n        };\n        #[allow(clippy::match_single_binding)]\n        let num_items = match self.db.get_database_backend() {\n            _ => result.try_get::<i64>(\"\", \"num_items\")? as u64,\n        };\n        Ok(num_items)\n    }\n\n    /// Get the total number of pages\n    pub fn num_pages(&self) -> Result<u64, DbErr> {\n        let num_items = self.num_items()?;\n        let num_pages = self.compute_pages_number(num_items);\n        Ok(num_pages)\n    }\n\n    /// Get the total number of items and pages\n    pub fn num_items_and_pages(&self) -> Result<ItemsAndPagesNumber, DbErr> {\n        let number_of_items = self.num_items()?;\n        let number_of_pages = self.compute_pages_number(number_of_items);\n\n        Ok(ItemsAndPagesNumber {\n            number_of_items,\n            number_of_pages,\n        })\n    }\n\n    /// Compute the number of pages for the current page\n    fn compute_pages_number(&self, num_items: u64) -> u64 {\n        (num_items / self.page_size) + (num_items % self.page_size > 0) as u64\n    }\n\n    /// Increment the page counter\n    pub fn next(&mut self) {\n        self.page += 1;\n    }\n\n    /// Get current page number\n    pub fn cur_page(&self) -> u64 {\n        self.page\n    }\n\n    /// Fetch one page and increment the page counter\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let owned_db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         vec![cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Cake\".to_owned(),\n    /// #         }],\n    /// #         vec![],\n    /// #     ])\n    /// #     .into_connection();\n    /// # let db = &owned_db;\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    /// let mut cake_pages = cake::Entity::find()\n    ///     .order_by_asc(cake::Column::Id)\n    ///     .paginate(db, 50);\n    ///\n    /// while let Some(cakes) = cake_pages.fetch_and_next()? {\n    ///     // Do something on cakes: Vec<cake::Model>\n    /// }\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn fetch_and_next(&mut self) -> Result<Option<Vec<S::Item>>, DbErr> {\n        let vec = self.fetch()?;\n        self.next();\n        let opt = if !vec.is_empty() { Some(vec) } else { None };\n        Ok(opt)\n    }\n\n    /// Convert self into an stream\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(all(feature = \"mock\", not(feature = \"sync\")))]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let owned_db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         vec![cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Cake\".to_owned(),\n    /// #         }],\n    /// #         vec![],\n    /// #     ])\n    /// #     .into_connection();\n    /// # let db = &owned_db;\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    /// let mut cake_stream = cake::Entity::find()\n    ///     .order_by_asc(cake::Column::Id)\n    ///     .paginate(db, 50)\n    ///     .into_stream();\n    ///\n    /// while let Some(cakes) = cake_stream.try_next()? {\n    ///     // Do something on cakes: Vec<cake::Model>\n    /// }\n    /// #\n    /// # Ok(())\n    /// # }\n    /// # #[cfg(all(feature = \"mock\", feature = \"sync\"))]\n    /// # fn main() {}\n    /// ```\n    /// (for SeaORM Sync)\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// # #[cfg(all(feature = \"mock\", feature = \"sync\"))]\n    /// # fn example() -> Result<(), DbErr> {\n    /// #\n    /// # let owned_db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         vec![cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Cake\".to_owned(),\n    /// #         }],\n    /// #         vec![],\n    /// #     ])\n    /// #     .into_connection();\n    /// # let db = &owned_db;\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    /// let mut cake_stream = cake::Entity::find()\n    ///     .order_by_asc(cake::Column::Id)\n    ///     .paginate(db, 50)\n    ///     .into_stream();\n    ///\n    /// while let Some(cakes) = cake_stream.next() {\n    ///     // Do something on cakes: Vec<cake::Model>\n    /// }\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn into_stream(self) -> PinBoxStream<'db, Result<Vec<S::Item>, DbErr>> {\n        #[cfg(not(feature = \"sync\"))]\n        {\n            let mut streamer = self;\n            Box::new(stream! {\n                while let Some(vec) = streamer.fetch_and_next()? {\n                    yield Ok(vec);\n                }\n            })\n        }\n        #[cfg(feature = \"sync\")]\n        {\n            Box::new(PaginatorStream { paginator: self })\n        }\n    }\n}\n\n#[cfg(feature = \"sync\")]\n#[derive(Debug)]\n/// Stream items by page\npub struct PaginatorStream<'db, C, S>\nwhere\n    C: ConnectionTrait,\n    S: SelectorTrait + 'db,\n{\n    paginator: Paginator<'db, C, S>,\n}\n\n/// A Trait for any type that can paginate results\npub trait PaginatorTrait<'db, C>\nwhere\n    C: ConnectionTrait,\n{\n    /// Select operation\n    type Selector: SelectorTrait + 'db;\n\n    /// Paginate the result of a select operation.\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector>;\n\n    /// Perform a count on the paginated results\n    fn count(self, db: &'db C) -> Result<u64, DbErr>\n    where\n        Self: Sized,\n    {\n        self.paginate(db, 1).num_items()\n    }\n}\n\nimpl<'db, C, S> PaginatorTrait<'db, C> for Selector<S>\nwhere\n    C: ConnectionTrait,\n    S: SelectorTrait + 'db,\n{\n    type Selector = S;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, S> {\n        assert!(page_size != 0, \"page_size should not be zero\");\n        Paginator {\n            query: self.query,\n            page: 0,\n            page_size,\n            db,\n            selector: PhantomData,\n        }\n    }\n}\n\nimpl<'db, C, S> PaginatorTrait<'db, C> for SelectorRaw<S>\nwhere\n    C: ConnectionTrait,\n    S: SelectorTrait + 'db,\n{\n    type Selector = S;\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, S> {\n        assert!(page_size != 0, \"page_size should not be zero\");\n        let sql = self.stmt.sql.trim()[6..].trim().to_owned();\n        let mut query = SelectStatement::new();\n        query.expr(if let Some(values) = self.stmt.values {\n            Expr::cust_with_values(sql, values.0)\n        } else {\n            Expr::cust(sql)\n        });\n\n        Paginator {\n            query,\n            page: 0,\n            page_size,\n            db,\n            selector: PhantomData,\n        }\n    }\n}\n\nimpl<'db, C, M, E> PaginatorTrait<'db, C> for Select<E>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait<Model = M>,\n    M: FromQueryResult + Sized + 'db,\n{\n    type Selector = SelectModel<M>;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {\n        self.into_model().paginate(db, page_size)\n    }\n}\n\nimpl<'db, C, M, N, E, F> PaginatorTrait<'db, C> for SelectTwo<E, F>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait<Model = M>,\n    F: EntityTrait<Model = N>,\n    M: FromQueryResult + Sized + 'db,\n    N: FromQueryResult + Sized + 'db,\n{\n    type Selector = SelectTwoModel<M, N>;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {\n        self.into_model().paginate(db, page_size)\n    }\n}\n\n#[cfg(feature = \"sync\")]\nimpl<'db, C, S> Iterator for PaginatorStream<'db, C, S>\nwhere\n    C: ConnectionTrait,\n    S: SelectorTrait + 'db,\n{\n    type Item = Result<Vec<S::Item>, DbErr>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        match self.paginator.fetch_and_next() {\n            Ok(Some(vec)) => Some(Ok(vec)),\n            Ok(None) => None,\n            Err(e) => Some(Err(e)),\n        }\n    }\n}\n\n#[cfg(test)]\n#[cfg(feature = \"mock\")]\nmod tests {\n    use super::*;\n    use crate::entity::prelude::*;\n    #[cfg(feature = \"sync\")]\n    use crate::util::StreamShim;\n    use crate::{DatabaseConnection, DbBackend, MockDatabase, Transaction};\n    use crate::{QueryOrder, QuerySelect};\n    use crate::{Statement, tests_cfg::*};\n    use pretty_assertions::assert_eq;\n    use sea_query::{Expr, SelectStatement, Value};\n    use std::sync::LazyLock;\n\n    static RAW_STMT: LazyLock<Statement> = LazyLock::new(|| {\n        Statement::from_sql_and_values(\n            DbBackend::Postgres,\n            r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\"\"#,\n            [],\n        )\n    });\n\n    fn setup() -> (DatabaseConnection, Vec<Vec<fruit::Model>>) {\n        let page1 = vec![\n            fruit::Model {\n                id: 1,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            },\n            fruit::Model {\n                id: 2,\n                name: \"Raspberry\".into(),\n                cake_id: Some(1),\n            },\n        ];\n\n        let page2 = vec![fruit::Model {\n            id: 3,\n            name: \"Strawberry\".into(),\n            cake_id: Some(2),\n        }];\n\n        let page3 = Vec::<fruit::Model>::new();\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([page1.clone(), page2.clone(), page3.clone()])\n            .into_connection();\n\n        (db, vec![page1, page2, page3])\n    }\n\n    fn setup_num_items() -> (DatabaseConnection, i64) {\n        let num_items = 3;\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[maplit::btreemap! {\n                \"num_items\" => Into::<Value>::into(num_items),\n            }]])\n            .into_connection();\n\n        (db, num_items)\n    }\n\n    #[test]\n    fn fetch_page() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let paginator = fruit::Entity::find().paginate(&db, 2);\n\n        assert_eq!(paginator.fetch_page(0)?, pages[0].clone());\n        assert_eq!(paginator.fetch_page(1)?, pages[1].clone());\n        assert_eq!(paginator.fetch_page(2)?, pages[2].clone());\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[test]\n    fn fetch_page_raw() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let paginator = fruit::Entity::find()\n            .from_raw_sql(RAW_STMT.clone())\n            .paginate(&db, 2);\n\n        assert_eq!(paginator.fetch_page(0)?, pages[0].clone());\n        assert_eq!(paginator.fetch_page(1)?, pages[1].clone());\n        assert_eq!(paginator.fetch_page(2)?, pages[2].clone());\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[test]\n    fn fetch() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let mut paginator = fruit::Entity::find().paginate(&db, 2);\n\n        assert_eq!(paginator.fetch()?, pages[0].clone());\n        paginator.next();\n\n        assert_eq!(paginator.fetch()?, pages[1].clone());\n        paginator.next();\n\n        assert_eq!(paginator.fetch()?, pages[2].clone());\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[test]\n    fn fetch_raw() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let mut paginator = fruit::Entity::find()\n            .from_raw_sql(RAW_STMT.clone())\n            .paginate(&db, 2);\n\n        assert_eq!(paginator.fetch()?, pages[0].clone());\n        paginator.next();\n\n        assert_eq!(paginator.fetch()?, pages[1].clone());\n        paginator.next();\n\n        assert_eq!(paginator.fetch()?, pages[2].clone());\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[test]\n    fn num_pages() -> Result<(), DbErr> {\n        let (db, num_items) = setup_num_items();\n\n        let num_items = num_items as u64;\n        let page_size = 2_u64;\n        let num_pages = (num_items / page_size) + (num_items % page_size > 0) as u64;\n        let paginator = fruit::Entity::find().paginate(&db, page_size);\n\n        assert_eq!(paginator.num_pages()?, num_pages);\n\n        let sub_query = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let select = SelectStatement::new()\n            .expr(Expr::cust(\"COUNT(*) AS num_items\"))\n            .from_subquery(sub_query, \"sub_query\")\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [query_builder.build(&select)];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[test]\n    fn num_pages_raw() -> Result<(), DbErr> {\n        let (db, num_items) = setup_num_items();\n\n        let num_items = num_items as u64;\n        let page_size = 2_u64;\n        let num_pages = (num_items / page_size) + (num_items % page_size > 0) as u64;\n        let paginator = fruit::Entity::find()\n            .from_raw_sql(RAW_STMT.clone())\n            .paginate(&db, page_size);\n\n        assert_eq!(paginator.num_pages()?, num_pages);\n\n        let sub_query = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let select = SelectStatement::new()\n            .expr(Expr::cust(\"COUNT(*) AS num_items\"))\n            .from_subquery(sub_query, \"sub_query\")\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [query_builder.build(&select)];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[test]\n    fn next_and_cur_page() -> Result<(), DbErr> {\n        let (db, _) = setup();\n\n        let mut paginator = fruit::Entity::find().paginate(&db, 2);\n\n        assert_eq!(paginator.cur_page(), 0);\n        paginator.next();\n\n        assert_eq!(paginator.cur_page(), 1);\n        paginator.next();\n\n        assert_eq!(paginator.cur_page(), 2);\n        Ok(())\n    }\n\n    #[test]\n    fn next_and_cur_page_raw() -> Result<(), DbErr> {\n        let (db, _) = setup();\n\n        let mut paginator = fruit::Entity::find()\n            .from_raw_sql(RAW_STMT.clone())\n            .paginate(&db, 2);\n\n        assert_eq!(paginator.cur_page(), 0);\n        paginator.next();\n\n        assert_eq!(paginator.cur_page(), 1);\n        paginator.next();\n\n        assert_eq!(paginator.cur_page(), 2);\n        Ok(())\n    }\n\n    #[test]\n    fn fetch_and_next() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let mut paginator = fruit::Entity::find().paginate(&db, 2);\n\n        assert_eq!(paginator.cur_page(), 0);\n        assert_eq!(paginator.fetch_and_next()?, Some(pages[0].clone()));\n\n        assert_eq!(paginator.cur_page(), 1);\n        assert_eq!(paginator.fetch_and_next()?, Some(pages[1].clone()));\n\n        assert_eq!(paginator.cur_page(), 2);\n        assert_eq!(paginator.fetch_and_next()?, None);\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[test]\n    fn fetch_and_next_raw() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let mut paginator = fruit::Entity::find()\n            .from_raw_sql(RAW_STMT.clone())\n            .paginate(&db, 2);\n\n        assert_eq!(paginator.cur_page(), 0);\n        assert_eq!(paginator.fetch_and_next()?, Some(pages[0].clone()));\n\n        assert_eq!(paginator.cur_page(), 1);\n        assert_eq!(paginator.fetch_and_next()?, Some(pages[1].clone()));\n\n        assert_eq!(paginator.cur_page(), 2);\n        assert_eq!(paginator.fetch_and_next()?, None);\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[test]\n    fn into_stream() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let mut fruit_stream = fruit::Entity::find().paginate(&db, 2).into_stream();\n\n        assert_eq!(fruit_stream.try_next()?, Some(pages[0].clone()));\n        assert_eq!(fruit_stream.try_next()?, Some(pages[1].clone()));\n        assert_eq!(fruit_stream.try_next()?, None);\n\n        drop(fruit_stream);\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[test]\n    fn into_stream_raw() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let mut fruit_stream = fruit::Entity::find()\n            .from_raw_sql(RAW_STMT.clone())\n            .paginate(&db, 2)\n            .into_stream();\n\n        assert_eq!(fruit_stream.try_next()?, Some(pages[0].clone()));\n        assert_eq!(fruit_stream.try_next()?, Some(pages[1].clone()));\n        assert_eq!(fruit_stream.try_next()?, None);\n\n        drop(fruit_stream);\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[test]\n    fn into_stream_raw_leading_spaces() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let raw_stmt = Statement::from_sql_and_values(\n            DbBackend::Postgres,\n            r#\"  SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\"  \"#,\n            [],\n        );\n\n        let mut fruit_stream = fruit::Entity::find()\n            .from_raw_sql(raw_stmt.clone())\n            .paginate(&db, 2)\n            .into_stream();\n\n        assert_eq!(fruit_stream.try_next()?, Some(pages[0].clone()));\n        assert_eq!(fruit_stream.try_next()?, Some(pages[1].clone()));\n        assert_eq!(fruit_stream.try_next()?, None);\n\n        drop(fruit_stream);\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[test]\n    #[should_panic]\n    fn error() {\n        let (db, _pages) = setup();\n\n        fruit::Entity::find().paginate(&db, 0);\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/query.rs",
    "content": "pub use crate::error::TryGetError;\nuse crate::{\n    SelectGetableValue, SelectorRaw, Statement,\n    error::{DbErr, type_err},\n};\nuse std::{fmt::Debug, marker::PhantomData, sync::Arc};\n\n#[cfg(any(feature = \"mock\", feature = \"proxy\"))]\nuse crate::debug_print;\n\n#[cfg(feature = \"sqlx-dep\")]\nuse crate::driver::*;\n#[cfg(feature = \"sqlx-dep\")]\nuse sqlx::Row;\n\n/// Defines the result of a query operation on a Model\n#[derive(Debug)]\npub struct QueryResult {\n    pub(crate) row: QueryResultRow,\n}\n\n#[allow(clippy::enum_variant_names)]\npub(crate) enum QueryResultRow {\n    #[cfg(feature = \"sqlx-mysql\")]\n    SqlxMySql(sqlx::mysql::MySqlRow),\n    #[cfg(feature = \"sqlx-postgres\")]\n    SqlxPostgres(sqlx::postgres::PgRow),\n    #[cfg(feature = \"sqlx-sqlite\")]\n    SqlxSqlite(sqlx::sqlite::SqliteRow),\n    #[cfg(feature = \"rusqlite\")]\n    Rusqlite(crate::driver::rusqlite::RusqliteRow),\n    #[cfg(feature = \"mock\")]\n    Mock(crate::MockRow),\n    #[cfg(feature = \"proxy\")]\n    Proxy(crate::ProxyRow),\n}\n\n/// An interface to get a value from the query result\npub trait TryGetable: Sized {\n    /// Get a value from the query result with an ColIdx\n    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError>;\n\n    /// Get a value from the query result with prefixed column name\n    fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {\n        if pre.is_empty() {\n            Self::try_get_by(res, col)\n        } else {\n            Self::try_get_by(res, format!(\"{pre}{col}\").as_str())\n        }\n    }\n\n    /// Get a value from the query result based on the order in the select expressions\n    fn try_get_by_index(res: &QueryResult, index: usize) -> Result<Self, TryGetError> {\n        Self::try_get_by(res, index)\n    }\n}\n\nimpl From<TryGetError> for DbErr {\n    fn from(e: TryGetError) -> DbErr {\n        match e {\n            TryGetError::DbErr(e) => e,\n            TryGetError::Null(s) => {\n                type_err(format!(\"A null value was encountered while decoding {s}\"))\n            }\n        }\n    }\n}\n\nimpl From<DbErr> for TryGetError {\n    fn from(e: DbErr) -> TryGetError {\n        Self::DbErr(e)\n    }\n}\n\n// QueryResult //\n\nimpl QueryResult {\n    /// Get a value from the query result with an ColIdx\n    pub fn try_get_by<T, I>(&self, index: I) -> Result<T, DbErr>\n    where\n        T: TryGetable,\n        I: ColIdx,\n    {\n        Ok(T::try_get_by(self, index)?)\n    }\n\n    /// Get a value from the query result with an ColIdx\n    pub fn try_get_by_nullable<T, I>(&self, index: I) -> Result<T, TryGetError>\n    where\n        T: TryGetable,\n        I: ColIdx,\n    {\n        T::try_get_by(self, index)\n    }\n\n    /// Get a value from the query result with prefixed column name\n    pub fn try_get<T>(&self, pre: &str, col: &str) -> Result<T, DbErr>\n    where\n        T: TryGetable,\n    {\n        Ok(T::try_get(self, pre, col)?)\n    }\n\n    /// Get a value from the query result with prefixed column name\n    pub fn try_get_nullable<T>(&self, pre: &str, col: &str) -> Result<T, TryGetError>\n    where\n        T: TryGetable,\n    {\n        T::try_get(self, pre, col)\n    }\n\n    /// Get a value from the query result based on the order in the select expressions\n    pub fn try_get_by_index<T>(&self, idx: usize) -> Result<T, DbErr>\n    where\n        T: TryGetable,\n    {\n        Ok(T::try_get_by_index(self, idx)?)\n    }\n\n    /// Get a value from the query result based on the order in the select expressions\n    pub fn try_get_by_index_nullable<T>(&self, idx: usize) -> Result<T, TryGetError>\n    where\n        T: TryGetable,\n    {\n        T::try_get_by_index(self, idx)\n    }\n\n    /// Get a tuple value from the query result with prefixed column name\n    pub fn try_get_many<T>(&self, pre: &str, cols: &[String]) -> Result<T, DbErr>\n    where\n        T: TryGetableMany,\n    {\n        Ok(T::try_get_many(self, pre, cols)?)\n    }\n\n    /// Get a tuple value from the query result based on the order in the select expressions\n    pub fn try_get_many_by_index<T>(&self) -> Result<T, DbErr>\n    where\n        T: TryGetableMany,\n    {\n        Ok(T::try_get_many_by_index(self)?)\n    }\n\n    /// Retrieves the names of the columns in the result set\n    pub fn column_names(&self) -> Vec<String> {\n        #[cfg(feature = \"sqlx-dep\")]\n        use sqlx::Column;\n\n        match &self.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(row) => {\n                row.columns().iter().map(|c| c.name().to_string()).collect()\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => {\n                row.columns().iter().map(|c| c.name().to_string()).collect()\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(row) => {\n                row.columns().iter().map(|c| c.name().to_string()).collect()\n            }\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(row) => row.columns().iter().map(|c| c.to_string()).collect(),\n            #[cfg(feature = \"mock\")]\n            QueryResultRow::Mock(row) => row\n                .clone()\n                .into_column_value_tuples()\n                .map(|(c, _)| c.to_string())\n                .collect(),\n            #[cfg(feature = \"proxy\")]\n            QueryResultRow::Proxy(row) => row\n                .clone()\n                .into_column_value_tuples()\n                .map(|(c, _)| c.to_string())\n                .collect(),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n\n    /// Access the underlying `MySqlRow` if we use the MySQL backend.\n    #[cfg(feature = \"sqlx-mysql\")]\n    pub fn try_as_mysql_row(&self) -> Option<&sqlx::mysql::MySqlRow> {\n        match &self.row {\n            QueryResultRow::SqlxMySql(mysql_row) => Some(mysql_row),\n            #[allow(unreachable_patterns)]\n            _ => None,\n        }\n    }\n\n    /// Access the underlying `PgRow` if we use the Postgres backend.\n    #[cfg(feature = \"sqlx-postgres\")]\n    pub fn try_as_pg_row(&self) -> Option<&sqlx::postgres::PgRow> {\n        match &self.row {\n            QueryResultRow::SqlxPostgres(pg_row) => Some(pg_row),\n            #[allow(unreachable_patterns)]\n            _ => None,\n        }\n    }\n\n    /// Access the underlying `SqliteRow` if we use the SQLite backend.\n    #[cfg(feature = \"sqlx-sqlite\")]\n    pub fn try_as_sqlite_row(&self) -> Option<&sqlx::sqlite::SqliteRow> {\n        match &self.row {\n            QueryResultRow::SqlxSqlite(sqlite_row) => Some(sqlite_row),\n            #[allow(unreachable_patterns)]\n            _ => None,\n        }\n    }\n\n    /// Access the underlying `MockRow` if we use a mock.\n    #[cfg(feature = \"mock\")]\n    pub fn try_as_mock_row(&self) -> Option<&crate::MockRow> {\n        match &self.row {\n            QueryResultRow::Mock(mock_row) => Some(mock_row),\n            #[allow(unreachable_patterns)]\n            _ => None,\n        }\n    }\n\n    /// Access the underlying `ProxyRow` if we use a proxy.\n    #[cfg(feature = \"proxy\")]\n    pub fn try_as_proxy_row(&self) -> Option<&crate::ProxyRow> {\n        match &self.row {\n            QueryResultRow::Proxy(proxy_row) => Some(proxy_row),\n            #[allow(unreachable_patterns)]\n            _ => None,\n        }\n    }\n}\n\n#[allow(unused_variables)]\nimpl Debug for QueryResultRow {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        match self {\n            #[cfg(feature = \"sqlx-mysql\")]\n            Self::SqlxMySql(row) => write!(f, \"{row:?}\"),\n            #[cfg(feature = \"sqlx-postgres\")]\n            Self::SqlxPostgres(_) => write!(f, \"QueryResultRow::SqlxPostgres cannot be inspected\"),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            Self::SqlxSqlite(_) => write!(f, \"QueryResultRow::SqlxSqlite cannot be inspected\"),\n            #[cfg(feature = \"rusqlite\")]\n            Self::Rusqlite(row) => write!(f, \"{row:?}\"),\n            #[cfg(feature = \"mock\")]\n            Self::Mock(row) => write!(f, \"{row:?}\"),\n            #[cfg(feature = \"proxy\")]\n            Self::Proxy(row) => write!(f, \"{row:?}\"),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\n// TryGetable //\n\nimpl<T: TryGetable> TryGetable for Option<T> {\n    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError> {\n        match T::try_get_by(res, index) {\n            Ok(v) => Ok(Some(v)),\n            Err(TryGetError::Null(_)) => Ok(None),\n            #[cfg(feature = \"sqlx-dep\")]\n            Err(TryGetError::DbErr(DbErr::Query(crate::RuntimeErr::SqlxError(err)))) => {\n                use std::ops::Deref;\n                match err.deref() {\n                    sqlx::Error::ColumnNotFound(_) => Ok(None),\n                    _ => Err(TryGetError::DbErr(DbErr::Query(\n                        crate::RuntimeErr::SqlxError(err),\n                    ))),\n                }\n            }\n            Err(e) => Err(e),\n        }\n    }\n}\n\n/// Column Index, used by [`TryGetable`]. Implemented for `&str` and `usize`\npub trait ColIdx: Debug + Copy {\n    #[cfg(feature = \"sqlx-mysql\")]\n    /// Type surrogate\n    type SqlxMySqlIndex: sqlx::ColumnIndex<sqlx::mysql::MySqlRow>;\n    #[cfg(feature = \"sqlx-postgres\")]\n    /// Type surrogate\n    type SqlxPostgresIndex: sqlx::ColumnIndex<sqlx::postgres::PgRow>;\n    #[cfg(feature = \"sqlx-sqlite\")]\n    /// Type surrogate\n    type SqlxSqliteIndex: sqlx::ColumnIndex<sqlx::sqlite::SqliteRow>;\n\n    #[cfg(feature = \"sqlx-mysql\")]\n    /// Basically a no-op; only to satisfy trait bounds\n    fn as_sqlx_mysql_index(&self) -> Self::SqlxMySqlIndex;\n    #[cfg(feature = \"sqlx-postgres\")]\n    /// Basically a no-op; only to satisfy trait bounds\n    fn as_sqlx_postgres_index(&self) -> Self::SqlxPostgresIndex;\n    #[cfg(feature = \"sqlx-sqlite\")]\n    /// Basically a no-op; only to satisfy trait bounds\n    fn as_sqlx_sqlite_index(&self) -> Self::SqlxSqliteIndex;\n\n    /// Self must be `&str`, return `None` otherwise\n    fn as_str(&self) -> Option<&str>;\n    /// Self must be `usize`, return `None` otherwise\n    fn as_usize(&self) -> Option<&usize>;\n}\n\nimpl ColIdx for &str {\n    #[cfg(feature = \"sqlx-mysql\")]\n    type SqlxMySqlIndex = Self;\n    #[cfg(feature = \"sqlx-postgres\")]\n    type SqlxPostgresIndex = Self;\n    #[cfg(feature = \"sqlx-sqlite\")]\n    type SqlxSqliteIndex = Self;\n\n    #[cfg(feature = \"sqlx-mysql\")]\n    #[inline]\n    fn as_sqlx_mysql_index(&self) -> Self::SqlxMySqlIndex {\n        self\n    }\n    #[cfg(feature = \"sqlx-postgres\")]\n    #[inline]\n    fn as_sqlx_postgres_index(&self) -> Self::SqlxPostgresIndex {\n        self\n    }\n    #[cfg(feature = \"sqlx-sqlite\")]\n    #[inline]\n    fn as_sqlx_sqlite_index(&self) -> Self::SqlxSqliteIndex {\n        self\n    }\n\n    #[inline]\n    fn as_str(&self) -> Option<&str> {\n        Some(self)\n    }\n    #[inline]\n    fn as_usize(&self) -> Option<&usize> {\n        None\n    }\n}\n\nimpl ColIdx for usize {\n    #[cfg(feature = \"sqlx-mysql\")]\n    type SqlxMySqlIndex = Self;\n    #[cfg(feature = \"sqlx-postgres\")]\n    type SqlxPostgresIndex = Self;\n    #[cfg(feature = \"sqlx-sqlite\")]\n    type SqlxSqliteIndex = Self;\n\n    #[cfg(feature = \"sqlx-mysql\")]\n    #[inline]\n    fn as_sqlx_mysql_index(&self) -> Self::SqlxMySqlIndex {\n        *self\n    }\n    #[cfg(feature = \"sqlx-postgres\")]\n    #[inline]\n    fn as_sqlx_postgres_index(&self) -> Self::SqlxPostgresIndex {\n        *self\n    }\n    #[cfg(feature = \"sqlx-sqlite\")]\n    #[inline]\n    fn as_sqlx_sqlite_index(&self) -> Self::SqlxSqliteIndex {\n        *self\n    }\n\n    #[inline]\n    fn as_str(&self) -> Option<&str> {\n        None\n    }\n    #[inline]\n    fn as_usize(&self) -> Option<&usize> {\n        Some(self)\n    }\n}\n\nmacro_rules! try_getable_all {\n    ( $type: ty ) => {\n        impl TryGetable for $type {\n            #[allow(unused_variables)]\n            fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                match &res.row {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    QueryResultRow::SqlxMySql(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_mysql_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    QueryResultRow::SqlxPostgres(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_postgres_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    QueryResultRow::SqlxSqlite(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_sqlite_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"rusqlite\")]\n                    QueryResultRow::Rusqlite(row) => row\n                        .try_get::<Option<$type>, _>(idx)\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"mock\")]\n                    QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[cfg(feature = \"proxy\")]\n                    QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[allow(unreachable_patterns)]\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\nmacro_rules! try_getable_unsigned {\n    ( $type: ty ) => {\n        impl TryGetable for $type {\n            #[allow(unused_variables)]\n            fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                match &res.row {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    QueryResultRow::SqlxMySql(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_mysql_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    QueryResultRow::SqlxPostgres(_) => Err(type_err(format!(\n                        \"{} unsupported by sqlx-postgres\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    QueryResultRow::SqlxSqlite(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_sqlite_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"rusqlite\")]\n                    QueryResultRow::Rusqlite(row) => row\n                        .try_get::<Option<$type>, _>(idx)\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"mock\")]\n                    QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[cfg(feature = \"proxy\")]\n                    QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[allow(unreachable_patterns)]\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\nmacro_rules! try_getable_mysql {\n    ( $type: ty ) => {\n        impl TryGetable for $type {\n            #[allow(unused_variables)]\n            fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                match &res.row {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    QueryResultRow::SqlxMySql(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_mysql_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    QueryResultRow::SqlxPostgres(_) => Err(type_err(format!(\n                        \"{} unsupported by sqlx-postgres\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    QueryResultRow::SqlxSqlite(_) => Err(type_err(format!(\n                        \"{} unsupported by sqlx-sqlite\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"rusqlite\")]\n                    QueryResultRow::Rusqlite(row) => Err(type_err(format!(\n                        \"{} unsupported by rusqlite\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"mock\")]\n                    QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[cfg(feature = \"proxy\")]\n                    QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[allow(unreachable_patterns)]\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\n#[allow(unused_macros)]\nmacro_rules! try_getable_postgres {\n    ( $type: ty ) => {\n        impl TryGetable for $type {\n            #[allow(unused_variables)]\n            fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                match &res.row {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    QueryResultRow::SqlxMySql(_) => Err(type_err(format!(\n                        \"{} unsupported by sqlx-mysql\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    QueryResultRow::SqlxPostgres(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_postgres_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    QueryResultRow::SqlxSqlite(_) => Err(type_err(format!(\n                        \"{} unsupported by sqlx-sqlite\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"rusqlite\")]\n                    QueryResultRow::Rusqlite(row) => Err(type_err(format!(\n                        \"{} unsupported by rusqlite\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"mock\")]\n                    QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[cfg(feature = \"proxy\")]\n                    QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[allow(unreachable_patterns)]\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\n#[allow(unused_macros)]\nmacro_rules! try_getable_date_time {\n    ( $type: ty ) => {\n        impl TryGetable for $type {\n            #[allow(unused_variables)]\n            fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                match &res.row {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    QueryResultRow::SqlxMySql(row) => {\n                        use chrono::{DateTime, Utc};\n                        row.try_get::<Option<DateTime<Utc>>, _>(idx.as_sqlx_mysql_index())\n                            .map_err(|e| sqlx_error_to_query_err(e).into())\n                            .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                            .map(|v| v.into())\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    QueryResultRow::SqlxPostgres(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_postgres_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    QueryResultRow::SqlxSqlite(row) => {\n                        use chrono::{DateTime, Utc};\n                        row.try_get::<Option<DateTime<Utc>>, _>(idx.as_sqlx_sqlite_index())\n                            .map_err(|e| sqlx_error_to_query_err(e).into())\n                            .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                            .map(|v| v.into())\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    QueryResultRow::Rusqlite(row) => {\n                        use chrono::{DateTime, Utc};\n                        row.try_get::<Option<DateTime<Utc>>, _>(idx)\n                            .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                            .map(|v| v.into())\n                    }\n                    #[cfg(feature = \"mock\")]\n                    QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[cfg(feature = \"proxy\")]\n                    QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[allow(unreachable_patterns)]\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\ntry_getable_all!(bool);\ntry_getable_all!(i8);\ntry_getable_all!(i16);\ntry_getable_all!(i32);\ntry_getable_all!(i64);\ntry_getable_unsigned!(u8);\ntry_getable_unsigned!(u16);\ntry_getable_mysql!(u64);\ntry_getable_all!(f32);\ntry_getable_all!(f64);\ntry_getable_all!(Vec<u8>);\n\n#[cfg(feature = \"with-json\")]\ntry_getable_all!(serde_json::Value);\n\n#[cfg(feature = \"with-chrono\")]\ntry_getable_all!(chrono::NaiveDate);\n\n#[cfg(feature = \"with-chrono\")]\ntry_getable_all!(chrono::NaiveTime);\n\n#[cfg(feature = \"with-chrono\")]\ntry_getable_all!(chrono::NaiveDateTime);\n\n#[cfg(feature = \"with-chrono\")]\ntry_getable_date_time!(chrono::DateTime<chrono::FixedOffset>);\n\n#[cfg(feature = \"with-chrono\")]\ntry_getable_all!(chrono::DateTime<chrono::Utc>);\n\n#[cfg(feature = \"with-chrono\")]\ntry_getable_all!(chrono::DateTime<chrono::Local>);\n\n#[cfg(feature = \"with-time\")]\ntry_getable_all!(time::Date);\n\n#[cfg(feature = \"with-time\")]\ntry_getable_all!(time::Time);\n\n#[cfg(feature = \"with-time\")]\ntry_getable_all!(time::PrimitiveDateTime);\n\n#[cfg(feature = \"with-time\")]\ntry_getable_all!(time::OffsetDateTime);\n\n#[cfg(feature = \"with-rust_decimal\")]\nuse rust_decimal::Decimal;\n\n#[cfg(feature = \"with-rust_decimal\")]\nimpl TryGetable for Decimal {\n    #[allow(unused_variables)]\n    fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(row) => row\n                .try_get::<Option<Decimal>, _>(idx.as_sqlx_mysql_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => row\n                .try_get::<Option<Decimal>, _>(idx.as_sqlx_postgres_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(row) => {\n                let val: Option<f64> = row\n                    .try_get(idx.as_sqlx_sqlite_index())\n                    .map_err(sqlx_error_to_query_err)?;\n                match val {\n                    Some(v) => Decimal::try_from(v).map_err(|e| {\n                        DbErr::TryIntoErr {\n                            from: \"f64\",\n                            into: \"Decimal\",\n                            source: Arc::new(e),\n                        }\n                        .into()\n                    }),\n                    None => Err(err_null_idx_col(idx)),\n                }\n            }\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(row) => {\n                let val: Option<f64> = row.try_get(idx)?;\n                match val {\n                    Some(v) => Decimal::try_from(v).map_err(|e| {\n                        DbErr::TryIntoErr {\n                            from: \"f64\",\n                            into: \"Decimal\",\n                            source: Arc::new(e),\n                        }\n                        .into()\n                    }),\n                    None => Err(err_null_idx_col(idx)),\n                }\n            }\n            #[cfg(feature = \"mock\")]\n            #[allow(unused_variables)]\n            QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[cfg(feature = \"proxy\")]\n            #[allow(unused_variables)]\n            QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(feature = \"with-bigdecimal\")]\nuse bigdecimal::BigDecimal;\n\n#[cfg(feature = \"with-bigdecimal\")]\nimpl TryGetable for BigDecimal {\n    #[allow(unused_variables)]\n    fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(row) => row\n                .try_get::<Option<BigDecimal>, _>(idx.as_sqlx_mysql_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => row\n                .try_get::<Option<BigDecimal>, _>(idx.as_sqlx_postgres_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(row) => {\n                let val: Option<f64> = row\n                    .try_get(idx.as_sqlx_sqlite_index())\n                    .map_err(sqlx_error_to_query_err)?;\n                match val {\n                    Some(v) => BigDecimal::try_from(v).map_err(|e| {\n                        DbErr::TryIntoErr {\n                            from: \"f64\",\n                            into: \"BigDecimal\",\n                            source: Arc::new(e),\n                        }\n                        .into()\n                    }),\n                    None => Err(err_null_idx_col(idx)),\n                }\n            }\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(row) => {\n                let val: Option<f64> = row.try_get(idx)?;\n                match val {\n                    Some(v) => BigDecimal::try_from(v).map_err(|e| {\n                        DbErr::TryIntoErr {\n                            from: \"f64\",\n                            into: \"BigDecimal\",\n                            source: Arc::new(e),\n                        }\n                        .into()\n                    }),\n                    None => Err(err_null_idx_col(idx)),\n                }\n            }\n            #[cfg(feature = \"mock\")]\n            #[allow(unused_variables)]\n            QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[cfg(feature = \"proxy\")]\n            #[allow(unused_variables)]\n            QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[allow(unused_macros)]\nmacro_rules! try_getable_uuid {\n    ( $type: ty, $conversion_fn: expr ) => {\n        #[allow(unused_variables, unreachable_code)]\n        impl TryGetable for $type {\n            fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                let res: Result<uuid::Uuid, TryGetError> = match &res.row {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    QueryResultRow::SqlxMySql(row) => row\n                        .try_get::<Option<uuid::Uuid>, _>(idx.as_sqlx_mysql_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                        .or_else(|_| {\n                            // MariaDB's UUID type stores UUIDs as hyphenated strings.\n                            // reference: https://github.com/SeaQL/sea-orm/pull/2485\n                            row.try_get::<Option<Vec<u8>>, _>(idx.as_sqlx_mysql_index())\n                                .map_err(|e| sqlx_error_to_query_err(e).into())\n                                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                                .map(|bytes| {\n                                    String::from_utf8(bytes).map_err(|e| {\n                                        DbErr::TryIntoErr {\n                                            from: \"Vec<u8>\",\n                                            into: \"String\",\n                                            source: Arc::new(e),\n                                        }\n                                        .into()\n                                    })\n                                })?\n                                .and_then(|s| {\n                                    uuid::Uuid::parse_str(&s).map_err(|e| {\n                                        DbErr::TryIntoErr {\n                                            from: \"String\",\n                                            into: \"uuid::Uuid\",\n                                            source: Arc::new(e),\n                                        }\n                                        .into()\n                                    })\n                                })\n                        }),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    QueryResultRow::SqlxPostgres(row) => row\n                        .try_get::<Option<uuid::Uuid>, _>(idx.as_sqlx_postgres_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    QueryResultRow::SqlxSqlite(row) => row\n                        .try_get::<Option<uuid::Uuid>, _>(idx.as_sqlx_sqlite_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"rusqlite\")]\n                    QueryResultRow::Rusqlite(row) => row\n                        .try_get::<Option<uuid::Uuid>, _>(idx)\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"mock\")]\n                    #[allow(unused_variables)]\n                    QueryResultRow::Mock(row) => row.try_get::<uuid::Uuid, _>(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[cfg(feature = \"proxy\")]\n                    #[allow(unused_variables)]\n                    QueryResultRow::Proxy(row) => row.try_get::<uuid::Uuid, _>(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[allow(unreachable_patterns)]\n                    _ => unreachable!(),\n                };\n                res.map($conversion_fn)\n            }\n        }\n    };\n}\n\n#[cfg(feature = \"with-uuid\")]\ntry_getable_uuid!(uuid::Uuid, Into::into);\n\n#[cfg(feature = \"with-uuid\")]\ntry_getable_uuid!(uuid::fmt::Braced, uuid::Uuid::braced);\n\n#[cfg(feature = \"with-uuid\")]\ntry_getable_uuid!(uuid::fmt::Hyphenated, uuid::Uuid::hyphenated);\n\n#[cfg(feature = \"with-uuid\")]\ntry_getable_uuid!(uuid::fmt::Simple, uuid::Uuid::simple);\n\n#[cfg(feature = \"with-uuid\")]\ntry_getable_uuid!(uuid::fmt::Urn, uuid::Uuid::urn);\n\n#[cfg(feature = \"with-ipnetwork\")]\ntry_getable_postgres!(ipnetwork::IpNetwork);\n\nimpl TryGetable for u32 {\n    #[allow(unused_variables)]\n    fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(row) => row\n                .try_get::<Option<u32>, _>(idx.as_sqlx_mysql_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => {\n                use sqlx::postgres::types::Oid;\n                // Since 0.6.0, SQLx has dropped direct mapping from PostgreSQL's OID to Rust's `u32`;\n                // Instead, `u32` was wrapped by a `sqlx::Oid`.\n                match row.try_get::<Option<Oid>, _>(idx.as_sqlx_postgres_index()) {\n                    Ok(opt) => opt.ok_or_else(|| err_null_idx_col(idx)).map(|oid| oid.0),\n                    Err(_) => row\n                        // Integers are always signed in PostgreSQL, so we try to get an `i32` and convert it to `u32`.\n                        .try_get::<i32, _>(idx.as_sqlx_postgres_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .map(|v| {\n                            v.try_into().map_err(|e| {\n                                DbErr::TryIntoErr {\n                                    from: \"i32\",\n                                    into: \"u32\",\n                                    source: Arc::new(e),\n                                }\n                                .into()\n                            })\n                        })\n                        .and_then(|r| r),\n                }\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(row) => row\n                .try_get::<Option<u32>, _>(idx.as_sqlx_sqlite_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(row) => row\n                .try_get::<Option<u32>, _>(idx)\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"mock\")]\n            #[allow(unused_variables)]\n            QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[cfg(feature = \"proxy\")]\n            #[allow(unused_variables)]\n            QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\nimpl TryGetable for String {\n    #[allow(unused_variables)]\n    fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(row) => row\n                .try_get::<Option<Vec<u8>>, _>(idx.as_sqlx_mysql_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                .map(|bytes| {\n                    String::from_utf8(bytes).map_err(|e| {\n                        DbErr::TryIntoErr {\n                            from: \"Vec<u8>\",\n                            into: \"String\",\n                            source: Arc::new(e),\n                        }\n                        .into()\n                    })\n                })?,\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => row\n                .try_get::<Option<String>, _>(idx.as_sqlx_postgres_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(row) => row\n                .try_get::<Option<String>, _>(idx.as_sqlx_sqlite_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(row) => row\n                .try_get::<Option<String>, _>(idx)\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"mock\")]\n            QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[cfg(feature = \"proxy\")]\n            QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[allow(dead_code)]\nfn err_null_idx_col<I: ColIdx>(idx: I) -> TryGetError {\n    TryGetError::Null(format!(\"{idx:?}\"))\n}\n\n#[cfg(feature = \"postgres-array\")]\nmod postgres_array {\n    use super::*;\n\n    #[allow(unused_macros)]\n    macro_rules! try_getable_postgres_array {\n        ( $type: ty ) => {\n            #[allow(unused_variables)]\n            impl TryGetable for Vec<$type> {\n                fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                    match &res.row {\n                        #[cfg(feature = \"sqlx-mysql\")]\n                        QueryResultRow::SqlxMySql(_) => Err(type_err(format!(\n                            \"{} unsupported by sqlx-mysql\",\n                            stringify!($type)\n                        ))\n                        .into()),\n                        #[cfg(feature = \"sqlx-postgres\")]\n                        QueryResultRow::SqlxPostgres(row) => row\n                            .try_get::<Option<Vec<$type>>, _>(idx.as_sqlx_postgres_index())\n                            .map_err(|e| sqlx_error_to_query_err(e).into())\n                            .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                        #[cfg(feature = \"sqlx-sqlite\")]\n                        QueryResultRow::SqlxSqlite(_) => Err(type_err(format!(\n                            \"{} unsupported by sqlx-sqlite\",\n                            stringify!($type)\n                        ))\n                        .into()),\n                        #[cfg(feature = \"rusqlite\")]\n                        QueryResultRow::Rusqlite(_) => Err(type_err(format!(\n                            \"{} unsupported by rusqlite\",\n                            stringify!($type)\n                        ))\n                        .into()),\n                        #[cfg(feature = \"mock\")]\n                        #[allow(unused_variables)]\n                        QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                            debug_print!(\"{:#?}\", e.to_string());\n                            err_null_idx_col(idx)\n                        }),\n                        #[cfg(feature = \"proxy\")]\n                        #[allow(unused_variables)]\n                        QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                            debug_print!(\"{:#?}\", e.to_string());\n                            err_null_idx_col(idx)\n                        }),\n                        #[allow(unreachable_patterns)]\n                        _ => unreachable!(),\n                    }\n                }\n            }\n        };\n    }\n\n    try_getable_postgres_array!(bool);\n    try_getable_postgres_array!(i8);\n    try_getable_postgres_array!(i16);\n    try_getable_postgres_array!(i32);\n    try_getable_postgres_array!(i64);\n    try_getable_postgres_array!(f32);\n    try_getable_postgres_array!(f64);\n    try_getable_postgres_array!(String);\n    try_getable_postgres_array!(Vec<u8>);\n\n    #[cfg(feature = \"with-json\")]\n    try_getable_postgres_array!(serde_json::Value);\n\n    #[cfg(feature = \"with-chrono\")]\n    try_getable_postgres_array!(chrono::NaiveDate);\n\n    #[cfg(feature = \"with-chrono\")]\n    try_getable_postgres_array!(chrono::NaiveTime);\n\n    #[cfg(feature = \"with-chrono\")]\n    try_getable_postgres_array!(chrono::NaiveDateTime);\n\n    #[cfg(feature = \"with-chrono\")]\n    try_getable_postgres_array!(chrono::DateTime<chrono::FixedOffset>);\n\n    #[cfg(feature = \"with-chrono\")]\n    try_getable_postgres_array!(chrono::DateTime<chrono::Utc>);\n\n    #[cfg(feature = \"with-chrono\")]\n    try_getable_postgres_array!(chrono::DateTime<chrono::Local>);\n\n    #[cfg(feature = \"with-time\")]\n    try_getable_postgres_array!(time::Date);\n\n    #[cfg(feature = \"with-time\")]\n    try_getable_postgres_array!(time::Time);\n\n    #[cfg(feature = \"with-time\")]\n    try_getable_postgres_array!(time::PrimitiveDateTime);\n\n    #[cfg(feature = \"with-time\")]\n    try_getable_postgres_array!(time::OffsetDateTime);\n\n    #[cfg(feature = \"with-rust_decimal\")]\n    try_getable_postgres_array!(rust_decimal::Decimal);\n\n    #[cfg(feature = \"with-bigdecimal\")]\n    try_getable_postgres_array!(bigdecimal::BigDecimal);\n\n    #[cfg(feature = \"with-ipnetwork\")]\n    try_getable_postgres_array!(ipnetwork::IpNetwork);\n\n    #[allow(unused_macros)]\n    macro_rules! try_getable_postgres_array_uuid {\n        ( $type: ty, $conversion_fn: expr ) => {\n            #[allow(unused_variables, unreachable_code)]\n            impl TryGetable for Vec<$type> {\n                fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                    let res: Result<Vec<uuid::Uuid>, TryGetError> = match &res.row {\n                        #[cfg(feature = \"sqlx-mysql\")]\n                        QueryResultRow::SqlxMySql(_) => Err(type_err(format!(\n                            \"{} unsupported by sqlx-mysql\",\n                            stringify!($type)\n                        ))\n                        .into()),\n                        #[cfg(feature = \"sqlx-postgres\")]\n                        QueryResultRow::SqlxPostgres(row) => row\n                            .try_get::<Option<Vec<uuid::Uuid>>, _>(idx.as_sqlx_postgres_index())\n                            .map_err(|e| sqlx_error_to_query_err(e).into())\n                            .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                        #[cfg(feature = \"sqlx-sqlite\")]\n                        QueryResultRow::SqlxSqlite(_) => Err(type_err(format!(\n                            \"{} unsupported by sqlx-sqlite\",\n                            stringify!($type)\n                        ))\n                        .into()),\n                        #[cfg(feature = \"rusqlite\")]\n                        QueryResultRow::Rusqlite(_) => Err(type_err(format!(\n                            \"{} unsupported by rusqlite\",\n                            stringify!($type)\n                        ))\n                        .into()),\n                        #[cfg(feature = \"mock\")]\n                        QueryResultRow::Mock(row) => {\n                            row.try_get::<Vec<uuid::Uuid>, _>(idx).map_err(|e| {\n                                debug_print!(\"{:#?}\", e.to_string());\n                                err_null_idx_col(idx)\n                            })\n                        }\n                        #[cfg(feature = \"proxy\")]\n                        QueryResultRow::Proxy(row) => {\n                            row.try_get::<Vec<uuid::Uuid>, _>(idx).map_err(|e| {\n                                debug_print!(\"{:#?}\", e.to_string());\n                                err_null_idx_col(idx)\n                            })\n                        }\n                        #[allow(unreachable_patterns)]\n                        _ => unreachable!(),\n                    };\n                    res.map(|vec| vec.into_iter().map($conversion_fn).collect())\n                }\n            }\n        };\n    }\n\n    #[cfg(feature = \"with-uuid\")]\n    try_getable_postgres_array_uuid!(uuid::Uuid, Into::into);\n\n    #[cfg(feature = \"with-uuid\")]\n    try_getable_postgres_array_uuid!(uuid::fmt::Braced, uuid::Uuid::braced);\n\n    #[cfg(feature = \"with-uuid\")]\n    try_getable_postgres_array_uuid!(uuid::fmt::Hyphenated, uuid::Uuid::hyphenated);\n\n    #[cfg(feature = \"with-uuid\")]\n    try_getable_postgres_array_uuid!(uuid::fmt::Simple, uuid::Uuid::simple);\n\n    #[cfg(feature = \"with-uuid\")]\n    try_getable_postgres_array_uuid!(uuid::fmt::Urn, uuid::Uuid::urn);\n\n    impl TryGetable for Vec<u32> {\n        #[allow(unused_variables)]\n        fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n            match &res.row {\n                #[cfg(feature = \"sqlx-mysql\")]\n                QueryResultRow::SqlxMySql(_) => {\n                    Err(type_err(format!(\"{} unsupported by sqlx-mysql\", stringify!($type))).into())\n                }\n                #[cfg(feature = \"sqlx-postgres\")]\n                QueryResultRow::SqlxPostgres(row) => {\n                    use sqlx::postgres::types::Oid;\n                    // Since 0.6.0, SQLx has dropped direct mapping from PostgreSQL's OID to Rust's `u32`;\n                    // Instead, `u32` was wrapped by a `sqlx::Oid`.\n                    row.try_get::<Option<Vec<Oid>>, _>(idx.as_sqlx_postgres_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                        .map(|oids| oids.into_iter().map(|oid| oid.0).collect())\n                }\n                #[cfg(feature = \"sqlx-sqlite\")]\n                QueryResultRow::SqlxSqlite(_) => Err(type_err(format!(\n                    \"{} unsupported by sqlx-sqlite\",\n                    stringify!($type)\n                ))\n                .into()),\n                #[cfg(feature = \"rusqlite\")]\n                QueryResultRow::Rusqlite(_) => {\n                    Err(type_err(format!(\"{} unsupported by rusqlite\", stringify!($type))).into())\n                }\n                #[cfg(feature = \"mock\")]\n                #[allow(unused_variables)]\n                QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                    debug_print!(\"{:#?}\", e.to_string());\n                    err_null_idx_col(idx)\n                }),\n                #[cfg(feature = \"proxy\")]\n                #[allow(unused_variables)]\n                QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                    debug_print!(\"{:#?}\", e.to_string());\n                    err_null_idx_col(idx)\n                }),\n                #[allow(unreachable_patterns)]\n                _ => unreachable!(),\n            }\n        }\n    }\n}\n\n#[cfg(feature = \"postgres-vector\")]\nimpl TryGetable for pgvector::Vector {\n    #[allow(unused_variables)]\n    fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(_) => {\n                Err(type_err(\"Vector unsupported by sqlx-mysql\").into())\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => row\n                .try_get::<Option<pgvector::Vector>, _>(idx.as_sqlx_postgres_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(_) => {\n                Err(type_err(\"Vector unsupported by sqlx-sqlite\").into())\n            }\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(_) => Err(type_err(\"Vector unsupported by rusqlite\").into()),\n            #[cfg(feature = \"mock\")]\n            QueryResultRow::Mock(row) => row.try_get::<pgvector::Vector, _>(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[cfg(feature = \"proxy\")]\n            QueryResultRow::Proxy(row) => row.try_get::<pgvector::Vector, _>(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\n// TryGetableMany //\n\n/// An interface to get a tuple value from the query result\npub trait TryGetableMany: Sized {\n    /// Get a tuple value from the query result with prefixed column name\n    fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError>;\n\n    /// Get a tuple value from the query result based on the order in the select expressions\n    fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError>;\n\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(all(feature = \"mock\", feature = \"macros\"))]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(1),\n    /// #         },\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"New York Cheese\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(1),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{DeriveIden, EnumIter, TryGetableMany, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// #[derive(EnumIter, DeriveIden)]\n    /// enum ResultCol {\n    ///     Name,\n    ///     NumOfCakes,\n    /// }\n    ///\n    /// let res: Vec<(String, i32)> =\n    ///     <(String, i32)>::find_by_statement::<ResultCol>(Statement::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"name\", count(\"cake\".\"id\") AS \"num_of_cakes\" FROM \"cake\"\"#,\n    ///         [],\n    ///     ))\n    ///     .all(&db)\n    ///     ?;\n    ///\n    /// assert_eq!(\n    ///     res,\n    ///     [\n    ///         (\"Chocolate Forest\".to_owned(), 1),\n    ///         (\"New York Cheese\".to_owned(), 1),\n    ///     ]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"name\", count(\"cake\".\"id\") AS \"num_of_cakes\" FROM \"cake\"\"#,\n    ///         []\n    ///     ),]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn find_by_statement<C>(stmt: Statement) -> SelectorRaw<SelectGetableValue<Self, C>>\n    where\n        C: strum::IntoEnumIterator + sea_query::Iden,\n    {\n        SelectorRaw {\n            stmt,\n            selector: PhantomData,\n        }\n    }\n}\n\nimpl<T> TryGetableMany for T\nwhere\n    T: TryGetable,\n{\n    fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError> {\n        try_get_many_with_slice_len_of(1, cols)?;\n        T::try_get(res, pre, &cols[0])\n    }\n\n    fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {\n        T::try_get_by_index(res, 0)\n    }\n}\n\nimpl<T> TryGetableMany for (T,)\nwhere\n    T: TryGetableMany,\n{\n    fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError> {\n        T::try_get_many(res, pre, cols).map(|r| (r,))\n    }\n\n    fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {\n        T::try_get_many_by_index(res).map(|r| (r,))\n    }\n}\n\nmacro_rules! impl_try_get_many {\n    ( $LEN:expr, $($T:ident : $N:expr),+ $(,)? ) => {\n        impl< $($T),+ > TryGetableMany for ( $($T),+ )\n        where\n            $($T: TryGetable),+\n        {\n            fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError> {\n                try_get_many_with_slice_len_of($LEN, cols)?;\n                Ok((\n                    $($T::try_get(res, pre, &cols[$N])?),+\n                ))\n            }\n\n            fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {\n                Ok((\n                    $($T::try_get_by_index(res, $N)?),+\n                ))\n            }\n        }\n    };\n}\n\n#[rustfmt::skip]\nmod impl_try_get_many {\n    use super::*;\n\n    impl_try_get_many!( 2, T0:0, T1:1);\n    impl_try_get_many!( 3, T0:0, T1:1, T2:2);\n    impl_try_get_many!( 4, T0:0, T1:1, T2:2, T3:3);\n    impl_try_get_many!( 5, T0:0, T1:1, T2:2, T3:3, T4:4);\n    impl_try_get_many!( 6, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5);\n    impl_try_get_many!( 7, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6);\n    impl_try_get_many!( 8, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7);\n    impl_try_get_many!( 9, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8);\n    impl_try_get_many!(10, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9);\n    impl_try_get_many!(11, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9, T10:10);\n    impl_try_get_many!(12, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9, T10:10, T11:11);\n}\n\nfn try_get_many_with_slice_len_of(len: usize, cols: &[String]) -> Result<(), TryGetError> {\n    if cols.len() < len {\n        Err(type_err(format!(\n            \"Expect {} column names supplied but got slice of length {}\",\n            len,\n            cols.len()\n        ))\n        .into())\n    } else {\n        Ok(())\n    }\n}\n\n/// An interface to get an array of values from the query result.\n/// A type can only implement `ActiveEnum` or `TryGetableFromJson`, but not both.\n/// A blanket impl is provided for `TryGetableFromJson`, while the impl for `ActiveEnum`\n/// is provided by the `DeriveActiveEnum` macro. So as an end user you won't normally\n/// touch this trait.\npub trait TryGetableArray: Sized {\n    /// Just a delegate\n    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Vec<Self>, TryGetError>;\n}\n\nimpl<T> TryGetable for Vec<T>\nwhere\n    T: TryGetableArray,\n{\n    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError> {\n        T::try_get_by(res, index)\n    }\n}\n\n// TryGetableFromJson //\n\n/// An interface to get a JSON from the query result\n#[cfg(feature = \"with-json\")]\npub trait TryGetableFromJson: Sized\nwhere\n    for<'de> Self: serde::Deserialize<'de>,\n{\n    /// Get a JSON from the query result with prefixed column name\n    #[allow(unused_variables, unreachable_code)]\n    fn try_get_from_json<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(row) => row\n                .try_get::<Option<sqlx::types::Json<Self>>, _>(idx.as_sqlx_mysql_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)).map(|json| json.0)),\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => row\n                .try_get::<Option<sqlx::types::Json<Self>>, _>(idx.as_sqlx_postgres_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)).map(|json| json.0)),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(row) => row\n                .try_get::<Option<sqlx::types::Json<Self>>, _>(idx.as_sqlx_sqlite_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)).map(|json| json.0)),\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(row) => row\n                .try_get::<Option<serde_json::Value>, _>(idx)?\n                .ok_or_else(|| err_null_idx_col(idx))\n                .and_then(|json| {\n                    serde_json::from_value(json).map_err(|e| crate::error::json_err(e).into())\n                }),\n            #[cfg(feature = \"mock\")]\n            QueryResultRow::Mock(row) => row\n                .try_get::<serde_json::Value, I>(idx)\n                .map_err(|e| {\n                    debug_print!(\"{:#?}\", e.to_string());\n                    err_null_idx_col(idx)\n                })\n                .and_then(|json| {\n                    serde_json::from_value(json).map_err(|e| crate::error::json_err(e).into())\n                }),\n            #[cfg(feature = \"proxy\")]\n            QueryResultRow::Proxy(row) => row\n                .try_get::<serde_json::Value, I>(idx)\n                .map_err(|e| {\n                    debug_print!(\"{:#?}\", e.to_string());\n                    err_null_idx_col(idx)\n                })\n                .and_then(|json| {\n                    serde_json::from_value(json).map_err(|e| crate::error::json_err(e).into())\n                }),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n\n    /// Get a Vec<Self> from an Array of Json\n    fn from_json_vec(value: serde_json::Value) -> Result<Vec<Self>, TryGetError> {\n        match value {\n            serde_json::Value::Array(values) => {\n                let mut res = Vec::new();\n                for item in values {\n                    res.push(serde_json::from_value(item).map_err(crate::error::json_err)?);\n                }\n                Ok(res)\n            }\n            _ => Err(TryGetError::DbErr(DbErr::Json(\n                \"Value is not an Array\".to_owned(),\n            ))),\n        }\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl<T> TryGetable for T\nwhere\n    T: TryGetableFromJson,\n{\n    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError> {\n        T::try_get_from_json(res, index)\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl<T> TryGetableArray for T\nwhere\n    T: TryGetableFromJson,\n{\n    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Vec<T>, TryGetError> {\n        T::from_json_vec(serde_json::Value::try_get_by(res, index)?)\n    }\n}\n\n// TryFromU64 //\n/// Try to convert a type to a u64\npub trait TryFromU64: Sized {\n    /// The method to convert the type to a u64\n    fn try_from_u64(n: u64) -> Result<Self, DbErr>;\n}\n\nmacro_rules! try_from_u64_err {\n    ( $type: ty ) => {\n        impl TryFromU64 for $type {\n            fn try_from_u64(_: u64) -> Result<Self, DbErr> {\n                Err(DbErr::ConvertFromU64(stringify!($type)))\n            }\n        }\n    };\n\n    ( $($gen_type: ident),* ) => {\n        impl<$( $gen_type, )*> TryFromU64 for ($( $gen_type, )*)\n        where\n            $( $gen_type: TryFromU64, )*\n        {\n            fn try_from_u64(_: u64) -> Result<Self, DbErr> {\n                Err(DbErr::ConvertFromU64(stringify!($($gen_type,)*)))\n            }\n        }\n    };\n}\n\n#[rustfmt::skip]\nmod try_from_u64_err {\n    use super::*;\n\n    try_from_u64_err!(T0, T1);\n    try_from_u64_err!(T0, T1, T2);\n    try_from_u64_err!(T0, T1, T2, T3);\n    try_from_u64_err!(T0, T1, T2, T3, T4);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5, T6);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5, T6, T7);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5, T6, T7, T8);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);\n}\n\nmacro_rules! try_from_u64_numeric {\n    ( $type: ty ) => {\n        impl TryFromU64 for $type {\n            fn try_from_u64(n: u64) -> Result<Self, DbErr> {\n                use std::convert::TryInto;\n                n.try_into().map_err(|e| DbErr::TryIntoErr {\n                    from: stringify!(u64),\n                    into: stringify!($type),\n                    source: Arc::new(e),\n                })\n            }\n        }\n    };\n}\n\ntry_from_u64_numeric!(i8);\ntry_from_u64_numeric!(i16);\ntry_from_u64_numeric!(i32);\ntry_from_u64_numeric!(i64);\ntry_from_u64_numeric!(u8);\ntry_from_u64_numeric!(u16);\ntry_from_u64_numeric!(u32);\ntry_from_u64_numeric!(u64);\n\nmacro_rules! try_from_u64_string {\n    ( $type: ty ) => {\n        impl TryFromU64 for $type {\n            fn try_from_u64(n: u64) -> Result<Self, DbErr> {\n                Ok(n.to_string())\n            }\n        }\n    };\n}\n\ntry_from_u64_string!(String);\n\ntry_from_u64_err!(bool);\ntry_from_u64_err!(f32);\ntry_from_u64_err!(f64);\ntry_from_u64_err!(Vec<u8>);\n\n#[cfg(feature = \"with-json\")]\ntry_from_u64_err!(serde_json::Value);\n\n#[cfg(feature = \"with-chrono\")]\ntry_from_u64_err!(chrono::NaiveDate);\n\n#[cfg(feature = \"with-chrono\")]\ntry_from_u64_err!(chrono::NaiveTime);\n\n#[cfg(feature = \"with-chrono\")]\ntry_from_u64_err!(chrono::NaiveDateTime);\n\n#[cfg(feature = \"with-chrono\")]\ntry_from_u64_err!(chrono::DateTime<chrono::FixedOffset>);\n\n#[cfg(feature = \"with-chrono\")]\ntry_from_u64_err!(chrono::DateTime<chrono::Utc>);\n\n#[cfg(feature = \"with-chrono\")]\ntry_from_u64_err!(chrono::DateTime<chrono::Local>);\n\n#[cfg(feature = \"with-time\")]\ntry_from_u64_err!(time::Date);\n\n#[cfg(feature = \"with-time\")]\ntry_from_u64_err!(time::Time);\n\n#[cfg(feature = \"with-time\")]\ntry_from_u64_err!(time::PrimitiveDateTime);\n\n#[cfg(feature = \"with-time\")]\ntry_from_u64_err!(time::OffsetDateTime);\n\n#[cfg(feature = \"with-rust_decimal\")]\ntry_from_u64_err!(rust_decimal::Decimal);\n\n#[cfg(feature = \"with-uuid\")]\ntry_from_u64_err!(uuid::Uuid);\n\n#[cfg(feature = \"with-ipnetwork\")]\ntry_from_u64_err!(ipnetwork::IpNetwork);\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::RuntimeErr;\n    use sea_query::Value;\n    use std::collections::BTreeMap;\n\n    #[test]\n    fn from_try_get_error() {\n        // TryGetError::DbErr\n        let try_get_error = TryGetError::DbErr(DbErr::Query(RuntimeErr::Internal(\n            \"expected error message\".to_owned(),\n        )));\n        assert_eq!(\n            DbErr::from(try_get_error),\n            DbErr::Query(RuntimeErr::Internal(\"expected error message\".to_owned()))\n        );\n\n        // TryGetError::Null\n        let try_get_error = TryGetError::Null(\"column\".to_owned());\n        let expected = \"A null value was encountered while decoding column\".to_owned();\n        assert_eq!(DbErr::from(try_get_error), DbErr::Type(expected));\n    }\n\n    #[test]\n    fn build_with_query() {\n        use sea_orm::{DbBackend, Statement};\n        use sea_query::{\n            ColumnRef, CommonTableExpression, Cycle, Expr, ExprTrait, JoinType, SelectStatement,\n            UnionType, WithClause,\n        };\n\n        let base_query = SelectStatement::new()\n            .column(\"id\")\n            .expr(1i32)\n            .column(\"next\")\n            .column(\"value\")\n            .from(\"table\")\n            .to_owned();\n\n        let cte_referencing = SelectStatement::new()\n            .column(\"id\")\n            .expr(Expr::col(\"depth\").add(1i32))\n            .column(\"next\")\n            .column(\"value\")\n            .from(\"table\")\n            .join(\n                JoinType::InnerJoin,\n                \"cte_traversal\",\n                Expr::col((\"cte_traversal\", \"next\")).equals((\"table\", \"id\")),\n            )\n            .to_owned();\n\n        let common_table_expression = CommonTableExpression::new()\n            .query(\n                base_query\n                    .clone()\n                    .union(UnionType::All, cte_referencing)\n                    .to_owned(),\n            )\n            .columns([\"id\", \"depth\", \"next\", \"value\"])\n            .table_name(\"cte_traversal\")\n            .to_owned();\n\n        let select = SelectStatement::new()\n            .column(ColumnRef::Asterisk(None))\n            .from(\"cte_traversal\")\n            .to_owned();\n\n        let with_clause = WithClause::new()\n            .recursive(true)\n            .cte(common_table_expression)\n            .cycle(Cycle::new_from_expr_set_using(\n                Expr::column(\"id\"),\n                \"looped\",\n                \"traversal_path\",\n            ))\n            .to_owned();\n\n        let with_query = select.with(with_clause).to_owned();\n\n        assert_eq!(\n            DbBackend::MySql.build(&with_query),\n            Statement::from_sql_and_values(\n                DbBackend::MySql,\n                r\"WITH RECURSIVE `cte_traversal` (`id`, `depth`, `next`, `value`) AS (SELECT `id`, ?, `next`, `value` FROM `table` UNION ALL (SELECT `id`, `depth` + ?, `next`, `value` FROM `table` INNER JOIN `cte_traversal` ON `cte_traversal`.`next` = `table`.`id`)) SELECT * FROM `cte_traversal`\",\n                [1.into(), 1.into()]\n            )\n        );\n    }\n\n    #[test]\n    fn column_names_from_query_result() {\n        let mut values = BTreeMap::new();\n        values.insert(\"id\".to_string(), Value::Int(Some(1)));\n        values.insert(\"name\".to_string(), Value::String(Some(\"Abc\".to_owned())));\n        let query_result = QueryResult {\n            row: QueryResultRow::Mock(crate::MockRow { values }),\n        };\n        assert_eq!(\n            query_result.column_names(),\n            vec![\"id\".to_owned(), \"name\".to_owned()]\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/returning.rs",
    "content": "use super::SelectorTrait;\nuse crate::{ConnectionTrait, StatementBuilder, error::*};\nuse itertools::Itertools;\nuse std::marker::PhantomData;\n\n#[derive(Clone, Debug)]\npub(super) struct ReturningSelector<S, Q>\nwhere\n    S: SelectorTrait,\n    Q: StatementBuilder,\n{\n    pub(crate) query: Q,\n    selector: PhantomData<S>,\n}\n\nimpl<S, Q> ReturningSelector<S, Q>\nwhere\n    S: SelectorTrait,\n    Q: StatementBuilder,\n{\n    pub fn from_query(query: Q) -> Self {\n        Self {\n            query,\n            selector: PhantomData,\n        }\n    }\n\n    pub fn one<C>(self, db: &C) -> Result<Option<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let row = db.query_one(&self.query)?;\n        match row {\n            Some(row) => Ok(Some(S::from_raw_query_result(row)?)),\n            None => Ok(None),\n        }\n    }\n\n    pub fn all<C>(self, db: &C) -> Result<Vec<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        db.query_all(&self.query)?\n            .into_iter()\n            .map(|row| S::from_raw_query_result(row))\n            .try_collect()\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/select/five.rs",
    "content": "use super::*;\nuse crate::{\n    JoinType, Paginator, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, QueryTrait, Related,\n    SelectC, SelectFive, SelectSix, Topology, TopologyStar,\n    combine::{SelectD, SelectE, prepare_select_col},\n};\n\nimpl<E, F, G, H, I, TOP> SelectFive<E, F, G, H, I, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query).prepare_select()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<I, _, _>(&mut self, SelectE);\n        self\n    }\n\n    /// Left Join with a Related Entity and select all Entities.\n    pub fn find_also<T, J>(self, _: T, _: J) -> SelectSix<E, F, G, H, I, J, TopologyStar>\n    where\n        J: EntityTrait,\n        T: EntityTrait + Related<J>,\n    {\n        SelectSix::new(\n            self.join_join(JoinType::LeftJoin, T::to(), T::via())\n                .into_query(),\n        )\n    }\n}\n\nmacro_rules! impl_query_trait {\n    ( $trait: ident ) => {\n        impl<E, F, G, H, I, TOP> $trait for SelectFive<E, F, G, H, I, TOP>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n            G: EntityTrait,\n            H: EntityTrait,\n            I: EntityTrait,\n            TOP: Topology,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n    };\n}\n\nimpl<E, F, G, H, I, TOP> QueryTrait for SelectFive<E, F, G, H, I, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    TOP: Topology,\n{\n    type QueryStatement = SelectStatement;\n    fn query(&mut self) -> &mut SelectStatement {\n        &mut self.query\n    }\n    fn as_query(&self) -> &SelectStatement {\n        &self.query\n    }\n    fn into_query(self) -> SelectStatement {\n        self.query\n    }\n}\n\nimpl_query_trait!(QuerySelect);\nimpl_query_trait!(QueryFilter);\nimpl_query_trait!(QueryOrder);\n\nimpl<M, N, O, P, Q> SelectorTrait for SelectFiveModel<M, N, O, P, Q>\nwhere\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n    O: FromQueryResult + Sized,\n    P: FromQueryResult + Sized,\n    Q: FromQueryResult + Sized,\n{\n    type Item = (M, Option<N>, Option<O>, Option<P>, Option<Q>);\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, SelectA.as_str())?,\n            N::from_query_result_optional(&res, SelectB.as_str())?,\n            O::from_query_result_optional(&res, SelectC.as_str())?,\n            P::from_query_result_optional(&res, SelectD.as_str())?,\n            Q::from_query_result_optional(&res, SelectE.as_str())?,\n        ))\n    }\n}\n\nimpl<E, F, G, H, I, TOP> SelectFive<E, F, G, H, I, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    TOP: Topology,\n{\n    /// Perform a conversion into a [SelectFiveModel]\n    pub fn into_model<M, N, O, P, Q>(self) -> Selector<SelectFiveModel<M, N, O, P, Q>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n        O: FromQueryResult,\n        P: FromQueryResult,\n        Q: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Perform a conversion into a [SelectFiveModel] with [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M, N, O, P, Q>(self) -> Selector<SelectFiveModel<M, N, O, P, Q>>\n    where\n        M: PartialModelTrait,\n        N: PartialModelTrait,\n        O: PartialModelTrait,\n        P: PartialModelTrait,\n        Q: PartialModelTrait,\n    {\n        let select = QuerySelect::select_only(self);\n        let select = M::select_cols(select);\n        let select = N::select_cols(select);\n        let select = O::select_cols(select);\n        let select = P::select_cols(select);\n        let select = Q::select_cols(select);\n        select.into_model::<M, N, O, P, Q>()\n    }\n\n    /// Convert the Models into JsonValue\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(\n        self,\n    ) -> Selector<SelectFiveModel<JsonValue, JsonValue, JsonValue, JsonValue, JsonValue>> {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the Select query\n    pub fn one<C>(\n        self,\n        db: &C,\n    ) -> Result<\n        Option<(\n            E::Model,\n            Option<F::Model>,\n            Option<G::Model>,\n            Option<H::Model>,\n            Option<I::Model>,\n        )>,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db)\n    }\n\n    /// Get all Models from the Select query\n    pub fn all<C>(\n        self,\n        db: &C,\n    ) -> Result<\n        Vec<(\n            E::Model,\n            Option<F::Model>,\n            Option<G::Model>,\n            Option<H::Model>,\n            Option<I::Model>,\n        )>,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db)\n    }\n\n    /// Stream the results of a Select operation on a Model\n    pub fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<\n        impl Iterator<\n            Item = Result<\n                (\n                    E::Model,\n                    Option<F::Model>,\n                    Option<G::Model>,\n                    Option<H::Model>,\n                    Option<I::Model>,\n                ),\n                DbErr,\n            >,\n        > + 'b,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait + StreamTrait,\n    {\n        self.into_model().stream(db)\n    }\n}\n\nimpl<'db, C, EE, FF, GG, HH, II, E, F, G, H, I, TOP> PaginatorTrait<'db, C>\n    for SelectFive<E, F, G, H, I, TOP>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait<Model = EE>,\n    F: EntityTrait<Model = FF>,\n    G: EntityTrait<Model = GG>,\n    H: EntityTrait<Model = HH>,\n    I: EntityTrait<Model = II>,\n    EE: FromQueryResult + Sized + 'db,\n    FF: FromQueryResult + Sized + 'db,\n    GG: FromQueryResult + Sized + 'db,\n    HH: FromQueryResult + Sized + 'db,\n    II: FromQueryResult + Sized + 'db,\n    TOP: Topology,\n{\n    type Selector = SelectFiveModel<EE, FF, GG, HH, II>;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {\n        self.into_model().paginate(db, page_size)\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/select/four.rs",
    "content": "use super::*;\nuse crate::{\n    JoinType, Paginator, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, QueryTrait, Related,\n    SelectC, SelectFive, SelectFour, Topology, TopologyStar,\n    combine::{SelectD, prepare_select_col},\n};\n\nimpl<E, F, G, H, TOP> SelectFour<E, F, G, H, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query).prepare_select()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<H, _, _>(&mut self, SelectD);\n        self\n    }\n\n    /// Left Join with a Related Entity and select all Entities.\n    pub fn find_also<T, I>(self, _: T, _: I) -> SelectFive<E, F, G, H, I, TopologyStar>\n    where\n        I: EntityTrait,\n        T: EntityTrait + Related<I>,\n    {\n        SelectFive::new(\n            self.join_join(JoinType::LeftJoin, T::to(), T::via())\n                .into_query(),\n        )\n    }\n}\n\nmacro_rules! impl_query_trait {\n    ( $trait: ident ) => {\n        impl<E, F, G, H, TOP> $trait for SelectFour<E, F, G, H, TOP>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n            G: EntityTrait,\n            H: EntityTrait,\n            TOP: Topology,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n    };\n}\n\nimpl<E, F, G, H, TOP> QueryTrait for SelectFour<E, F, G, H, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    TOP: Topology,\n{\n    type QueryStatement = SelectStatement;\n    fn query(&mut self) -> &mut SelectStatement {\n        &mut self.query\n    }\n    fn as_query(&self) -> &SelectStatement {\n        &self.query\n    }\n    fn into_query(self) -> SelectStatement {\n        self.query\n    }\n}\n\nimpl_query_trait!(QuerySelect);\nimpl_query_trait!(QueryFilter);\nimpl_query_trait!(QueryOrder);\n\nimpl<M, N, O, P> SelectorTrait for SelectFourModel<M, N, O, P>\nwhere\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n    O: FromQueryResult + Sized,\n    P: FromQueryResult + Sized,\n{\n    type Item = (M, Option<N>, Option<O>, Option<P>);\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, SelectA.as_str())?,\n            N::from_query_result_optional(&res, SelectB.as_str())?,\n            O::from_query_result_optional(&res, SelectC.as_str())?,\n            P::from_query_result_optional(&res, SelectD.as_str())?,\n        ))\n    }\n}\n\nimpl<E, F, G, H, TOP> SelectFour<E, F, G, H, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    TOP: Topology,\n{\n    /// Perform a conversion into a [SelectFourModel]\n    pub fn into_model<M, N, O, P>(self) -> Selector<SelectFourModel<M, N, O, P>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n        O: FromQueryResult,\n        P: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Perform a conversion into a [SelectFourModel] with [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M, N, O, P>(self) -> Selector<SelectFourModel<M, N, O, P>>\n    where\n        M: PartialModelTrait,\n        N: PartialModelTrait,\n        O: PartialModelTrait,\n        P: PartialModelTrait,\n    {\n        let select = QuerySelect::select_only(self);\n        let select = M::select_cols(select);\n        let select = N::select_cols(select);\n        let select = O::select_cols(select);\n        let select = P::select_cols(select);\n        select.into_model::<M, N, O, P>()\n    }\n\n    /// Convert the Models into JsonValue\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(\n        self,\n    ) -> Selector<SelectFourModel<JsonValue, JsonValue, JsonValue, JsonValue>> {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the Select query\n    pub fn one<C>(\n        self,\n        db: &C,\n    ) -> Result<\n        Option<(\n            E::Model,\n            Option<F::Model>,\n            Option<G::Model>,\n            Option<H::Model>,\n        )>,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db)\n    }\n\n    /// Get all Models from the Select query\n    pub fn all<C>(\n        self,\n        db: &C,\n    ) -> Result<\n        Vec<(\n            E::Model,\n            Option<F::Model>,\n            Option<G::Model>,\n            Option<H::Model>,\n        )>,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db)\n    }\n\n    /// Stream the results of a Select operation on a Model\n    pub fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<\n        impl Iterator<\n            Item = Result<\n                (\n                    E::Model,\n                    Option<F::Model>,\n                    Option<G::Model>,\n                    Option<H::Model>,\n                ),\n                DbErr,\n            >,\n        > + 'b,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait + StreamTrait,\n    {\n        self.into_model().stream(db)\n    }\n\n    /// Stream the result of the operation with PartialModel\n    pub fn stream_partial_model<'a: 'b, 'b, C, M, N, O, P>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Iterator<Item = Result<(M, Option<N>, Option<O>, Option<P>), DbErr>> + 'b, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait,\n        M: PartialModelTrait + 'b,\n        N: PartialModelTrait + 'b,\n        O: PartialModelTrait + 'b,\n        P: PartialModelTrait + 'b,\n    {\n        self.into_partial_model().stream(db)\n    }\n}\n\nimpl<'db, C, EE, FF, GG, HH, E, F, G, H, TOP> PaginatorTrait<'db, C> for SelectFour<E, F, G, H, TOP>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait<Model = EE>,\n    F: EntityTrait<Model = FF>,\n    G: EntityTrait<Model = GG>,\n    H: EntityTrait<Model = HH>,\n    EE: FromQueryResult + Sized + 'db,\n    FF: FromQueryResult + Sized + 'db,\n    GG: FromQueryResult + Sized + 'db,\n    HH: FromQueryResult + Sized + 'db,\n    TOP: Topology,\n{\n    type Selector = SelectFourModel<EE, FF, GG, HH>;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {\n        self.into_model().paginate(db, page_size)\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/select/six.rs",
    "content": "use super::*;\nuse crate::{\n    Paginator, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, QueryTrait, SelectC,\n    SelectSix, Topology,\n    combine::{SelectD, SelectE, SelectF, prepare_select_col},\n};\n\nimpl<E, F, G, H, I, J, TOP> SelectSix<E, F, G, H, I, J, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    J: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query).prepare_select()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<J, _, _>(&mut self, SelectF);\n        self\n    }\n}\n\nmacro_rules! impl_query_trait {\n    ( $trait: ident ) => {\n        impl<E, F, G, H, I, J, TOP> $trait for SelectSix<E, F, G, H, I, J, TOP>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n            G: EntityTrait,\n            H: EntityTrait,\n            I: EntityTrait,\n            J: EntityTrait,\n            TOP: Topology,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n    };\n}\n\nimpl<E, F, G, H, I, J, TOP> QueryTrait for SelectSix<E, F, G, H, I, J, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    J: EntityTrait,\n    TOP: Topology,\n{\n    type QueryStatement = SelectStatement;\n    fn query(&mut self) -> &mut SelectStatement {\n        &mut self.query\n    }\n    fn as_query(&self) -> &SelectStatement {\n        &self.query\n    }\n    fn into_query(self) -> SelectStatement {\n        self.query\n    }\n}\n\nimpl_query_trait!(QuerySelect);\nimpl_query_trait!(QueryFilter);\nimpl_query_trait!(QueryOrder);\n\nimpl<M, N, O, P, Q, R> SelectorTrait for SelectSixModel<M, N, O, P, Q, R>\nwhere\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n    O: FromQueryResult + Sized,\n    P: FromQueryResult + Sized,\n    Q: FromQueryResult + Sized,\n    R: FromQueryResult + Sized,\n{\n    type Item = (M, Option<N>, Option<O>, Option<P>, Option<Q>, Option<R>);\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, SelectA.as_str())?,\n            N::from_query_result_optional(&res, SelectB.as_str())?,\n            O::from_query_result_optional(&res, SelectC.as_str())?,\n            P::from_query_result_optional(&res, SelectD.as_str())?,\n            Q::from_query_result_optional(&res, SelectE.as_str())?,\n            R::from_query_result_optional(&res, SelectF.as_str())?,\n        ))\n    }\n}\n\nimpl<E, F, G, H, I, J, TOP> SelectSix<E, F, G, H, I, J, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    J: EntityTrait,\n    TOP: Topology,\n{\n    /// Perform a conversion into a [SelectSixModel]\n    pub fn into_model<M, N, O, P, Q, R>(self) -> Selector<SelectSixModel<M, N, O, P, Q, R>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n        O: FromQueryResult,\n        P: FromQueryResult,\n        Q: FromQueryResult,\n        R: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Perform a conversion into a [SelectSixModel] with [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M, N, O, P, Q, R>(self) -> Selector<SelectSixModel<M, N, O, P, Q, R>>\n    where\n        M: PartialModelTrait,\n        N: PartialModelTrait,\n        O: PartialModelTrait,\n        P: PartialModelTrait,\n        Q: PartialModelTrait,\n        R: PartialModelTrait,\n    {\n        let select = QuerySelect::select_only(self);\n        let select = M::select_cols(select);\n        let select = N::select_cols(select);\n        let select = O::select_cols(select);\n        let select = P::select_cols(select);\n        let select = Q::select_cols(select);\n        let select = R::select_cols(select);\n        select.into_model::<M, N, O, P, Q, R>()\n    }\n\n    /// Convert the Models into JsonValue\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(\n        self,\n    ) -> Selector<SelectSixModel<JsonValue, JsonValue, JsonValue, JsonValue, JsonValue, JsonValue>>\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the Select query\n    pub fn one<C>(\n        self,\n        db: &C,\n    ) -> Result<\n        Option<(\n            E::Model,\n            Option<F::Model>,\n            Option<G::Model>,\n            Option<H::Model>,\n            Option<I::Model>,\n            Option<J::Model>,\n        )>,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db)\n    }\n\n    /// Get all Models from the Select query\n    pub fn all<C>(\n        self,\n        db: &C,\n    ) -> Result<\n        Vec<(\n            E::Model,\n            Option<F::Model>,\n            Option<G::Model>,\n            Option<H::Model>,\n            Option<I::Model>,\n            Option<J::Model>,\n        )>,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db)\n    }\n\n    /// Stream the results of a Select operation on a Model\n    pub fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<\n        impl Iterator<\n            Item = Result<\n                (\n                    E::Model,\n                    Option<F::Model>,\n                    Option<G::Model>,\n                    Option<H::Model>,\n                    Option<I::Model>,\n                    Option<J::Model>,\n                ),\n                DbErr,\n            >,\n        > + 'b,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait + StreamTrait,\n    {\n        self.into_model().stream(db)\n    }\n}\n\nimpl<'db, C, EE, FF, GG, HH, II, JJ, E, F, G, H, I, J, TOP> PaginatorTrait<'db, C>\n    for SelectSix<E, F, G, H, I, J, TOP>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait<Model = EE>,\n    F: EntityTrait<Model = FF>,\n    G: EntityTrait<Model = GG>,\n    H: EntityTrait<Model = HH>,\n    I: EntityTrait<Model = II>,\n    J: EntityTrait<Model = JJ>,\n    EE: FromQueryResult + Sized + 'db,\n    FF: FromQueryResult + Sized + 'db,\n    GG: FromQueryResult + Sized + 'db,\n    HH: FromQueryResult + Sized + 'db,\n    II: FromQueryResult + Sized + 'db,\n    JJ: FromQueryResult + Sized + 'db,\n    TOP: Topology,\n{\n    type Selector = SelectSixModel<EE, FF, GG, HH, II, JJ>;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {\n        self.into_model().paginate(db, page_size)\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/select/three.rs",
    "content": "use super::*;\nuse crate::{\n    JoinType, Paginator, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, QueryTrait, Related,\n    SelectC, SelectFour, SelectThree, SelectThreeMany, Topology, TopologyChain, TopologyStar,\n    combine::prepare_select_col,\n};\n\nimpl<E, F, G, TOP> SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query).prepare_select()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<G, _, _>(&mut self, SelectC);\n        self\n    }\n\n    /// Left Join with a Related Entity and select all Entities.\n    pub fn find_also<T, H>(self, _: T, _: H) -> SelectFour<E, F, G, H, TopologyStar>\n    where\n        H: EntityTrait,\n        T: EntityTrait + Related<H>,\n    {\n        SelectFour::new(\n            self.join_join(JoinType::LeftJoin, T::to(), T::via())\n                .into_query(),\n        )\n    }\n}\n\nmacro_rules! impl_query_trait {\n    ( $trait: ident ) => {\n        impl<E, F, G, TOP> $trait for SelectThree<E, F, G, TOP>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n            G: EntityTrait,\n            TOP: Topology,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n    };\n}\n\nimpl<E, F, G, TOP> QueryTrait for SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    type QueryStatement = SelectStatement;\n    fn query(&mut self) -> &mut SelectStatement {\n        &mut self.query\n    }\n    fn as_query(&self) -> &SelectStatement {\n        &self.query\n    }\n    fn into_query(self) -> SelectStatement {\n        self.query\n    }\n}\n\nimpl_query_trait!(QuerySelect);\nimpl_query_trait!(QueryFilter);\nimpl_query_trait!(QueryOrder);\n\nimpl<M, N, O> SelectorTrait for SelectThreeModel<M, N, O>\nwhere\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n    O: FromQueryResult + Sized,\n{\n    type Item = (M, Option<N>, Option<O>);\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, SelectA.as_str())?,\n            N::from_query_result_optional(&res, SelectB.as_str())?,\n            O::from_query_result_optional(&res, SelectC.as_str())?,\n        ))\n    }\n}\n\nimpl<E, F, G, TOP> SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    /// Perform a conversion into a [SelectThreeModel]\n    pub fn into_model<M, N, O>(self) -> Selector<SelectThreeModel<M, N, O>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n        O: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Perform a conversion into a [SelectThreeModel] with [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M, N, O>(self) -> Selector<SelectThreeModel<M, N, O>>\n    where\n        M: PartialModelTrait,\n        N: PartialModelTrait,\n        O: PartialModelTrait,\n    {\n        let select = QuerySelect::select_only(self);\n        let select = M::select_cols(select);\n        let select = N::select_cols(select);\n        let select = O::select_cols(select);\n        select.into_model::<M, N, O>()\n    }\n\n    /// Convert the Models into JsonValue\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(self) -> Selector<SelectThreeModel<JsonValue, JsonValue, JsonValue>> {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the Select query\n    pub fn one<C>(\n        self,\n        db: &C,\n    ) -> Result<Option<(E::Model, Option<F::Model>, Option<G::Model>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db)\n    }\n\n    /// Get all Models from the Select query\n    pub fn all<C>(\n        self,\n        db: &C,\n    ) -> Result<Vec<(E::Model, Option<F::Model>, Option<G::Model>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db)\n    }\n\n    /// Stream the results of a Select operation on a Model\n    pub fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<\n        impl Iterator<Item = Result<(E::Model, Option<F::Model>, Option<G::Model>), DbErr>> + 'b,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait + StreamTrait,\n    {\n        self.into_model().stream(db)\n    }\n\n    /// Stream the result of the operation with PartialModel\n    pub fn stream_partial_model<'a: 'b, 'b, C, M, N, O>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Iterator<Item = Result<(M, Option<N>, Option<O>), DbErr>> + 'b, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait,\n        M: PartialModelTrait + 'b,\n        N: PartialModelTrait + 'b,\n        O: PartialModelTrait + 'b,\n    {\n        self.into_partial_model().stream(db)\n    }\n\n    /// Consolidate query result by first / second model depending on join topology\n    /// ```\n    /// # use sea_orm::{tests_cfg::*, *};\n    /// # fn function(db: &DbConn) -> Result<(), DbErr> {\n    /// // fruit -> cake -> filling\n    /// let items: Vec<(fruit::Model, Vec<(cake::Model, Vec<filling::Model>)>)> = fruit::Entity::find()\n    ///     .find_also_related(cake::Entity)\n    ///     .and_also_related(filling::Entity)\n    ///     .consolidate()\n    ///     .all(db)\n    ///     ?;\n    ///\n    /// // cake -> fruit\n    /// //      -> filling\n    /// let items: Vec<(cake::Model, Vec<fruit::Model>, Vec<filling::Model>)> = cake::Entity::find()\n    ///     .find_also_related(fruit::Entity)\n    ///     .find_also_related(filling::Entity)\n    ///     .consolidate()\n    ///     .all(db)\n    ///     ?;\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn consolidate(self) -> SelectThreeMany<E, F, G, TOP> {\n        SelectThreeMany {\n            query: self.query,\n            entity: self.entity,\n        }\n    }\n}\n\nimpl<E, F, G, TOP> SelectThreeMany<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    /// Performs a conversion to [Selector]\n    fn into_model<M, N, O>(self) -> Selector<SelectThreeModel<M, N, O>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n        O: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n}\n\nimpl<E, F, G> SelectThreeMany<E, F, G, TopologyStar>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n{\n    /// Execute query and consolidate rows by E\n    pub fn all<C>(self, db: &C) -> Result<Vec<(E::Model, Vec<F::Model>, Vec<G::Model>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let rows = self.into_model().all(db)?;\n        Ok(consolidate_query_result_tee::<E, F, G>(rows))\n    }\n}\n\nimpl<E, F, G> SelectThreeMany<E, F, G, TopologyChain>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n{\n    /// Execute query and consolidate rows in two passes, first by E, then by F\n    pub fn all<C>(self, db: &C) -> Result<Vec<(E::Model, Vec<(F::Model, Vec<G::Model>)>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let rows = self.into_model().all(db)?;\n        Ok(consolidate_query_result_chain::<E, F, G>(rows))\n    }\n}\n\nimpl<'db, C, M, N, O, E, F, G, TOP> PaginatorTrait<'db, C> for SelectThree<E, F, G, TOP>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait<Model = M>,\n    F: EntityTrait<Model = N>,\n    G: EntityTrait<Model = O>,\n    M: FromQueryResult + Sized + 'db,\n    N: FromQueryResult + Sized + 'db,\n    O: FromQueryResult + Sized + 'db,\n    TOP: Topology,\n{\n    type Selector = SelectThreeModel<M, N, O>;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {\n        self.into_model().paginate(db, page_size)\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/select.rs",
    "content": "use super::{\n    consolidate_query_result, consolidate_query_result_chain, consolidate_query_result_tee,\n};\nuse crate::{\n    ConnectionTrait, DbBackend, EntityTrait, FromQueryResult, IdenStatic, PartialModelTrait,\n    QueryResult, QuerySelect, Select, SelectA, SelectB, SelectTwo, SelectTwoMany, Statement,\n    StreamTrait, TryGetableMany, error::*,\n};\nuse itertools::Itertools;\nuse sea_query::SelectStatement;\nuse std::marker::PhantomData;\n\nmod five;\nmod four;\nmod six;\nmod three;\n\n#[cfg(feature = \"with-json\")]\nuse crate::JsonValue;\n\n#[cfg(not(feature = \"sync\"))]\ntype PinBoxStream<'b, S> = Pin<Box<dyn Stream<Item = Result<S, DbErr>> + 'b>>;\n#[cfg(feature = \"sync\")]\ntype PinBoxStream<'b, S> = Box<dyn Iterator<Item = Result<S, DbErr>> + 'b>;\n\n/// Defines a type to do `SELECT` operations through a [SelectStatement] on a Model\n#[derive(Clone, Debug)]\npub struct Selector<S>\nwhere\n    S: SelectorTrait,\n{\n    pub(crate) query: SelectStatement,\n    selector: PhantomData<S>,\n}\n\n/// Performs a raw `SELECT` operation on a model\n#[derive(Clone, Debug)]\npub struct SelectorRaw<S>\nwhere\n    S: SelectorTrait,\n{\n    pub(crate) stmt: Statement,\n    pub(super) selector: PhantomData<S>,\n}\n\n/// A Trait for any type that can perform SELECT queries\npub trait SelectorTrait {\n    #[allow(missing_docs)]\n    type Item: Sized;\n\n    /// The method to perform a query on a Model\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr>;\n}\n\n/// Get tuple from query result based on a list of column identifiers\n#[derive(Debug)]\npub struct SelectGetableValue<T, C>\nwhere\n    T: TryGetableMany,\n    C: strum::IntoEnumIterator + sea_query::Iden,\n{\n    columns: PhantomData<C>,\n    model: PhantomData<T>,\n}\n\n/// Get tuple from query result based on column index\n#[derive(Debug)]\npub struct SelectGetableTuple<T>\nwhere\n    T: TryGetableMany,\n{\n    model: PhantomData<T>,\n}\n\n/// Helper class to handle query result for 1 Model\n#[derive(Debug)]\npub struct SelectModel<M>\nwhere\n    M: FromQueryResult,\n{\n    model: PhantomData<M>,\n}\n\n/// Helper class to handle query result for 2 Models\n#[derive(Clone, Debug)]\npub struct SelectTwoModel<M, N>\nwhere\n    M: FromQueryResult,\n    N: FromQueryResult,\n{\n    model: PhantomData<(M, N)>,\n}\n\n/// Helper class to handle query result for 3 Models\n#[derive(Clone, Debug)]\npub struct SelectThreeModel<M, N, O>\nwhere\n    M: FromQueryResult,\n    N: FromQueryResult,\n    O: FromQueryResult,\n{\n    model: PhantomData<(M, N, O)>,\n}\n\n/// Helper class to handle query result for 4 Models\n#[derive(Clone, Debug)]\npub struct SelectFourModel<M, N, O, P>\nwhere\n    M: FromQueryResult,\n    N: FromQueryResult,\n    O: FromQueryResult,\n    P: FromQueryResult,\n{\n    model: PhantomData<(M, N, O, P)>,\n}\n\n/// Helper class to handle query result for 5 Models\n#[derive(Clone, Debug)]\npub struct SelectFiveModel<M, N, O, P, Q>\nwhere\n    M: FromQueryResult,\n    N: FromQueryResult,\n    O: FromQueryResult,\n    P: FromQueryResult,\n    Q: FromQueryResult,\n{\n    model: PhantomData<(M, N, O, P, Q)>,\n}\n\n/// Helper class to handle query result for 6 Models\n#[derive(Clone, Debug)]\npub struct SelectSixModel<M, N, O, P, Q, R>\nwhere\n    M: FromQueryResult,\n    N: FromQueryResult,\n    O: FromQueryResult,\n    P: FromQueryResult,\n    Q: FromQueryResult,\n    R: FromQueryResult,\n{\n    model: PhantomData<(M, N, O, P, Q, R)>,\n}\n\nimpl<T, C> Default for SelectGetableValue<T, C>\nwhere\n    T: TryGetableMany,\n    C: strum::IntoEnumIterator + sea_query::Iden,\n{\n    fn default() -> Self {\n        Self {\n            columns: PhantomData,\n            model: PhantomData,\n        }\n    }\n}\n\nimpl<T, C> SelectorTrait for SelectGetableValue<T, C>\nwhere\n    T: TryGetableMany,\n    C: strum::IntoEnumIterator + sea_query::Iden,\n{\n    type Item = T;\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        let cols: Vec<String> = C::iter().map(|col| col.to_string()).collect();\n        T::try_get_many(&res, \"\", &cols).map_err(Into::into)\n    }\n}\n\nimpl<T> SelectorTrait for SelectGetableTuple<T>\nwhere\n    T: TryGetableMany,\n{\n    type Item = T;\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        T::try_get_many_by_index(&res).map_err(Into::into)\n    }\n}\n\nimpl<M> SelectorTrait for SelectModel<M>\nwhere\n    M: FromQueryResult + Sized,\n{\n    type Item = M;\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        M::from_query_result(&res, \"\")\n    }\n}\n\nimpl<M, N> SelectorTrait for SelectTwoModel<M, N>\nwhere\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n{\n    type Item = (M, Option<N>);\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, SelectA.as_str())?,\n            N::from_query_result_optional(&res, SelectB.as_str())?,\n        ))\n    }\n}\n\nimpl<E> Select<E>\nwhere\n    E: EntityTrait,\n{\n    /// Perform a Select operation on a Model using a [Statement]\n    #[allow(clippy::wrong_self_convention)]\n    pub fn from_raw_sql(self, stmt: Statement) -> SelectorRaw<SelectModel<E::Model>> {\n        SelectorRaw {\n            stmt,\n            selector: PhantomData,\n        }\n    }\n\n    /// Return a [Selector] from `Self` that wraps a [SelectModel]\n    pub fn into_model<M>(self) -> Selector<SelectModel<M>>\n    where\n        M: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Return a [Selector] from `Self` that wraps a [SelectModel] with a [PartialModel](PartialModelTrait)\n    ///\n    /// ```\n    /// # #[cfg(feature = \"macros\")]\n    /// # {\n    /// use sea_orm::{\n    ///     entity::*,\n    ///     query::*,\n    ///     tests_cfg::cake::{self, Entity as Cake},\n    ///     DbBackend, DerivePartialModel,\n    /// };\n    /// use sea_query::{Expr, Func, SimpleExpr};\n    ///\n    /// #[derive(DerivePartialModel)]\n    /// #[sea_orm(entity = \"Cake\")]\n    /// struct PartialCake {\n    ///     name: String,\n    ///     #[sea_orm(\n    ///         from_expr = r#\"SimpleExpr::FunctionCall(Func::upper(Expr::col((Cake, cake::Column::Name))))\"#\n    ///     )]\n    ///     name_upper: String,\n    /// }\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .into_partial_model::<PartialCake>()\n    ///         .into_statement(DbBackend::Sqlite)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"name\" AS \"name\", UPPER(\"cake\".\"name\") AS \"name_upper\" FROM \"cake\"\"#\n    /// );\n    /// # }\n    /// ```\n    pub fn into_partial_model<M>(self) -> Selector<SelectModel<M>>\n    where\n        M: PartialModelTrait,\n    {\n        M::select_cols(QuerySelect::select_only(self)).into_model::<M>()\n    }\n\n    /// Get a selectable Model as a [JsonValue] for SQL JSON operations\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(self) -> Selector<SelectModel<JsonValue>> {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(all(feature = \"mock\", feature = \"macros\"))]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[\n    /// #         maplit::btreemap! {\n    /// #             \"cake_name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #         },\n    /// #         maplit::btreemap! {\n    /// #             \"cake_name\" => Into::<Value>::into(\"New York Cheese\"),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{DeriveColumn, EnumIter, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n    /// enum QueryAs {\n    ///     CakeName,\n    /// }\n    ///\n    /// let res: Vec<String> = cake::Entity::find()\n    ///     .select_only()\n    ///     .column_as(cake::Column::Name, QueryAs::CakeName)\n    ///     .into_values::<_, QueryAs>()\n    ///     .all(&db)\n    ///     ?;\n    ///\n    /// assert_eq!(\n    ///     res,\n    ///     [\"Chocolate Forest\".to_owned(), \"New York Cheese\".to_owned()]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"name\" AS \"cake_name\" FROM \"cake\"\"#,\n    ///         []\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(all(feature = \"mock\", feature = \"macros\"))]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[\n    /// #         maplit::btreemap! {\n    /// #             \"cake_name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(2i64),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{DeriveColumn, EnumIter, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n    /// enum QueryAs {\n    ///     CakeName,\n    ///     NumOfCakes,\n    /// }\n    ///\n    /// let res: Vec<(String, i64)> = cake::Entity::find()\n    ///     .select_only()\n    ///     .column_as(cake::Column::Name, QueryAs::CakeName)\n    ///     .column_as(cake::Column::Id.count(), QueryAs::NumOfCakes)\n    ///     .group_by(cake::Column::Name)\n    ///     .into_values::<_, QueryAs>()\n    ///     .all(&db)\n    ///     ?;\n    ///\n    /// assert_eq!(res, [(\"Chocolate Forest\".to_owned(), 2i64)]);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         [\n    ///             r#\"SELECT \"cake\".\"name\" AS \"cake_name\", COUNT(\"cake\".\"id\") AS \"num_of_cakes\"\"#,\n    ///             r#\"FROM \"cake\" GROUP BY \"cake\".\"name\"\"#,\n    ///         ]\n    ///         .join(\" \")\n    ///         .as_str(),\n    ///         []\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn into_values<T, C>(self) -> Selector<SelectGetableValue<T, C>>\n    where\n        T: TryGetableMany,\n        C: strum::IntoEnumIterator + sea_query::Iden,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(all(feature = \"mock\", feature = \"macros\"))]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results(vec![vec![\n    /// #         maplit::btreemap! {\n    /// #             \"cake_name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #         },\n    /// #         maplit::btreemap! {\n    /// #             \"cake_name\" => Into::<Value>::into(\"New York Cheese\"),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let res: Vec<String> = cake::Entity::find()\n    ///     .select_only()\n    ///     .column(cake::Column::Name)\n    ///     .into_tuple()\n    ///     .all(&db)\n    ///     ?;\n    ///\n    /// assert_eq!(\n    ///     res,\n    ///     vec![\"Chocolate Forest\".to_owned(), \"New York Cheese\".to_owned()]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     vec![Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"name\" FROM \"cake\"\"#,\n    ///         vec![]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(all(feature = \"mock\", feature = \"macros\"))]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results(vec![vec![\n    /// #         maplit::btreemap! {\n    /// #             \"cake_name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(2i64),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let res: Vec<(String, i64)> = cake::Entity::find()\n    ///     .select_only()\n    ///     .column(cake::Column::Name)\n    ///     .column(cake::Column::Id)\n    ///     .group_by(cake::Column::Name)\n    ///     .into_tuple()\n    ///     .all(&db)\n    ///     ?;\n    ///\n    /// assert_eq!(res, vec![(\"Chocolate Forest\".to_owned(), 2i64)]);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     vec![Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         vec![\n    ///             r#\"SELECT \"cake\".\"name\", \"cake\".\"id\"\"#,\n    ///             r#\"FROM \"cake\" GROUP BY \"cake\".\"name\"\"#,\n    ///         ]\n    ///         .join(\" \")\n    ///         .as_str(),\n    ///         vec![]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn into_tuple<T>(self) -> Selector<SelectGetableTuple<T>>\n    where\n        T: TryGetableMany,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the SELECT query\n    pub fn one<C>(self, db: &C) -> Result<Option<E::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db)\n    }\n\n    /// Get all Models from the SELECT query\n    pub fn all<C>(self, db: &C) -> Result<Vec<E::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db)\n    }\n\n    /// Stream the results of a SELECT operation on a Model\n    pub fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Iterator<Item = Result<E::Model, DbErr>> + 'b, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait,\n    {\n        self.into_model().stream(db)\n    }\n\n    /// Stream the result of the operation with PartialModel\n    pub fn stream_partial_model<'a: 'b, 'b, C, M>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Iterator<Item = Result<M, DbErr>> + 'b, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait,\n        M: PartialModelTrait + 'b,\n    {\n        self.into_partial_model().stream(db)\n    }\n}\n\nimpl<E, F> SelectTwo<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    /// Perform a conversion into a [SelectTwoModel]\n    pub fn into_model<M, N>(self) -> Selector<SelectTwoModel<M, N>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Perform a conversion into a [SelectTwoModel] with [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M, N>(self) -> Selector<SelectTwoModel<M, N>>\n    where\n        M: PartialModelTrait,\n        N: PartialModelTrait,\n    {\n        let select = QuerySelect::select_only(self);\n        let select = M::select_cols(select);\n        let select = N::select_cols(select);\n        select.into_model::<M, N>()\n    }\n\n    /// Convert the Models into JsonValue\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(self) -> Selector<SelectTwoModel<JsonValue, JsonValue>> {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the Select query\n    pub fn one<C>(self, db: &C) -> Result<Option<(E::Model, Option<F::Model>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db)\n    }\n\n    /// Get all Models from the Select query\n    pub fn all<C>(self, db: &C) -> Result<Vec<(E::Model, Option<F::Model>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db)\n    }\n\n    /// Stream the results of a Select operation on a Model\n    pub fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Iterator<Item = Result<(E::Model, Option<F::Model>), DbErr>> + 'b, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait,\n    {\n        self.into_model().stream(db)\n    }\n\n    /// Stream the result of the operation with PartialModel\n    pub fn stream_partial_model<'a: 'b, 'b, C, M, N>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Iterator<Item = Result<(M, Option<N>), DbErr>> + 'b, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait,\n        M: PartialModelTrait + 'b,\n        N: PartialModelTrait + 'b,\n    {\n        self.into_partial_model().stream(db)\n    }\n}\n\nimpl<E, F> SelectTwoMany<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    /// Performs a conversion to [Selector]\n    fn into_model<M, N>(self) -> Selector<SelectTwoModel<M, N>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get all Models from the select operation and consolidate result based on left Model.\n    ///\n    /// > `SelectTwoMany::one()` method has been dropped (#486)\n    /// >\n    /// > You can get `(Entity, Vec<relatedEntity>)` by first querying a single model from Entity,\n    /// > then use [`ModelTrait::find_related`] on the model.\n    /// >\n    /// > See https://www.sea-ql.org/SeaORM/docs/basic-crud/select#lazy-loading for details.\n    pub fn all<C>(self, db: &C) -> Result<Vec<(E::Model, Vec<F::Model>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let rows = self.into_model().all(db)?;\n        Ok(consolidate_query_result::<E, F>(rows))\n    }\n\n    // pub fn paginate()\n    // we could not implement paginate easily, if the number of children for a\n    // parent is larger than one page, then we will end up splitting it in two pages\n    // so the correct way is actually perform query in two stages\n    // paginate the parent model and then populate the children\n\n    // pub fn count()\n    // we should only count the number of items of the parent model\n}\n\nimpl<S> Selector<S>\nwhere\n    S: SelectorTrait,\n{\n    /// Get the SQL statement\n    pub fn into_statement(self, builder: DbBackend) -> Statement {\n        builder.build(&self.query)\n    }\n\n    /// Get an item from the Select query\n    pub fn one<C>(mut self, db: &C) -> Result<Option<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.query.limit(1);\n        let row = db.query_one(&self.query)?;\n        match row {\n            Some(row) => Ok(Some(S::from_raw_query_result(row)?)),\n            None => Ok(None),\n        }\n    }\n\n    /// Get all items from the Select query\n    pub fn all<C>(self, db: &C) -> Result<Vec<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        db.query_all(&self.query)?\n            .into_iter()\n            .map(|row| S::from_raw_query_result(row))\n            .try_collect()\n    }\n\n    /// Stream the results of the Select operation\n    pub fn stream<'a: 'b, 'b, C>(self, db: &'a C) -> Result<PinBoxStream<'b, S::Item>, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait,\n        S: 'b,\n    {\n        let stream = db.stream(&self.query)?;\n\n        #[cfg(not(feature = \"sync\"))]\n        {\n            Ok(Box::new(stream.and_then(|row| {\n                futures_util::future::ready(S::from_raw_query_result(row))\n            })))\n        }\n        #[cfg(feature = \"sync\")]\n        {\n            Ok(Box::new(\n                stream.map(|item| item.and_then(S::from_raw_query_result)),\n            ))\n        }\n    }\n}\n\nimpl<S> SelectorRaw<S>\nwhere\n    S: SelectorTrait,\n{\n    /// Select a custom Model from a raw SQL [Statement].\n    pub fn from_statement<M>(stmt: Statement) -> SelectorRaw<SelectModel<M>>\n    where\n        M: FromQueryResult,\n    {\n        SelectorRaw {\n            stmt,\n            selector: PhantomData,\n        }\n    }\n\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(1),\n    /// #         },\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"New York Cheese\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(1),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{FromQueryResult, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// #[derive(Debug, PartialEq, FromQueryResult)]\n    /// struct SelectResult {\n    ///     name: String,\n    ///     num_of_cakes: i32,\n    /// }\n    ///\n    /// let res: Vec<SelectResult> = cake::Entity::find()\n    ///     .from_raw_sql(Statement::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"name\", count(\"cake\".\"id\") AS \"num_of_cakes\" FROM \"cake\"\"#,\n    ///         [],\n    ///     ))\n    ///     .into_model::<SelectResult>()\n    ///     .all(&db)\n    ///     ?;\n    ///\n    /// assert_eq!(\n    ///     res,\n    ///     [\n    ///         SelectResult {\n    ///             name: \"Chocolate Forest\".to_owned(),\n    ///             num_of_cakes: 1,\n    ///         },\n    ///         SelectResult {\n    ///             name: \"New York Cheese\".to_owned(),\n    ///             num_of_cakes: 1,\n    ///         },\n    ///     ]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"name\", count(\"cake\".\"id\") AS \"num_of_cakes\" FROM \"cake\"\"#,\n    ///         []\n    ///     ),]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn into_model<M>(self) -> SelectorRaw<SelectModel<M>>\n    where\n        M: FromQueryResult,\n    {\n        SelectorRaw {\n            stmt: self.stmt,\n            selector: PhantomData,\n        }\n    }\n\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(1),\n    /// #         },\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"New York Cheese\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(1),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let res: Vec<serde_json::Value> = cake::Entity::find().from_raw_sql(\n    ///     Statement::from_sql_and_values(\n    ///         DbBackend::Postgres, r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#, []\n    ///     )\n    /// )\n    /// .into_json()\n    /// .all(&db)\n    /// ?;\n    ///\n    /// assert_eq!(\n    ///     res,\n    ///     [\n    ///         serde_json::json!({\n    ///             \"name\": \"Chocolate Forest\",\n    ///             \"num_of_cakes\": 1,\n    ///         }),\n    ///         serde_json::json!({\n    ///             \"name\": \"New York Cheese\",\n    ///             \"num_of_cakes\": 1,\n    ///         }),\n    ///     ]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [\n    ///     Transaction::from_sql_and_values(\n    ///             DbBackend::Postgres, r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#, []\n    ///     ),\n    /// ]);\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(self) -> SelectorRaw<SelectModel<JsonValue>> {\n        SelectorRaw {\n            stmt: self.stmt,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get the SQL statement\n    pub fn into_statement(self) -> Statement {\n        self.stmt\n    }\n\n    /// Get an item from the Select query\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Cake\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, raw_sql, tests_cfg::cake};\n    ///\n    /// let id = 1;\n    ///\n    /// let _: Option<cake::Model> = cake::Entity::find()\n    ///     .from_raw_sql(raw_sql!(\n    ///         Postgres,\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"id\" = {id}\"#\n    ///     ))\n    ///     .one(&db)\n    ///     ?;\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"id\" = $1\"#,\n    ///         [1.into()]\n    ///     ),]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn one<C>(self, db: &C) -> Result<Option<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let row = db.query_one_raw(self.stmt)?;\n        match row {\n            Some(row) => Ok(Some(S::from_raw_query_result(row)?)),\n            None => Ok(None),\n        }\n    }\n\n    /// Get all items from the Select query\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Cake\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, raw_sql, tests_cfg::cake};\n    ///\n    /// let _: Vec<cake::Model> = cake::Entity::find()\n    ///     .from_raw_sql(raw_sql!(\n    ///         Postgres,\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#\n    ///     ))\n    ///     .all(&db)\n    ///     ?;\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n    ///         []\n    ///     ),]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn all<C>(self, db: &C) -> Result<Vec<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        db.query_all_raw(self.stmt)?\n            .into_iter()\n            .map(|row| S::from_raw_query_result(row))\n            .try_collect()\n    }\n\n    /// Stream the results of the Select operation\n    pub fn stream<'a: 'b, 'b, C>(self, db: &'a C) -> Result<PinBoxStream<'b, S::Item>, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait,\n        S: 'b,\n    {\n        let stream = db.stream_raw(self.stmt)?;\n\n        #[cfg(not(feature = \"sync\"))]\n        {\n            Ok(Box::new(stream.and_then(|row| {\n                futures_util::future::ready(S::from_raw_query_result(row))\n            })))\n        }\n        #[cfg(feature = \"sync\")]\n        {\n            Ok(Box::new(\n                stream.map(|item| item.and_then(S::from_raw_query_result)),\n            ))\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/select_ext.rs",
    "content": "use crate::{\n    ConnectionTrait, DbErr, EntityTrait, Select, SelectFive, SelectFour, SelectSix, SelectThree,\n    SelectTwo, Selector, SelectorRaw, SelectorTrait, Topology,\n};\nuse sea_query::{Expr, SelectStatement};\n\n// TODO: Move count here\n/// Helper trait for selectors with convenient methods\npub trait SelectExt {\n    /// This method is unstable and is only used for internal testing.\n    /// It may be removed in the future.\n    #[doc(hidden)]\n    fn exists_query(self) -> SelectStatement;\n    /// Check if any records exist\n    fn exists<C>(self, db: &C) -> Result<bool, DbErr>\n    where\n        C: ConnectionTrait,\n        Self: Sized,\n    {\n        let stmt = self.exists_query();\n        Ok(db.query_one(&stmt)?.is_some())\n    }\n}\n\nfn into_exists_query(mut stmt: SelectStatement) -> SelectStatement {\n    stmt.clear_selects();\n    // Expr::Custom has fewer branches, but this may not have any significant impact on performance.\n    stmt.expr(Expr::cust(\"1\"));\n    stmt.reset_limit();\n    stmt.reset_offset();\n    stmt.clear_order_by();\n    stmt\n}\n\nimpl<S> SelectExt for Selector<S>\nwhere\n    S: SelectorTrait,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\nimpl<S> SelectExt for SelectorRaw<S>\nwhere\n    S: SelectorTrait,\n{\n    fn exists_query(self) -> SelectStatement {\n        let stmt = self.stmt;\n        let sub_query_sql = stmt.sql.trim().trim_end_matches(';').trim();\n        let exists_sql = format!(\"1 FROM ({sub_query_sql}) AS sub_query LIMIT 1\");\n\n        let mut query = SelectStatement::new();\n        query.expr(if let Some(values) = stmt.values {\n            Expr::cust_with_values(exists_sql, values.0)\n        } else {\n            Expr::cust(exists_sql)\n        });\n        query\n    }\n}\n\nimpl<E> SelectExt for Select<E>\nwhere\n    E: EntityTrait,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\nimpl<E, F> SelectExt for SelectTwo<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\nimpl<E, F, G, TOP> SelectExt for SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\nimpl<E, F, G, H, TOP> SelectExt for SelectFour<E, F, G, H, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    TOP: Topology,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\nimpl<E, F, G, H, I, TOP> SelectExt for SelectFive<E, F, G, H, I, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    TOP: Topology,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\nimpl<E, F, G, H, I, J, TOP> SelectExt for SelectSix<E, F, G, H, I, J, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    J: EntityTrait,\n    TOP: Topology,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::SelectExt;\n    use crate::entity::prelude::*;\n    use crate::{DbBackend, QueryOrder, QuerySelect, Statement, tests_cfg::*};\n\n    #[test]\n    fn exists_query_select_basic() {\n        let stmt = fruit::Entity::find().exists_query();\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(sql, r#\"SELECT 1 FROM \"fruit\"\"#);\n    }\n\n    #[test]\n    fn exists_query_select_strips_limit_offset_order() {\n        let stmt = fruit::Entity::find()\n            .filter(fruit::Column::Id.gt(1))\n            .order_by_asc(fruit::Column::Id)\n            .limit(2)\n            .offset(4)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(sql, r#\"SELECT 1 FROM \"fruit\" WHERE \"fruit\".\"id\" > 1\"#);\n    }\n\n    #[test]\n    fn exists_query_selector_basic() {\n        let stmt = fruit::Entity::find()\n            .into_model::<fruit::Model>()\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(sql, r#\"SELECT 1 FROM \"fruit\"\"#);\n    }\n\n    #[test]\n    fn exists_query_selector_complex() {\n        let stmt = fruit::Entity::find()\n            .filter(fruit::Column::Id.gt(1))\n            .order_by_desc(fruit::Column::Id)\n            .limit(2)\n            .offset(4)\n            .into_model::<fruit::Model>()\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(sql, r#\"SELECT 1 FROM \"fruit\" WHERE \"fruit\".\"id\" > 1\"#);\n    }\n\n    #[test]\n    fn exists_query_selector_raw_simple() {\n        let raw_stmt =\n            Statement::from_string(DbBackend::Postgres, r#\"SELECT \"fruit\".\"id\" FROM \"fruit\"\"#);\n        let stmt = fruit::Entity::find().from_raw_sql(raw_stmt).exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            r#\"SELECT 1 FROM (SELECT \"fruit\".\"id\" FROM \"fruit\") AS sub_query LIMIT 1\"#\n        );\n    }\n\n    #[test]\n    fn exists_query_selector_raw_complex() {\n        let raw_stmt = Statement::from_string(\n            DbBackend::Postgres,\n            r#\"SELECT \"fruit\".\"id\" FROM \"fruit\" WHERE \"fruit\".\"id\" > 1 ORDER BY \"fruit\".\"id\" DESC LIMIT 5 OFFSET 2\"#,\n        );\n        let stmt = fruit::Entity::find().from_raw_sql(raw_stmt).exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            r#\"SELECT 1 FROM (SELECT \"fruit\".\"id\" FROM \"fruit\" WHERE \"fruit\".\"id\" > 1 ORDER BY \"fruit\".\"id\" DESC LIMIT 5 OFFSET 2) AS sub_query LIMIT 1\"#\n        );\n    }\n\n    #[test]\n    fn exists_query_select_two_simple() {\n        let stmt = cake::Entity::find()\n            .find_also_related(fruit::Entity)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            r#\"SELECT 1 FROM \"cake\" LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#\n        );\n    }\n\n    #[test]\n    fn exists_query_select_two_complex() {\n        let stmt = cake::Entity::find()\n            .find_also_related(fruit::Entity)\n            .filter(cake::Column::Id.gt(1))\n            .order_by_desc(cake::Column::Id)\n            .limit(2)\n            .offset(4)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake\"\"#,\n                r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                r#\"WHERE \"cake\".\"id\" > 1\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_three_simple() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_three_complex() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .filter(cake_filling::Column::CakeId.gt(1))\n            .order_by_desc(cake_filling::Column::CakeId)\n            .limit(2)\n            .offset(4)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"WHERE \"cake_filling\".\"cake_id\" > 1\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_four_simple() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .find_also(filling::Entity, ingredient::Entity)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"LEFT JOIN \"ingredient\" ON \"filling\".\"id\" = \"ingredient\".\"filling_id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_four_complex() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .find_also(filling::Entity, ingredient::Entity)\n            .filter(cake_filling::Column::CakeId.gt(1))\n            .order_by_desc(cake_filling::Column::CakeId)\n            .limit(2)\n            .offset(4)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"LEFT JOIN \"ingredient\" ON \"filling\".\"id\" = \"ingredient\".\"filling_id\"\"#,\n                r#\"WHERE \"cake_filling\".\"cake_id\" > 1\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_five_simple() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .find_also(filling::Entity, ingredient::Entity)\n            .find_also(cake_filling::Entity, cake_filling_price::Entity)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"LEFT JOIN \"ingredient\" ON \"filling\".\"id\" = \"ingredient\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"public\".\"cake_filling_price\" ON \"cake_filling\".\"cake_id\" = \"cake_filling_price\".\"cake_id\" AND \"cake_filling\".\"filling_id\" = \"cake_filling_price\".\"filling_id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_five_complex() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .find_also(filling::Entity, ingredient::Entity)\n            .find_also(cake_filling::Entity, cake_filling_price::Entity)\n            .filter(cake_filling::Column::CakeId.gt(1))\n            .order_by_desc(cake_filling::Column::CakeId)\n            .limit(2)\n            .offset(4)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"LEFT JOIN \"ingredient\" ON \"filling\".\"id\" = \"ingredient\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"public\".\"cake_filling_price\" ON \"cake_filling\".\"cake_id\" = \"cake_filling_price\".\"cake_id\" AND \"cake_filling\".\"filling_id\" = \"cake_filling_price\".\"filling_id\"\"#,\n                r#\"WHERE \"cake_filling\".\"cake_id\" > 1\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_six_simple() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .find_also(filling::Entity, ingredient::Entity)\n            .find_also(cake_filling::Entity, cake_filling_price::Entity)\n            .find_also(filling::Entity, cake_compact::Entity)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"LEFT JOIN \"ingredient\" ON \"filling\".\"id\" = \"ingredient\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"public\".\"cake_filling_price\" ON \"cake_filling\".\"cake_id\" = \"cake_filling_price\".\"cake_id\" AND \"cake_filling\".\"filling_id\" = \"cake_filling_price\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"cake_filling\" ON \"filling\".\"id\" = \"cake_filling\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_six_complex() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .find_also(filling::Entity, ingredient::Entity)\n            .find_also(cake_filling::Entity, cake_filling_price::Entity)\n            .find_also(filling::Entity, cake_compact::Entity)\n            .filter(cake_filling::Column::CakeId.gt(1))\n            .order_by_desc(cake_filling::Column::CakeId)\n            .limit(2)\n            .offset(4)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"LEFT JOIN \"ingredient\" ON \"filling\".\"id\" = \"ingredient\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"public\".\"cake_filling_price\" ON \"cake_filling\".\"cake_id\" = \"cake_filling_price\".\"cake_id\" AND \"cake_filling\".\"filling_id\" = \"cake_filling_price\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"cake_filling\" ON \"filling\".\"id\" = \"cake_filling\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"WHERE \"cake_filling\".\"cake_id\" > 1\"#,\n            ]\n            .join(\" \")\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/executor/update.rs",
    "content": "use super::ReturningSelector;\nuse crate::{\n    ActiveModelTrait, ColumnTrait, ConnectionTrait, EntityTrait, IntoActiveModel, Iterable,\n    PrimaryKeyTrait, SelectModel, UpdateMany, UpdateOne, ValidatedUpdateOne, error::*,\n};\nuse sea_query::{FromValueTuple, Query, UpdateStatement};\n\n/// Defines an update operation\n#[derive(Clone, Debug)]\npub struct Updater {\n    query: UpdateStatement,\n    check_record_exists: bool,\n}\n\n/// The result of an update operation on an ActiveModel\n#[derive(Clone, Debug, PartialEq, Eq, Default)]\npub struct UpdateResult {\n    /// The rows affected by the update operation\n    pub rows_affected: u64,\n}\n\nimpl<A> ValidatedUpdateOne<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Execute an UPDATE operation on an ActiveModel\n    pub fn exec<C>(self, db: &C) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        Updater::new(self.query).exec_update_and_return_updated(self.model, db)\n    }\n}\n\nimpl<A> UpdateOne<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Execute an UPDATE operation on an ActiveModel\n    pub fn exec<C>(self, db: &C) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        self.0?.exec(db)\n    }\n}\n\nimpl<'a, E> UpdateMany<E>\nwhere\n    E: EntityTrait,\n{\n    /// Execute an update operation on multiple ActiveModels\n    pub fn exec<C>(self, db: &'a C) -> Result<UpdateResult, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Updater::new(self.query).exec(db)\n    }\n\n    /// Execute an update operation and return the updated model (use `RETURNING` syntax if supported)\n    pub fn exec_with_returning<C>(self, db: &'a C) -> Result<Vec<E::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Updater::new(self.query).exec_update_with_returning::<E, _>(db)\n    }\n}\n\nimpl Updater {\n    /// Instantiate an update using an [UpdateStatement]\n    fn new(query: UpdateStatement) -> Self {\n        Self {\n            query,\n            check_record_exists: false,\n        }\n    }\n\n    /// Execute an update operation\n    pub fn exec<C>(self, db: &C) -> Result<UpdateResult, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.is_noop() {\n            return Ok(UpdateResult::default());\n        }\n        let result = db.execute(&self.query)?;\n        if self.check_record_exists && result.rows_affected() == 0 {\n            return Err(DbErr::RecordNotUpdated);\n        }\n        Ok(UpdateResult {\n            rows_affected: result.rows_affected(),\n        })\n    }\n\n    fn exec_update_and_return_updated<A, C>(\n        mut self,\n        model: A,\n        db: &C,\n    ) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\n    where\n        A: ActiveModelTrait,\n        C: ConnectionTrait,\n    {\n        type Entity<A> = <A as ActiveModelTrait>::Entity;\n        type Model<A> = <Entity<A> as EntityTrait>::Model;\n        type Column<A> = <Entity<A> as EntityTrait>::Column;\n\n        if self.is_noop() {\n            return find_updated_model_by_id(model, db);\n        }\n\n        match db.support_returning() {\n            true => {\n                let db_backend = db.get_database_backend();\n                let returning = Query::returning().exprs(\n                    Column::<A>::iter().map(|c| c.select_as(c.into_returning_expr(db_backend))),\n                );\n                self.query.returning(returning);\n                let found: Option<Model<A>> =\n                    ReturningSelector::<SelectModel<Model<A>>, _>::from_query(self.query)\n                        .one(db)?;\n                // If we got `None` then we are updating a row that does not exist.\n                match found {\n                    Some(model) => Ok(model),\n                    None => Err(DbErr::RecordNotUpdated),\n                }\n            }\n            false => {\n                // If we updating a row that does not exist then an error will be thrown here.\n                self.check_record_exists = true;\n                self.exec(db)?;\n                find_updated_model_by_id(model, db)\n            }\n        }\n    }\n\n    fn exec_update_with_returning<E, C>(mut self, db: &C) -> Result<Vec<E::Model>, DbErr>\n    where\n        E: EntityTrait,\n        C: ConnectionTrait,\n    {\n        if self.is_noop() {\n            return Ok(vec![]);\n        }\n\n        let db_backend = db.get_database_backend();\n        match db.support_returning() {\n            true => {\n                let returning = Query::returning().exprs(\n                    E::Column::iter().map(|c| c.select_as(c.into_returning_expr(db_backend))),\n                );\n                self.query.returning(returning);\n                let models: Vec<E::Model> =\n                    ReturningSelector::<SelectModel<E::Model>, _>::from_query(self.query)\n                        .all(db)?;\n                Ok(models)\n            }\n            false => Err(DbErr::BackendNotSupported {\n                db: db_backend.as_str(),\n                ctx: \"UPDATE RETURNING\",\n            }),\n        }\n    }\n\n    fn is_noop(&self) -> bool {\n        self.query.get_values().is_empty()\n    }\n}\n\nfn find_updated_model_by_id<A, C>(\n    model: A,\n    db: &C,\n) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\nwhere\n    A: ActiveModelTrait,\n    C: ConnectionTrait,\n{\n    type Entity<A> = <A as ActiveModelTrait>::Entity;\n    type ValueType<A> = <<Entity<A> as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType;\n\n    let primary_key_value = match model.get_primary_key_value() {\n        Some(val) => ValueType::<A>::from_value_tuple(val),\n        None => return Err(DbErr::UpdateGetPrimaryKey),\n    };\n    let found = Entity::<A>::find_by_id(primary_key_value).one(db)?;\n    // If we cannot select the updated row from db by the cached primary key\n    match found {\n        Some(model) => Ok(model),\n        None => Err(DbErr::RecordNotFound(\n            \"Failed to find updated item\".to_owned(),\n        )),\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        ColumnTrait, DbBackend, DbErr, EntityTrait, IntoActiveModel, MockDatabase, MockExecResult,\n        QueryFilter, Set, Transaction, Update, UpdateResult, tests_cfg::cake,\n    };\n    use pretty_assertions::assert_eq;\n    use sea_query::Expr;\n\n    #[test]\n    fn update_record_not_found_1() -> Result<(), DbErr> {\n        use crate::ActiveModelTrait;\n\n        let updated_cake = cake::Model {\n            id: 1,\n            name: \"Cheese Cake\".to_owned(),\n        };\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([\n                vec![updated_cake.clone()],\n                vec![],\n                vec![],\n                vec![],\n                vec![updated_cake.clone()],\n                vec![updated_cake.clone()],\n                vec![updated_cake.clone()],\n            ])\n            .append_exec_results([MockExecResult {\n                last_insert_id: 0,\n                rows_affected: 0,\n            }])\n            .into_connection();\n\n        let model = cake::Model {\n            id: 1,\n            name: \"New York Cheese\".to_owned(),\n        };\n\n        assert_eq!(\n            cake::ActiveModel {\n                name: Set(\"Cheese Cake\".to_owned()),\n                ..model.clone().into_active_model()\n            }\n            .update(&db)?,\n            cake::Model {\n                id: 1,\n                name: \"Cheese Cake\".to_owned(),\n            }\n        );\n\n        let model = cake::Model {\n            id: 2,\n            name: \"New York Cheese\".to_owned(),\n        };\n\n        assert_eq!(\n            cake::ActiveModel {\n                name: Set(\"Cheese Cake\".to_owned()),\n                ..model.clone().into_active_model()\n            }\n            .update(&db),\n            Err(DbErr::RecordNotUpdated)\n        );\n\n        assert_eq!(\n            cake::Entity::update(cake::ActiveModel {\n                name: Set(\"Cheese Cake\".to_owned()),\n                ..model.clone().into_active_model()\n            })\n            .exec(&db),\n            Err(DbErr::RecordNotUpdated)\n        );\n\n        assert_eq!(\n            Update::one(cake::ActiveModel {\n                name: Set(\"Cheese Cake\".to_owned()),\n                ..model.clone().into_active_model()\n            })\n            .exec(&db),\n            Err(DbErr::RecordNotUpdated)\n        );\n\n        assert_eq!(\n            Update::many(cake::Entity)\n                .col_expr(cake::Column::Name, Expr::value(\"Cheese Cake\".to_owned()))\n                .filter(cake::Column::Id.eq(2))\n                .exec(&db),\n            Ok(UpdateResult { rows_affected: 0 })\n        );\n\n        assert_eq!(\n            updated_cake.clone().into_active_model().save(&db)?,\n            updated_cake.clone().into_active_model()\n        );\n\n        assert_eq!(\n            updated_cake.clone().into_active_model().update(&db)?,\n            updated_cake\n        );\n\n        assert_eq!(\n            cake::Entity::update(updated_cake.clone().into_active_model()).exec(&db)?,\n            updated_cake\n        );\n\n        assert_eq!(cake::Entity::update_many().exec(&db)?.rows_affected, 0);\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"cake\" SET \"name\" = $1 WHERE \"cake\".\"id\" = $2 RETURNING \"id\", \"name\"\"#,\n                    [\"Cheese Cake\".into(), 1i32.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"cake\" SET \"name\" = $1 WHERE \"cake\".\"id\" = $2 RETURNING \"id\", \"name\"\"#,\n                    [\"Cheese Cake\".into(), 2i32.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"cake\" SET \"name\" = $1 WHERE \"cake\".\"id\" = $2 RETURNING \"id\", \"name\"\"#,\n                    [\"Cheese Cake\".into(), 2i32.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"cake\" SET \"name\" = $1 WHERE \"cake\".\"id\" = $2 RETURNING \"id\", \"name\"\"#,\n                    [\"Cheese Cake\".into(), 2i32.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"cake\" SET \"name\" = $1 WHERE \"cake\".\"id\" = $2\"#,\n                    [\"Cheese Cake\".into(), 2i32.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = $1 LIMIT $2\"#,\n                    [1.into(), 1u64.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = $1 LIMIT $2\"#,\n                    [1.into(), 1u64.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = $1 LIMIT $2\"#,\n                    [1.into(), 1u64.into()]\n                ),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn update_error() {\n        use crate::{DbBackend, DbErr, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::MySql).into_connection();\n\n        assert!(matches!(\n            Update::one(cake::ActiveModel {\n                ..Default::default()\n            })\n            .exec(&db),\n            Err(DbErr::PrimaryKeyNotSet { .. })\n        ));\n\n        assert!(matches!(\n            cake::Entity::update(cake::ActiveModel::default()).exec(&db),\n            Err(DbErr::PrimaryKeyNotSet { .. })\n        ));\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/lib.rs",
    "content": "#![cfg_attr(docsrs, feature(doc_cfg))]\n#![warn(missing_docs)]\n#![deny(\n    missing_debug_implementations,\n    clippy::missing_panics_doc,\n    clippy::unwrap_used,\n    clippy::print_stderr,\n    clippy::print_stdout\n)]\n\n//! <div align=\"center\">\n//!\n//!   <img alt=\"SeaORM\" src=\"https://www.sea-ql.org/blog/img/SeaORM 2.0 Banner.png\"/>\n//!\n//!   <h1></h1>\n//!   <h3>SeaORM is a powerful ORM for building web services in Rust</h3>\n//!\n//!   [![crate](https://img.shields.io/crates/v/sea-orm.svg)](https://crates.io/crates/sea-orm)\n//!   [![build status](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml/badge.svg)](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml)\n//!   [![GitHub stars](https://img.shields.io/github/stars/SeaQL/sea-orm.svg?style=social&label=Star&maxAge=1)](https://github.com/SeaQL/sea-orm/stargazers/)\n//!   <br>Support us with a ⭐ !\n//!\n//! </div>\n//!\n//! # 🐚 SeaORM\n//!\n//! [中文文档](https://github.com/SeaQL/sea-orm/blob/master/README-zh.md)\n//!\n//! ### Advanced Relations\n//!\n//! Model complex relationships 1-1, 1-N, M-N, and even self-referential in a high-level, conceptual way.\n//!\n//! ### Familiar Concepts\n//!\n//! Inspired by popular ORMs in the Ruby, Python, and Node.js ecosystem, SeaORM offers a developer experience that feels instantly recognizable.\n//!\n//! ### Feature Rich\n//!\n//! SeaORM is a batteries-included ORM with filters, pagination, and nested queries to accelerate building REST, GraphQL, and gRPC APIs.\n//!\n//! ### Production Ready\n//!\n//! With 250k+ weekly downloads, SeaORM is production-ready, trusted by startups and enterprises worldwide.\n//!\n//! ## Getting Started\n//!\n//! [![Discord](https://img.shields.io/discord/873880840487206962?label=Discord)](https://discord.com/invite/uCPdDXzbdv)\n//! Join our Discord server to chat with others!\n//!\n//! + [Documentation](https://www.sea-ql.org/SeaORM)\n//!\n//! Integration examples:\n//!\n//! + [Actix Example](https://github.com/SeaQL/sea-orm/tree/master/examples/actix_example)\n//! + [Axum Example](https://github.com/SeaQL/sea-orm/tree/master/examples/axum_example)\n//! + [GraphQL Example](https://github.com/SeaQL/sea-orm/tree/master/examples/graphql_example)\n//! + [jsonrpsee Example](https://github.com/SeaQL/sea-orm/tree/master/examples/jsonrpsee_example)\n//! + [Loco Example](https://github.com/SeaQL/sea-orm/tree/master/examples/loco_example) / [Loco REST Starter](https://github.com/SeaQL/sea-orm/tree/master/examples/loco_starter)\n//! + [Poem Example](https://github.com/SeaQL/sea-orm/tree/master/examples/poem_example)\n//! + [Rocket Example](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_example) / [Rocket OpenAPI Example](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_okapi_example)\n//! + [Salvo Example](https://github.com/SeaQL/sea-orm/tree/master/examples/salvo_example)\n//! + [Tonic Example](https://github.com/SeaQL/sea-orm/tree/master/examples/tonic_example)\n//! + [Seaography Example (Bakery)](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) / [Seaography Example (Sakila)](https://github.com/SeaQL/seaography/tree/main/examples/sqlite)\n//!\n//! If you want a simple, clean example that fits in a single file that demonstrates the best of SeaORM, you can try:\n//! + [Quickstart](https://github.com/SeaQL/sea-orm/blob/master/examples/quickstart/src/main.rs)\n//!\n//! Let's have a quick walk through of the unique features of SeaORM.\n//!\n//! ## Expressive Entity format\n//! You don't have to write this by hand! Entity files can be generated from an existing database using `sea-orm-cli`,\n//! following is generated with `--entity-format dense` *(new in 2.0)*.\n//! ```\n//! # #[cfg(feature = \"macros\")]\n//! # mod entities {\n//! # mod profile {\n//! # use sea_orm::entity::prelude::*;\n//! # #[sea_orm::model]\n//! # #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n//! # #[sea_orm(table_name = \"profile\")]\n//! # pub struct Model {\n//! #     #[sea_orm(primary_key)]\n//! #     pub id: i32,\n//! #     pub picture: String,\n//! #     #[sea_orm(unique)]\n//! #     pub user_id: i32,\n//! #     #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n//! #     pub user: HasOne<super::user::Entity>,\n//! # }\n//! # impl ActiveModelBehavior for ActiveModel {}\n//! # }\n//! # mod tag {\n//! # use sea_orm::entity::prelude::*;\n//! # #[sea_orm::model]\n//! # #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n//! # #[sea_orm(table_name = \"post\")]\n//! # pub struct Model {\n//! #     #[sea_orm(primary_key)]\n//! #     pub id: i32,\n//! #     #[sea_orm(has_many, via = \"post_tag\")]\n//! #     pub tags: HasMany<super::tag::Entity>,\n//! # }\n//! # impl ActiveModelBehavior for ActiveModel {}\n//! # }\n//! # mod post_tag {\n//! # use sea_orm::entity::prelude::*;\n//! # #[sea_orm::model]\n//! # #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n//! # #[sea_orm(table_name = \"post_tag\")]\n//! # pub struct Model {\n//! #     #[sea_orm(primary_key, auto_increment = false)]\n//! #     pub post_id: i32,\n//! #     #[sea_orm(primary_key, auto_increment = false)]\n//! #     pub tag_id: i32,\n//! #     #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n//! #     pub post: Option<super::post::Entity>,\n//! #     #[sea_orm(belongs_to, from = \"tag_id\", to = \"id\")]\n//! #     pub tag: Option<super::tag::Entity>,\n//! # }\n//! # impl ActiveModelBehavior for ActiveModel {}\n//! # }\n//! mod user {\n//!     use sea_orm::entity::prelude::*;\n//!\n//!     #[sea_orm::model]\n//!     #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n//!     #[sea_orm(table_name = \"user\")]\n//!     pub struct Model {\n//!         #[sea_orm(primary_key)]\n//!         pub id: i32,\n//!         pub name: String,\n//!         #[sea_orm(unique)]\n//!         pub email: String,\n//!         #[sea_orm(has_one)]\n//!         pub profile: HasOne<super::profile::Entity>,\n//!         #[sea_orm(has_many)]\n//!         pub posts: HasMany<super::post::Entity>,\n//!     }\n//! # impl ActiveModelBehavior for ActiveModel {}\n//! }\n//! mod post {\n//!     use sea_orm::entity::prelude::*;\n//!\n//!     #[sea_orm::model]\n//!     #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n//!     #[sea_orm(table_name = \"post\")]\n//!     pub struct Model {\n//!         #[sea_orm(primary_key)]\n//!         pub id: i32,\n//!         pub user_id: i32,\n//!         pub title: String,\n//!         #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n//!         pub author: HasOne<super::user::Entity>,\n//!         #[sea_orm(has_many, via = \"post_tag\")] // M-N relation with junction\n//!         pub tags: HasMany<super::tag::Entity>,\n//!     }\n//! # impl ActiveModelBehavior for ActiveModel {}\n//! }\n//! # }\n//! ```\n//!\n//! ## Smart Entity Loader\n//! The Entity Loader intelligently uses join for 1-1 and data loader for 1-N relations,\n//! eliminating the N+1 problem even when performing nested queries.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, prelude::*, entity::*, query::*, tests_cfg::*};\n//! # fn function(db: &DbConn) -> Result<(), DbErr> {\n//! // join paths:\n//! // user -> profile\n//! // user -> post\n//! //         post -> post_tag -> tag\n//! let smart_user = user::Entity::load()\n//!     .filter_by_id(42) // shorthand for .filter(user::COLUMN.id.eq(42))\n//!     .with(profile::Entity) // 1-1 uses join\n//!     .with((post::Entity, tag::Entity)) // 1-N uses data loader\n//!     .one(db)\n//!     ?\n//!     .unwrap();\n//!\n//! // 3 queries are executed under the hood:\n//! // 1. SELECT FROM user JOIN profile WHERE id = $\n//! // 2. SELECT FROM post WHERE user_id IN (..)\n//! // 3. SELECT FROM tag JOIN post_tag WHERE post_id IN (..)\n//!\n//! smart_user\n//!     == user::ModelEx {\n//!         id: 42,\n//!         name: \"Bob\".into(),\n//!         email: \"bob@sea-ql.org\".into(),\n//!         profile: HasOne::Loaded(\n//!             profile::ModelEx {\n//! #           id: 1,\n//!                 picture: \"image.jpg\".into(),\n//! #           user_id: 1,\n//! #           user: HasOne::Unloaded,\n//!             }\n//!             .into(),\n//!         ),\n//!         posts: HasMany::Loaded(vec![post::ModelEx {\n//! #           id: 2,\n//! #           user_id: 1,\n//!             title: \"Nice weather\".into(),\n//! #           author: HasOne::Unloaded,\n//! #           comments: HasMany::Unloaded,\n//!             tags: HasMany::Loaded(vec![tag::ModelEx {\n//! #               id: 3,\n//!                 tag: \"sunny\".into(),\n//! #               posts: HasMany::Unloaded,\n//!             }]),\n//!         }]),\n//!     };\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ## ActiveModel: nested persistence made simple\n//! Persist an entire object graph: user, profile (1-1), posts (1-N), and tags (M-N)\n//! in a single operation using a fluent builder API. SeaORM automatically determines\n//! the dependencies and inserts or deletes objects in the correct order.\n//!\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! # fn function(db: &DbConn) -> Result<(), DbErr> {\n//! // this creates the nested object as shown above:\n//! let user = user::ActiveModel::builder()\n//!     .set_name(\"Bob\")\n//!     .set_email(\"bob@sea-ql.org\")\n//!     .set_profile(profile::ActiveModel::builder().set_picture(\"image.jpg\"))\n//!     .add_post(\n//!         post::ActiveModel::builder()\n//!             .set_title(\"Nice weather\")\n//!             .add_tag(tag::ActiveModel::builder().set_tag(\"sunny\")),\n//!     )\n//!     .save(db)\n//!     ?;\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ## Schema first or Entity first? Your choice\n//!\n//! SeaORM provides a powerful migration system that lets you create tables, modify schemas, and seed data with ease.\n//!\n//! With SeaORM 2.0, you also get a first-class [Entity First Workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/):\n//! simply define new entities or add columns to existing ones,\n//! and SeaORM will automatically detect the changes and create the new tables, columns, unique keys, and foreign keys.\n//!\n//! ```ignore\n//! // SeaORM resolves foreign key dependencies and creates the tables in topological order.\n//! // Requires the `entity-registry` and `schema-sync` feature flags.\n//! db.get_schema_registry(\"my_crate::entity::*\").sync(db);\n//! ```\n//!\n//! ## Ergonomic Raw SQL\n//!\n//! Let SeaORM handle 95% of your transactional queries.\n//! For the remaining cases that are too complex to express,\n//! SeaORM still offers convenient support for writing raw SQL.\n//! ```\n//! # use sea_orm::{DbErr, DbConn};\n//! # fn function(db: &DbConn) -> Result<(), DbErr> {\n//! # use sea_orm::{entity::*, query::*, tests_cfg::*, raw_sql};\n//! # struct Item<'a> { name: &'a str }\n//! let user = Item { name: \"Bob\" }; // nested parameter access\n//! let ids = [2, 3, 4]; // expanded by the `..` operator\n//!\n//! let user: Option<user::Model> = user::Entity::find()\n//!     .from_raw_sql(raw_sql!(\n//!         Sqlite,\n//!         r#\"SELECT \"id\", \"name\" FROM \"user\"\n//!            WHERE \"name\" LIKE {user.name}\n//!            AND \"id\" in ({..ids})\n//!         \"#\n//!     ))\n//!     .one(db)\n//!     ?;\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ## Synchronous Support\n//!\n//! [`sea-orm-sync`](https://crates.io/crates/sea-orm-sync) provides the full SeaORM API without requiring an runtime, making it ideal for lightweight CLI programs with SQLite.\n//!\n//! See the [quickstart example](https://github.com/SeaQL/sea-orm/blob/master/sea-orm-sync/examples/quickstart/src/main.rs) for usage.\n//!\n//! ## Basics\n//!\n//! ### Select\n//! SeaORM models 1-N and M-N relationships at the Entity level,\n//! letting you traverse many-to-many links through a junction table in a single call.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! # fn function(db: &DbConn) -> Result<(), DbErr> {\n//! // find all models\n//! let cakes: Vec<cake::Model> = Cake::find().all(db)?;\n//!\n//! // find and filter\n//! let chocolate: Vec<cake::Model> = Cake::find()\n//!     .filter(Cake::COLUMN.name.contains(\"chocolate\"))\n//!     .all(db)\n//!     ?;\n//!\n//! // find one model\n//! let cheese: Option<cake::Model> = Cake::find_by_id(1).one(db)?;\n//! let cheese: cake::Model = cheese.unwrap();\n//!\n//! // find related models (lazy)\n//! let fruit: Option<fruit::Model> = cheese.find_related(Fruit).one(db)?;\n//!\n//! // find related models (eager): for 1-1 relations\n//! let cake_with_fruit: Vec<(cake::Model, Option<fruit::Model>)> =\n//!     Cake::find().find_also_related(Fruit).all(db)?;\n//!\n//! // find related models (eager): works for both 1-N and M-N relations\n//! let cake_with_fillings: Vec<(cake::Model, Vec<filling::Model>)> = Cake::find()\n//!     .find_with_related(Filling) // for M-N relations, two joins are performed\n//!     .all(db) // rows are automatically consolidated by left entity\n//!     ?;\n//! # Ok(())\n//! # }\n//! ```\n//! ### Nested Select\n//!\n//! Partial models prevent overfetching by letting you querying only the fields\n//! you need; it also makes writing deeply nested relational queries simple.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! # fn function(db: &DbConn) -> Result<(), DbErr> {\n//! use sea_orm::DerivePartialModel;\n//!\n//! #[derive(DerivePartialModel)]\n//! #[sea_orm(entity = \"cake::Entity\")]\n//! struct CakeWithFruit {\n//!     id: i32,\n//!     name: String,\n//!     #[sea_orm(nested)]\n//!     fruit: Option<fruit::Model>, // this can be a regular or another partial model\n//! }\n//!\n//! let cakes: Vec<CakeWithFruit> = Cake::find()\n//!     .left_join(fruit::Entity) // no need to specify join condition\n//!     .into_partial_model() // only the columns in the partial model will be selected\n//!     .all(db)\n//!     ?;\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ### Insert\n//! SeaORM's ActiveModel lets you work directly with Rust data structures and\n//! persist them through a simple API.\n//! It's easy to insert large batches of rows from different data sources.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! # fn function(db: &DbConn) -> Result<(), DbErr> {\n//! let apple = fruit::ActiveModel {\n//!     name: Set(\"Apple\".to_owned()),\n//!     ..Default::default() // no need to set primary key\n//! };\n//!\n//! let pear = fruit::ActiveModel {\n//!     name: Set(\"Pear\".to_owned()),\n//!     ..Default::default()\n//! };\n//!\n//! // insert one: Active Record style\n//! let apple = apple.insert(db)?;\n//! apple.id == 1;\n//! # let apple = fruit::ActiveModel {\n//! #     name: Set(\"Apple\".to_owned()),\n//! #     ..Default::default() // no need to set primary key\n//! # };\n//!\n//! // insert one: repository style\n//! let result = Fruit::insert(apple).exec(db)?;\n//! result.last_insert_id == 1;\n//! # let apple = fruit::ActiveModel {\n//! #     name: Set(\"Apple\".to_owned()),\n//! #     ..Default::default() // no need to set primary key\n//! # };\n//!\n//! // insert many returning last insert id\n//! let result = Fruit::insert_many([apple, pear]).exec(db)?;\n//! result.last_insert_id == Some(2);\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ### Insert (advanced)\n//! You can take advantage of database specific features to perform upsert and idempotent insert.\n//! ```\n//! # use sea_orm::{DbConn, TryInsertResult, DbErr, entity::*, query::*, tests_cfg::*};\n//! # fn function_1(db: &DbConn) -> Result<(), DbErr> {\n//! # let apple = fruit::ActiveModel {\n//! #     name: Set(\"Apple\".to_owned()),\n//! #     ..Default::default() // no need to set primary key\n//! # };\n//! # let pear = fruit::ActiveModel {\n//! #     name: Set(\"Pear\".to_owned()),\n//! #     ..Default::default()\n//! # };\n//! // insert many with returning (if supported by database)\n//! let models: Vec<fruit::Model> = Fruit::insert_many([apple, pear])\n//!     .exec_with_returning(db)\n//!     ?;\n//! models[0]\n//!     == fruit::Model {\n//!         id: 1, // database assigned value\n//!         name: \"Apple\".to_owned(),\n//!         cake_id: None,\n//!     };\n//! # Ok(())\n//! # }\n//!\n//! # fn function_2(db: &DbConn) -> Result<(), DbErr> {\n//! # let apple = fruit::ActiveModel {\n//! #     name: Set(\"Apple\".to_owned()),\n//! #     ..Default::default() // no need to set primary key\n//! # };\n//! # let pear = fruit::ActiveModel {\n//! #     name: Set(\"Pear\".to_owned()),\n//! #     ..Default::default()\n//! # };\n//! // insert with ON CONFLICT on primary key do nothing, with MySQL specific polyfill\n//! let result = Fruit::insert_many([apple, pear])\n//!     .on_conflict_do_nothing()\n//!     .exec(db)\n//!     ?;\n//!\n//! matches!(result, TryInsertResult::Conflicted);\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ### Update\n//! ActiveModel avoids race conditions by updating only the fields you've changed,\n//! never overwriting untouched columns.\n//! You can also craft complex bulk update queries with a fluent query building API.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! use sea_orm::sea_query::{Expr, Value};\n//!\n//! # fn function(db: &DbConn) -> Result<(), DbErr> {\n//! let pear: Option<fruit::Model> = Fruit::find_by_id(1).one(db)?;\n//! let mut pear: fruit::ActiveModel = pear.unwrap().into();\n//!\n//! pear.name = Set(\"Sweet pear\".to_owned()); // update value of a single field\n//!\n//! // update one: only changed columns will be updated\n//! let pear: fruit::Model = pear.update(db)?;\n//!\n//! // update many: UPDATE \"fruit\" SET \"cake_id\" = \"cake_id\" + 2\n//! //               WHERE \"fruit\".\"name\" LIKE '%Apple%'\n//! Fruit::update_many()\n//!     .col_expr(fruit::COLUMN.cake_id, fruit::COLUMN.cake_id.add(2))\n//!     .filter(fruit::COLUMN.name.contains(\"Apple\"))\n//!     .exec(db)\n//!     ?;\n//! # Ok(())\n//! # }\n//! ```\n//! ### Save\n//! You can perform \"insert or update\" operation with ActiveModel, making it easy to compose transactional operations.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! # fn function(db: &DbConn) -> Result<(), DbErr> {\n//! let banana = fruit::ActiveModel {\n//!     id: NotSet,\n//!     name: Set(\"Banana\".to_owned()),\n//!     ..Default::default()\n//! };\n//!\n//! // create, because primary key `id` is `NotSet`\n//! let mut banana = banana.save(db)?;\n//!\n//! banana.id == Unchanged(2);\n//! banana.name = Set(\"Banana Mongo\".to_owned());\n//!\n//! // update, because primary key `id` is present\n//! let banana = banana.save(db)?;\n//! # Ok(())\n//! # }\n//! ```\n//! ### Delete\n//! The same ActiveModel API consistent with insert and update.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! # fn function(db: &DbConn) -> Result<(), DbErr> {\n//! // delete one: Active Record style\n//! let orange: Option<fruit::Model> = Fruit::find_by_id(1).one(db)?;\n//! let orange: fruit::Model = orange.unwrap();\n//! orange.delete(db)?;\n//!\n//! // delete one: repository style\n//! let orange = fruit::ActiveModel {\n//!     id: Set(2),\n//!     ..Default::default()\n//! };\n//! fruit::Entity::delete(orange).exec(db)?;\n//!\n//! // delete many: DELETE FROM \"fruit\" WHERE \"fruit\".\"name\" LIKE '%Orange%'\n//! fruit::Entity::delete_many()\n//!     .filter(fruit::COLUMN.name.contains(\"Orange\"))\n//!     .exec(db)\n//!     ?;\n//!\n//! # Ok(())\n//! # }\n//! ```\n//! ### Raw SQL Query\n//! The `raw_sql!` macro is like the `format!` macro but without the risk of SQL injection.\n//! It supports nested parameter interpolation, array and tuple expansion, and even repeating group,\n//! offering great flexibility in crafting complex queries.\n//!\n//! ```\n//! # use sea_orm::{DbErr, DbConn};\n//! # fn functio(db: &DbConn) -> Result<(), DbErr> {\n//! # use sea_orm::{query::*, FromQueryResult, raw_sql};\n//! #[derive(FromQueryResult)]\n//! struct CakeWithBakery {\n//!     name: String,\n//!     #[sea_orm(nested)]\n//!     bakery: Option<Bakery>,\n//! }\n//!\n//! #[derive(FromQueryResult)]\n//! struct Bakery {\n//!     #[sea_orm(alias = \"bakery_name\")]\n//!     name: String,\n//! }\n//!\n//! let cake_ids = [2, 3, 4]; // expanded by the `..` operator\n//!\n//! // can use many APIs with raw SQL, including nested select\n//! let cake: Option<CakeWithBakery> = CakeWithBakery::find_by_statement(raw_sql!(\n//!     Sqlite,\n//!     r#\"SELECT \"cake\".\"name\", \"bakery\".\"name\" AS \"bakery_name\"\n//!        FROM \"cake\"\n//!        LEFT JOIN \"bakery\" ON \"cake\".\"bakery_id\" = \"bakery\".\"id\"\n//!        WHERE \"cake\".\"id\" IN ({..cake_ids})\"#\n//! ))\n//! .one(db)\n//! ?;\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ## 🧭 Seaography: instant GraphQL API\n//!\n//! [Seaography](https://github.com/SeaQL/seaography) is a GraphQL framework built for SeaORM.\n//! Seaography allows you to build GraphQL resolvers quickly.\n//! With just a few commands, you can launch a fullly-featured GraphQL server from SeaORM entities,\n//! complete with filter, pagination, relational queries and mutations!\n//!\n//! Look at the [Seaography Example](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) to learn more.\n//!\n//! <img src=\"https://raw.githubusercontent.com/SeaQL/sea-orm/master/examples/seaography_example/Seaography%20example.png\"/>\n//!\n//! ## 🖥️ SeaORM Pro: Professional Admin Panel\n//!\n//! [SeaORM Pro](https://github.com/SeaQL/sea-orm-pro/) is an admin panel solution allowing you to quickly and easily launch an admin panel for your application - frontend development skills not required, but certainly nice to have!\n//!\n//! SeaORM Pro has been updated to support the latest features in SeaORM 2.0.\n//!\n//! Features:\n//!\n//! + Full CRUD\n//! + Built on React + GraphQL\n//! + Built-in GraphQL resolver\n//! + Customize the UI with TOML config\n//! + Role Based Access Control *(new in 2.0)*\n//!\n//! Read the [Getting Started](https://www.sea-ql.org/sea-orm-pro/docs/install-and-config/getting-started/) guide to learn more.\n//!\n//! ![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-dark.png#gh-dark-mode-only)\n//! ![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-light.png#gh-light-mode-only)\n//!\n//! ## SQL Server Support\n//!\n//! [SQL Server for SeaORM](https://www.sea-ql.org/SeaORM-X/) offers the same SeaORM API for MSSQL. We ported all test cases and examples, complemented by MSSQL specific documentation. If you are building enterprise software, you can [request commercial access](https://forms.office.com/r/1MuRPJmYBR). It is currently based on SeaORM 1.0, but we will offer free upgrade to existing users when SeaORM 2.0 is finalized.\n//!\n//! ## Releases\n//!\n//! SeaORM 2.0 has reached its release candidate phase. We'd love for you to try it out and help shape the final release by [sharing your feedback](https://github.com/SeaQL/sea-orm/discussions/).\n//!\n//! + [Change Log](https://github.com/SeaQL/sea-orm/tree/master/CHANGELOG.md)\n//!\n//! SeaORM 2.0 is shaping up to be our most significant release yet - with a few breaking changes, plenty of enhancements, and a clear focus on developer experience.\n//!\n//! + [A Sneak Peek at SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-16-sea-orm-2.0/)\n//! + [SeaORM 2.0: A closer look](https://www.sea-ql.org/blog/2025-09-24-sea-orm-2.0/)\n//! + [Role Based Access Control in SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-30-sea-orm-rbac/)\n//! + [Seaography 2.0: A Powerful and Extensible GraphQL Framework](https://www.sea-ql.org/blog/2025-10-08-seaography/)\n//! + [SeaORM 2.0: New Entity Format](https://www.sea-ql.org/blog/2025-10-20-sea-orm-2.0/)\n//! + [SeaORM 2.0: Entity First Workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/)\n//! + [SeaORM 2.0: Strongly-Typed Column](https://www.sea-ql.org/blog/2025-11-11-sea-orm-2.0/)\n//! + [What's new in SeaORM Pro 2.0](https://www.sea-ql.org/blog/2025-11-21-whats-new-in-seaormpro-2.0/)\n//! + [SeaORM 2.0: Nested ActiveModel](https://www.sea-ql.org/blog/2025-11-25-sea-orm-2.0/)\n//! + [A walk-through of SeaORM 2.0](https://www.sea-ql.org/blog/2025-12-05-sea-orm-2.0/)\n//! + [How we made SeaORM synchronous](https://www.sea-ql.org/blog/2025-12-12-sea-orm-2.0/)\n//! + [SeaORM 2.0 Migration Guide](https://www.sea-ql.org/blog/2026-01-12-sea-orm-2.0/)\n//! + [SeaORM now supports Arrow & Parquet](https://www.sea-ql.org/blog/2026-02-22-sea-orm-arrow/)\n//! + [SeaORM 2.0 with SQL Server Support](https://www.sea-ql.org/blog/2026-02-25-sea-orm-x/)\n//!\n//! If you make extensive use of SeaQuery, we recommend checking out our blog post on SeaQuery 1.0 release:\n//!\n//! + [The road to SeaQuery 1.0](https://www.sea-ql.org/blog/2025-08-30-sea-query-1.0/)\n//!\n//! ## License\n//!\n//! Licensed under either of\n//!\n//! -   Apache License, Version 2.0\n//!     ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)\n//! -   MIT license\n//!     ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)\n//!\n//! at your option.\n//!\n//! ## Contribution\n//!\n//! Unless you explicitly state otherwise, any contribution intentionally submitted\n//! for inclusion in the work by you, as defined in the Apache-2.0 license, shall be\n//! dual licensed as above, without any additional terms or conditions.\n//!\n//! We invite you to participate, contribute and together help build Rust's future.\n//!\n//! A big shout out to our contributors!\n//!\n//! [![Contributors](https://opencollective.com/sea-orm/contributors.svg?width=1000&button=false)](https://github.com/SeaQL/sea-orm/graphs/contributors)\n//!\n//! ## Who's using SeaORM?\n//!\n//! Here is a short list of awesome open source software built with SeaORM. Feel free to [submit yours](https://github.com/SeaQL/sea-orm/blob/master/COMMUNITY.md#built-with-seaorm)!\n//!\n//! | Project | GitHub | Tagline |\n//! |---------|--------|---------|\n//! | [Zed](https://github.com/zed-industries/zed) | ![GitHub stars](https://img.shields.io/github/stars/zed-industries/zed.svg?style=social) | A high-performance, multiplayer code editor |\n//! | [OpenObserve](https://github.com/openobserve/openobserve) | ![GitHub stars](https://img.shields.io/github/stars/openobserve/openobserve.svg?style=social) | Open-source observability platform |\n//! | [RisingWave](https://github.com/risingwavelabs/risingwave) | ![GitHub stars](https://img.shields.io/github/stars/risingwavelabs/risingwave.svg?style=social) | Stream processing and management platform |\n//! | [LLDAP](https://github.com/nitnelave/lldap) | ![GitHub stars](https://img.shields.io/github/stars/nitnelave/lldap.svg?style=social) | A light LDAP server for user management |\n//! | [Warpgate](https://github.com/warp-tech/warpgate) | ![GitHub stars](https://img.shields.io/github/stars/warp-tech/warpgate.svg?style=social) | Smart SSH bastion that works with any SSH client |\n//! | [Svix](https://github.com/svix/svix-webhooks) | ![GitHub stars](https://img.shields.io/github/stars/svix/svix-webhooks.svg?style=social) | The enterprise ready webhooks service |\n//! | [Ryot](https://github.com/IgnisDa/ryot) | ![GitHub stars](https://img.shields.io/github/stars/ignisda/ryot.svg?style=social) | The only self hosted tracker you will ever need |\n//! | [Lapdev](https://github.com/lapce/lapdev) | ![GitHub stars](https://img.shields.io/github/stars/lapce/lapdev.svg?style=social) | Self-hosted remote development enviroment |\n//! | [System Initiative](https://github.com/systeminit/si) | ![GitHub stars](https://img.shields.io/github/stars/systeminit/si.svg?style=social) | DevOps Automation Platform |\n//! | [OctoBase](https://github.com/toeverything/OctoBase) | ![GitHub stars](https://img.shields.io/github/stars/toeverything/OctoBase.svg?style=social) | A light-weight, scalable, offline collaborative data backend |\n//!\n//! ## Sponsorship\n//!\n//! [SeaQL.org](https://www.sea-ql.org/) is an independent open-source organization run by passionate developers.\n//! If you feel generous, a small donation via [GitHub Sponsor](https://github.com/sponsors/SeaQL) will be greatly appreciated, and goes a long way towards sustaining the organization.\n//!\n//! ### Gold Sponsors\n//!\n//! <table><tr>\n//! <td><a href=\"https://qdx.co/\">\n//!   <img src=\"https://www.sea-ql.org/static/sponsors/QDX.svg\" width=\"138\"/>\n//! </a></td>\n//! </tr></table>\n//!\n//! [QDX](https://qdx.co/) pioneers quantum dynamics-powered drug discovery, leveraging AI and supercomputing to accelerate molecular modeling.\n//! We're immensely grateful to QDX for sponsoring the development of SeaORM, the SQL toolkit that powers their data intensive applications.\n//!\n//! ### Silver Sponsors\n//!\n//! We're grateful to our silver sponsors: Digital Ocean, for sponsoring our servers. And JetBrains, for sponsoring our IDE.\n//!\n//! <table><tr>\n//! <td><a href=\"https://www.digitalocean.com/\">\n//!   <img src=\"https://www.sea-ql.org/static/sponsors/DigitalOcean.svg\" width=\"125\">\n//! </a></td>\n//!\n//! <td><a href=\"https://www.jetbrains.com/\">\n//!   <img src=\"https://www.sea-ql.org/static/sponsors/JetBrains.svg\" width=\"125\">\n//! </a></td>\n//! </tr></table>\n//!\n//! ## Mascot\n//!\n//! A friend of Ferris, Terres the hermit crab is the official mascot of SeaORM. His hobby is collecting shells.\n//!\n//! <img alt=\"Terres\" src=\"https://www.sea-ql.org/SeaORM/img/Terres.png\" width=\"400\"/>\n//!\n//! ## 🦀 Rustacean Sticker Pack\n//! The Rustacean Sticker Pack is the perfect way to express your passion for Rust. Our stickers are made with a premium water-resistant vinyl with a unique matte finish.\n//!\n//! Sticker Pack Contents:\n//!\n//! + Logo of SeaQL projects: SeaQL, SeaORM, SeaQuery, Seaography\n//! + Mascots: Ferris the Crab x 3, Terres the Hermit Crab\n//! + The Rustacean wordmark\n//!\n//! [Support SeaQL and get a Sticker Pack!](https://www.sea-ql.org/sticker-pack/) All proceeds contributes directly to the ongoing development of SeaQL projects.\n//!\n//! <a href=\"https://www.sea-ql.org/sticker-pack/\"><img alt=\"Rustacean Sticker Pack by SeaQL\" src=\"https://www.sea-ql.org/static/sticker-pack-1s.jpg\" width=\"600\"/></a>\n#![doc(\n    html_logo_url = \"https://raw.githubusercontent.com/SeaQL/sea-query/master/docs/SeaQL icon dark.png\"\n)]\n\nmod database;\nmod docs;\nmod driver;\npub mod dynamic;\n/// Module for the Entity type and operations\npub mod entity;\n/// Error types for all database operations\npub mod error;\n/// This module performs execution of queries on a Model or ActiveModel\nmod executor;\n/// Types and methods to perform metric collection\npub mod metric;\n/// Types and methods to perform queries\npub mod query;\n#[cfg(feature = \"rbac\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"rbac\")))]\npub mod rbac;\n/// Types that defines the schemas of an Entity\npub mod schema;\n/// Helpers for working with Value\npub mod value;\n\n#[doc(hidden)]\n#[cfg(all(feature = \"macros\", feature = \"tests-cfg\"))]\npub mod tests_cfg;\nmod util;\n\npub use database::*;\n#[allow(unused_imports)]\npub use driver::*;\npub use entity::*;\npub use error::*;\npub use executor::*;\npub use query::*;\npub use schema::*;\n\n#[cfg(feature = \"macros\")]\npub use sea_orm_macros::{\n    DeriveActiveEnum, DeriveActiveModel, DeriveActiveModelBehavior, DeriveActiveModelEx,\n    DeriveArrowSchema, DeriveColumn, DeriveDisplay, DeriveEntity, DeriveEntityModel, DeriveIden,\n    DeriveIntoActiveModel, DeriveMigrationName, DeriveModel, DeriveModelEx, DerivePartialModel,\n    DerivePrimaryKey, DeriveRelatedEntity, DeriveRelation, DeriveValueType, FromJsonQueryResult,\n    FromQueryResult, raw_sql, sea_orm_compact_model as compact_model, sea_orm_model as model,\n};\n\npub use sea_query;\npub use sea_query::Iden;\n\npub use sea_orm_macros::EnumIter;\npub use strum;\n\n#[cfg(feature = \"with-arrow\")]\npub use sea_orm_arrow::arrow;\n\n#[cfg(feature = \"sqlx-dep\")]\npub use sqlx;\n"
  },
  {
    "path": "sea-orm-sync/src/metric.rs",
    "content": "use std::{sync::Arc, time::Duration};\n\npub(crate) type Callback = Arc<dyn Fn(&Info<'_>)>;\n\n#[allow(unused_imports)]\npub(crate) use inner::metric;\n\n#[derive(Debug)]\n/// Query execution infos\npub struct Info<'a> {\n    /// Query executiuon duration\n    pub elapsed: Duration,\n    /// Query data\n    pub statement: &'a crate::Statement,\n    /// Query execution failed\n    pub failed: bool,\n}\n\nmod inner {\n    #[allow(unused_macros)]\n    macro_rules! metric {\n        ($metric_callback:expr, $stmt:expr, $code:block) => {{\n            let _start = $metric_callback.is_some().then(std::time::SystemTime::now);\n            let res = $code;\n            if let (Some(_start), Some(callback)) = (_start, $metric_callback.as_deref()) {\n                let info = crate::metric::Info {\n                    elapsed: _start.elapsed().unwrap_or_default(),\n                    statement: $stmt,\n                    failed: res.is_err(),\n                };\n                callback(&info);\n            }\n            res\n        }};\n    }\n    pub(crate) use metric;\n}\n"
  },
  {
    "path": "sea-orm-sync/src/query/combine.rs",
    "content": "use crate::{\n    ColumnTrait, EntityTrait, IdenStatic, Iterable, QueryTrait, Select, SelectTwo, SelectTwoMany,\n};\nuse core::marker::PhantomData;\nuse sea_query::{Iden, IntoIden, Order, SelectExpr, SelectStatement, SimpleExpr};\nuse std::borrow::Cow;\n\nmacro_rules! select_def {\n    ( $ident: ident, $str: expr ) => {\n        /// Implements the traits [Iden] for select alias\n        #[derive(Debug, Clone, Copy)]\n        pub struct $ident;\n\n        impl Iden for $ident {\n            fn quoted(&self) -> Cow<'static, str> {\n                Cow::Borrowed(IdenStatic::as_str(self))\n            }\n\n            fn unquoted(&self) -> &str {\n                IdenStatic::as_str(self)\n            }\n        }\n\n        impl IdenStatic for $ident {\n            fn as_str(&self) -> &'static str {\n                $str\n            }\n        }\n    };\n}\n\nselect_def!(SelectA, \"A_\");\nselect_def!(SelectB, \"B_\");\nselect_def!(SelectC, \"C_\");\nselect_def!(SelectD, \"D_\");\nselect_def!(SelectE, \"E_\");\nselect_def!(SelectF, \"F_\");\n\nimpl<E> Select<E>\nwhere\n    E: EntityTrait,\n{\n    pub(crate) fn apply_alias(mut self, pre: &str) -> Self {\n        self.query().exprs_mut_for_each(|sel| {\n            match &sel.alias {\n                Some(alias) => {\n                    let alias = format!(\"{}{}\", pre, alias.to_string().as_str());\n                    sel.alias = Some(alias.into_iden());\n                }\n                None => {\n                    let col = match &sel.expr {\n                        SimpleExpr::Column(col_ref) => match col_ref.column() {\n                            Some(col) => col,\n                            None => {\n                                panic!(\"cannot apply alias for Column with asterisk\");\n                            }\n                        },\n                        SimpleExpr::AsEnum(_, simple_expr) => match simple_expr.as_ref() {\n                            SimpleExpr::Column(col_ref) => match col_ref.column() {\n                                Some(col) => col,\n                                None => {\n                                    panic!(\"cannot apply alias for AsEnum with asterisk\")\n                                }\n                            },\n                            _ => {\n                                panic!(\"cannot apply alias for AsEnum with expr other than Column\")\n                            }\n                        },\n                        _ => panic!(\"cannot apply alias for expr other than Column or AsEnum\"),\n                    };\n                    let alias = format!(\"{}{}\", pre, col.to_string().as_str());\n                    sel.alias = Some(alias.into_iden());\n                }\n            };\n        });\n        self\n    }\n\n    /// Selects extra Entity and returns it together with the Entity from `Self`\n    pub fn select_also<F>(mut self, _: F) -> SelectTwo<E, F>\n    where\n        F: EntityTrait,\n    {\n        self = self.apply_alias(SelectA.as_str());\n        SelectTwo::new(self.into_query())\n    }\n\n    /// Only used by Entity loader\n    #[doc(hidden)]\n    pub fn select_also_fake<F>(mut self, _: F) -> SelectTwo<E, F>\n    where\n        F: EntityTrait,\n    {\n        self = self.apply_alias(SelectA.as_str());\n        SelectTwo::new_without_prepare(self.into_query())\n    }\n\n    /// Makes a SELECT operation in conjunction to another relation\n    pub fn select_with<F>(mut self, _: F) -> SelectTwoMany<E, F>\n    where\n        F: EntityTrait,\n    {\n        self = self.apply_alias(SelectA.as_str());\n        SelectTwoMany::new(self.into_query())\n    }\n}\n\nimpl<E, F> SelectTwo<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query).prepare_select()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<F, _, _>(&mut self, SelectB);\n        self\n    }\n}\n\nimpl<E, F> SelectTwoMany<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query)\n            .prepare_select()\n            .prepare_order_by()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<F, _, _>(&mut self, SelectB);\n        self\n    }\n\n    fn prepare_order_by(mut self) -> Self {\n        for col in <E::PrimaryKey as Iterable>::iter() {\n            self.query.order_by((E::default(), col), Order::Asc);\n        }\n        self\n    }\n}\n\npub(crate) fn prepare_select_col<F, S, A>(selector: &mut S, alias: A)\nwhere\n    F: EntityTrait,\n    S: QueryTrait<QueryStatement = SelectStatement>,\n    A: IdenStatic,\n{\n    for col in <F::Column as Iterable>::iter() {\n        let alias = format!(\"{}{}\", alias.as_str(), col.as_str());\n        selector.query().expr(SelectExpr {\n            expr: col.select_as(col.into_expr()),\n            alias: Some(alias.into_iden()),\n            window: None,\n        });\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::{cake, fruit};\n    use crate::{ColumnTrait, DbBackend, EntityTrait, QueryFilter, QuerySelect, QueryTrait};\n\n    #[test]\n    fn alias_1() {\n        assert_eq!(\n            cake::Entity::find()\n                .column_as(cake::Column::Id, \"B\")\n                .apply_alias(\"A_\")\n                .build(DbBackend::MySql)\n                .to_string(),\n            \"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`, `cake`.`id` AS `A_B` FROM `cake`\",\n        );\n    }\n\n    #[test]\n    fn select_also_1() {\n        assert_eq!(\n            cake::Entity::find()\n                .left_join(fruit::Entity)\n                .select_also(fruit::Entity)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                \"`fruit`.`id` AS `B_id`, `fruit`.`name` AS `B_name`, `fruit`.`cake_id` AS `B_cake_id`\",\n                \"FROM `cake` LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`\",\n            ].join(\" \")\n        );\n    }\n\n    #[test]\n    fn select_with_1() {\n        assert_eq!(\n            cake::Entity::find()\n                .left_join(fruit::Entity)\n                .select_with(fruit::Entity)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                \"`fruit`.`id` AS `B_id`, `fruit`.`name` AS `B_name`, `fruit`.`cake_id` AS `B_cake_id`\",\n                \"FROM `cake` LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`\",\n                \"ORDER BY `cake`.`id` ASC\",\n            ].join(\" \")\n        );\n    }\n\n    #[test]\n    fn select_also_2() {\n        assert_eq!(\n            cake::Entity::find()\n                .left_join(fruit::Entity)\n                .select_also(fruit::Entity)\n                .filter(cake::Column::Id.eq(1))\n                .filter(fruit::Column::Id.eq(2))\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                \"`fruit`.`id` AS `B_id`, `fruit`.`name` AS `B_name`, `fruit`.`cake_id` AS `B_cake_id`\",\n                \"FROM `cake` LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`\",\n                \"WHERE `cake`.`id` = 1 AND `fruit`.`id` = 2\",\n            ].join(\" \")\n        );\n    }\n\n    #[test]\n    fn select_with_2() {\n        assert_eq!(\n            cake::Entity::find()\n                .left_join(fruit::Entity)\n                .select_with(fruit::Entity)\n                .filter(cake::Column::Id.eq(1))\n                .filter(fruit::Column::Id.eq(2))\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                \"`fruit`.`id` AS `B_id`, `fruit`.`name` AS `B_name`, `fruit`.`cake_id` AS `B_cake_id`\",\n                \"FROM `cake` LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`\",\n                \"WHERE `cake`.`id` = 1 AND `fruit`.`id` = 2\",\n                \"ORDER BY `cake`.`id` ASC\",\n            ].join(\" \")\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/query/debug.rs",
    "content": "use crate::{QueryTrait, Statement, database::*};\n\n/// This structure provides debug capabilities\n#[derive(Debug)]\npub struct DebugQuery<'a, Q, T> {\n    /// The query to debug\n    pub query: &'a Q,\n    /// The value of the query\n    pub value: T,\n}\n\nmacro_rules! debug_query_build {\n    ($impl_obj:ty, $db_expr:expr) => {\n        impl<'a, Q> DebugQuery<'a, Q, $impl_obj>\n        where\n            Q: QueryTrait,\n        {\n            /// This macro builds a [Statement] when invoked\n            pub fn build(&self) -> Statement {\n                let func = $db_expr;\n                let db_backend = func(self);\n                self.query.build(db_backend)\n            }\n        }\n    };\n}\n\ndebug_query_build!(DbBackend, |x: &DebugQuery<_, DbBackend>| x.value);\ndebug_query_build!(&DbBackend, |x: &DebugQuery<_, &DbBackend>| *x.value);\ndebug_query_build!(DatabaseConnection, |x: &DebugQuery<\n    _,\n    DatabaseConnection,\n>| x.value.get_database_backend());\ndebug_query_build!(&DatabaseConnection, |x: &DebugQuery<\n    _,\n    &DatabaseConnection,\n>| x.value.get_database_backend());\n\n/// Helper to get a `Statement` from an object that impl `QueryTrait`.\n///\n/// # Example\n///\n/// ```\n/// # #[cfg(feature = \"mock\")]\n/// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, DbBackend};\n/// #\n/// # let conn = MockDatabase::new(DbBackend::Postgres)\n/// #     .into_connection();\n/// #\n/// use sea_orm::{debug_query_stmt, entity::*, query::*, tests_cfg::cake};\n///\n/// let c = cake::Entity::insert(cake::ActiveModel {\n///     id: ActiveValue::set(1),\n///     name: ActiveValue::set(\"Apple Pie\".to_owned()),\n/// });\n///\n/// let raw_sql = debug_query_stmt!(&c, &conn).to_string();\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#\n/// );\n///\n/// let raw_sql = debug_query_stmt!(&c, conn).to_string();\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#\n/// );\n///\n/// let raw_sql = debug_query_stmt!(&c, DbBackend::MySql).to_string();\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO `cake` (`id`, `name`) VALUES (1, 'Apple Pie')\"#\n/// );\n///\n/// let raw_sql = debug_query_stmt!(&c, &DbBackend::MySql).to_string();\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO `cake` (`id`, `name`) VALUES (1, 'Apple Pie')\"#\n/// );\n/// ```\n#[macro_export]\nmacro_rules! debug_query_stmt {\n    ($query:expr,$value:expr) => {\n        $crate::DebugQuery {\n            query: $query,\n            value: $value,\n        }\n        .build();\n    };\n}\n\n/// Helper to get a raw SQL string from an object that impl `QueryTrait`.\n///\n/// # Example\n///\n/// ```\n/// # #[cfg(feature = \"mock\")]\n/// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, DbBackend};\n/// #\n/// # let conn = MockDatabase::new(DbBackend::Postgres)\n/// #     .into_connection();\n/// #\n/// use sea_orm::{debug_query, entity::*, query::*, tests_cfg::cake};\n///\n/// let c = cake::Entity::insert(cake::ActiveModel {\n///     id: ActiveValue::set(1),\n///     name: ActiveValue::set(\"Apple Pie\".to_owned()),\n/// });\n///\n/// let raw_sql = debug_query!(&c, &conn);\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#\n/// );\n///\n/// let raw_sql = debug_query!(&c, conn);\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#\n/// );\n///\n/// let raw_sql = debug_query!(&c, DbBackend::Sqlite);\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#\n/// );\n/// ```\n#[macro_export]\nmacro_rules! debug_query {\n    ($query:expr,$value:expr) => {\n        $crate::debug_query_stmt!($query, $value).to_string();\n    };\n}\n"
  },
  {
    "path": "sea-orm-sync/src/query/delete.rs",
    "content": "use crate::{\n    ActiveModelTrait, ActiveValue, ColumnTrait, DbBackend, DbErr, EntityTrait, IntoActiveModel,\n    Iterable, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryTrait,\n    query::column_tuple_in_condition,\n    sea_query::{IntoValueTuple, ValueTuple},\n};\nuse core::marker::PhantomData;\nuse sea_query::DeleteStatement;\n\n/// Defines the structure for a delete operation\n#[derive(Clone, Debug)]\npub struct Delete;\n\n/// A request to delete an [`ActiveModel`](ActiveModelTrait).\n///\n/// The primary key must be set.\n/// Otherwise, it's impossible to generate the SQL condition and find the record.\n/// In that case, [`exec`][Self::exec] will return an error and not send any queries to the database.\n///\n/// If you want to use [`QueryTrait`] and access the generated SQL query,\n/// you need to convert into [`ValidatedDeleteOne`] first.\n#[derive(Clone, Debug)]\npub struct DeleteOne<E: EntityTrait>(pub(crate) Result<ValidatedDeleteOne<E>, DbErr>);\n\n/// A validated [`DeleteOne`] request, where the primary key is set\n/// and it's possible to generate the right SQL condition.\n#[derive(Clone, Debug)]\npub struct ValidatedDeleteOne<E: EntityTrait> {\n    pub(crate) query: DeleteStatement,\n    pub(crate) entity: PhantomData<E>,\n}\n\nimpl<E: EntityTrait> TryFrom<DeleteOne<E>> for ValidatedDeleteOne<E> {\n    type Error = DbErr;\n\n    fn try_from(value: DeleteOne<E>) -> Result<Self, Self::Error> {\n        value.0\n    }\n}\n\nimpl<E: EntityTrait> DeleteOne<E> {\n    /// Check whether the primary key is set and we can proceed with the operation.\n    pub fn validate(self) -> Result<ValidatedDeleteOne<E>, DbErr> {\n        self.try_into()\n    }\n}\n\n/// Perform a delete operation on multiple models\n#[derive(Clone, Debug)]\npub struct DeleteMany<E>\nwhere\n    E: EntityTrait,\n{\n    pub(crate) query: DeleteStatement,\n    pub(crate) entity: PhantomData<E>,\n}\n\nimpl Delete {\n    /// Delete one Model or ActiveModel\n    ///\n    /// Model\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     Delete::one(cake::Model {\n    ///         id: 1,\n    ///         name: \"Apple Pie\".to_owned(),\n    ///     })\n    ///     .validate()\n    ///     .unwrap()\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"DELETE FROM \"cake\" WHERE \"cake\".\"id\" = 1\"#,\n    /// );\n    /// ```\n    /// ActiveModel\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     Delete::one(cake::ActiveModel {\n    ///         id: ActiveValue::set(1),\n    ///         name: ActiveValue::set(\"Apple Pie\".to_owned()),\n    ///     })\n    ///     .validate()\n    ///     .unwrap()\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"DELETE FROM \"cake\" WHERE \"cake\".\"id\" = 1\"#,\n    /// );\n    /// ```\n    //\n    // (non-doc comment for maintainers)\n    // Ideally, we would make this method fallible instead of stashing and delaying the error.\n    // But that's a bigger breaking change.\n    pub fn one<E, A, M>(model: M) -> DeleteOne<E>\n    where\n        E: EntityTrait,\n        A: ActiveModelTrait<Entity = E>,\n        M: IntoActiveModel<A>,\n    {\n        let model = model.into_active_model();\n        let mut myself = ValidatedDeleteOne {\n            query: DeleteStatement::new()\n                .from_table(A::Entity::default().table_ref())\n                .to_owned(),\n            entity: PhantomData,\n        };\n        // Build the SQL condition from the primary key columns.\n        for key in <A::Entity as EntityTrait>::PrimaryKey::iter() {\n            let col = key.into_column();\n            let av = model.get(col);\n            match av {\n                ActiveValue::Set(value) | ActiveValue::Unchanged(value) => {\n                    myself = myself.filter(col.eq(value));\n                }\n                ActiveValue::NotSet => {\n                    return DeleteOne(Err(DbErr::PrimaryKeyNotSet { ctx: \"DeleteOne\" }));\n                }\n            }\n        }\n        DeleteOne(Ok(myself))\n    }\n\n    #[doc(hidden)]\n    pub fn _one_only_for_use_by_model_ex<E: EntityTrait>(entity: E) -> ValidatedDeleteOne<E> {\n        ValidatedDeleteOne {\n            query: DeleteStatement::new()\n                .from_table(entity.table_ref())\n                .to_owned(),\n            entity: PhantomData,\n        }\n    }\n\n    /// Delete many ActiveModel\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// assert_eq!(\n    ///     Delete::many(fruit::Entity)\n    ///         .filter(fruit::Column::Name.contains(\"Apple\"))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"DELETE FROM \"fruit\" WHERE \"fruit\".\"name\" LIKE '%Apple%'\"#,\n    /// );\n    /// ```\n    pub fn many<E>(entity: E) -> DeleteMany<E>\n    where\n        E: EntityTrait,\n    {\n        DeleteMany {\n            query: DeleteStatement::new()\n                .from_table(entity.table_ref())\n                .to_owned(),\n            entity: PhantomData,\n        }\n    }\n}\n\nimpl<E> QueryFilter for ValidatedDeleteOne<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = DeleteStatement;\n\n    fn query(&mut self) -> &mut DeleteStatement {\n        &mut self.query\n    }\n}\n\nimpl<E> QueryFilter for DeleteMany<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = DeleteStatement;\n\n    fn query(&mut self) -> &mut DeleteStatement {\n        &mut self.query\n    }\n}\n\nimpl<E> DeleteMany<E>\nwhere\n    E: EntityTrait,\n{\n    /// Filter by vector of IDs by primary key\n    ///\n    /// # Panics\n    ///\n    /// Should not panic.\n    pub fn filter_by_ids<I>(mut self, values: I) -> Self\n    where\n        I: IntoIterator<Item = <E::PrimaryKey as PrimaryKeyTrait>::ValueType>,\n    {\n        self.query.cond_where(\n            column_tuple_in_condition(\n                &E::default().table_ref(),\n                &E::primary_key_identity(),\n                &values\n                    .into_iter()\n                    .map(|v| v.into_value_tuple())\n                    .collect::<Vec<_>>(),\n                DbBackend::Sqlite,\n            )\n            .expect(\"trait bound ensured arity\"),\n        );\n        self\n    }\n\n    #[doc(hidden)]\n    /// # Panics\n    ///\n    /// Panic if `ValueTuple` arity does not match primary key\n    pub fn filter_by_value_tuples(mut self, values: &[ValueTuple], db_backend: DbBackend) -> Self {\n        self.query.cond_where(\n            column_tuple_in_condition(\n                &E::default().table_ref(),\n                &E::primary_key_identity(),\n                values,\n                db_backend,\n            )\n            .expect(\"\"),\n        );\n        self\n    }\n}\n\nimpl<E> QueryTrait for ValidatedDeleteOne<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = DeleteStatement;\n\n    fn query(&mut self) -> &mut DeleteStatement {\n        &mut self.query\n    }\n\n    fn as_query(&self) -> &DeleteStatement {\n        &self.query\n    }\n\n    fn into_query(self) -> DeleteStatement {\n        self.query\n    }\n}\n\nimpl<E> QueryTrait for DeleteMany<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = DeleteStatement;\n\n    fn query(&mut self) -> &mut DeleteStatement {\n        &mut self.query\n    }\n\n    fn as_query(&self) -> &DeleteStatement {\n        &self.query\n    }\n\n    fn into_query(self) -> DeleteStatement {\n        self.query\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::{cake, fruit};\n    use crate::{DbBackend, entity::*, query::*};\n\n    #[test]\n    fn delete_1() {\n        assert_eq!(\n            Delete::one(cake::Model {\n                id: 1,\n                name: \"Apple Pie\".to_owned(),\n            })\n            .validate()\n            .unwrap()\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"DELETE FROM \"cake\" WHERE \"cake\".\"id\" = 1\"#,\n        );\n        assert_eq!(\n            Delete::one(cake::ActiveModel {\n                id: ActiveValue::set(1),\n                name: ActiveValue::set(\"Apple Pie\".to_owned()),\n            })\n            .validate()\n            .unwrap()\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"DELETE FROM \"cake\" WHERE \"cake\".\"id\" = 1\"#,\n        );\n    }\n\n    #[test]\n    fn delete_2() {\n        assert_eq!(\n            Delete::many(fruit::Entity)\n                .filter(fruit::Column::Name.contains(\"Cheese\"))\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"DELETE FROM \"fruit\" WHERE \"fruit\".\"name\" LIKE '%Cheese%'\"#,\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/query/helper.rs",
    "content": "use crate::{\n    ActiveModelTrait, ColumnAsExpr, ColumnTrait, EntityTrait, Identity, IntoIdentity,\n    IntoSimpleExpr, Iterable, ModelTrait, PrimaryKeyToColumn, RelationDef,\n};\nuse sea_query::{\n    Alias, Expr, ExprTrait, IntoCondition, IntoIden, LockBehavior, LockType, NullOrdering, SeaRc,\n    SelectExpr, SelectStatement, SimpleExpr,\n};\npub use sea_query::{Condition, ConditionalStatement, DynIden, JoinType, Order, OrderedStatement};\n\nuse sea_query::IntoColumnRef;\n\n// LINT: when the column does not appear in tables selected from\n// LINT: when there is a group by clause, but some columns don't have aggregate functions\n// LINT: when the join table or column does not exists\n/// Abstract API for performing queries\npub trait QuerySelect: Sized {\n    #[allow(missing_docs)]\n    type QueryStatement;\n\n    /// Add the select SQL statement\n    fn query(&mut self) -> &mut SelectStatement;\n\n    /// Clear the selection list\n    fn select_only(mut self) -> Self {\n        self.query().clear_selects();\n        self\n    }\n\n    /// Add a select column\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .column(cake::Column::Name)\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"name\" FROM \"cake\"\"#\n    /// );\n    /// ```\n    ///\n    /// Enum column will be casted into text (PostgreSQL only)\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::lunch_set};\n    ///\n    /// assert_eq!(\n    ///     lunch_set::Entity::find()\n    ///         .select_only()\n    ///         .column(lunch_set::Column::Tea)\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT CAST(\"lunch_set\".\"tea\" AS \"text\") FROM \"lunch_set\"\"#\n    /// );\n    /// assert_eq!(\n    ///     lunch_set::Entity::find()\n    ///         .select_only()\n    ///         .column(lunch_set::Column::Tea)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     r#\"SELECT `lunch_set`.`tea` FROM `lunch_set`\"#\n    /// );\n    /// ```\n    fn column<C>(mut self, col: C) -> Self\n    where\n        C: ColumnTrait,\n    {\n        self.query().expr(col.select_as(col.into_expr()));\n        self\n    }\n\n    /// Add a select column with alias\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .column_as(cake::Column::Id.count(), \"count\")\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT COUNT(\"cake\".\"id\") AS \"count\" FROM \"cake\"\"#\n    /// );\n    /// ```\n    fn column_as<C, I>(mut self, col: C, alias: I) -> Self\n    where\n        C: ColumnAsExpr,\n        I: IntoIdentity,\n    {\n        self.query().expr(SelectExpr {\n            expr: col.into_column_as_expr(),\n            alias: Some(SeaRc::new(alias.into_identity())),\n            window: None,\n        });\n        self\n    }\n\n    /// Select columns\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .columns([cake::Column::Id, cake::Column::Name])\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#\n    /// );\n    /// ```\n    ///\n    /// Conditionally select all columns expect a specific column\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .columns(cake::Column::iter().filter(|col| match col {\n    ///             cake::Column::Id => false,\n    ///             _ => true,\n    ///         }))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"name\" FROM \"cake\"\"#\n    /// );\n    /// ```\n    ///\n    /// Enum column will be casted into text (PostgreSQL only)\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::lunch_set};\n    ///\n    /// assert_eq!(\n    ///     lunch_set::Entity::find()\n    ///         .select_only()\n    ///         .columns([lunch_set::Column::Name, lunch_set::Column::Tea])\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"lunch_set\".\"name\", CAST(\"lunch_set\".\"tea\" AS \"text\") FROM \"lunch_set\"\"#\n    /// );\n    /// assert_eq!(\n    ///     lunch_set::Entity::find()\n    ///         .select_only()\n    ///         .columns([lunch_set::Column::Name, lunch_set::Column::Tea])\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     r#\"SELECT `lunch_set`.`name`, `lunch_set`.`tea` FROM `lunch_set`\"#\n    /// );\n    /// ```\n    fn columns<C, I>(mut self, cols: I) -> Self\n    where\n        C: ColumnTrait,\n        I: IntoIterator<Item = C>,\n    {\n        for col in cols.into_iter() {\n            self = self.column(col);\n        }\n        self\n    }\n\n    /// Add an offset expression. Passing in None would remove the offset.\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .offset(10)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` OFFSET 10\"\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .offset(Some(10))\n    ///         .offset(Some(20))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` OFFSET 20\"\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .offset(10)\n    ///         .offset(None)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\"\n    /// );\n    /// ```\n    fn offset<T>(mut self, offset: T) -> Self\n    where\n        T: Into<Option<u64>>,\n    {\n        if let Some(offset) = offset.into() {\n            self.query().offset(offset);\n        } else {\n            self.query().reset_offset();\n        }\n        self\n    }\n\n    /// Add a limit expression. Passing in None would remove the limit.\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .limit(10)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` LIMIT 10\"\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .limit(Some(10))\n    ///         .limit(Some(20))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` LIMIT 20\"\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .limit(10)\n    ///         .limit(None)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\"\n    /// );\n    /// ```\n    fn limit<T>(mut self, limit: T) -> Self\n    where\n        T: Into<Option<u64>>,\n    {\n        if let Some(limit) = limit.into() {\n            self.query().limit(limit);\n        } else {\n            self.query().reset_limit();\n        }\n        self\n    }\n\n    /// Add a group by column\n    /// ```\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake, DbBackend};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .column(cake::Column::Name)\n    ///         .group_by(cake::Column::Name)\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"name\" FROM \"cake\" GROUP BY \"cake\".\"name\"\"#\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .column_as(cake::Column::Id.count(), \"count\")\n    ///         .column_as(cake::Column::Id.sum(), \"sum_of_id\")\n    ///         .group_by(cake::Column::Name)\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT COUNT(\"cake\".\"id\") AS \"count\", SUM(\"cake\".\"id\") AS \"sum_of_id\" FROM \"cake\" GROUP BY \"cake\".\"name\"\"#\n    /// );\n    /// ```\n    fn group_by<C>(mut self, col: C) -> Self\n    where\n        C: IntoSimpleExpr,\n    {\n        self.query().add_group_by([col.into_simple_expr()]);\n        self\n    }\n\n    /// Add an AND HAVING expression\n    /// ```\n    /// use sea_orm::{sea_query::{Alias, Expr, ExprTrait}, entity::*, query::*, tests_cfg::cake, DbBackend};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .having(cake::Column::Id.eq(4))\n    ///         .having(cake::Column::Id.eq(5))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` HAVING `cake`.`id` = 4 AND `cake`.`id` = 5\"\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .column_as(cake::Column::Id.count(), \"count\")\n    ///         .column_as(cake::Column::Id.sum(), \"sum_of_id\")\n    ///         .group_by(cake::Column::Name)\n    ///         .having(Expr::col(\"count\").gt(6))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT COUNT(`cake`.`id`) AS `count`, SUM(`cake`.`id`) AS `sum_of_id` FROM `cake` GROUP BY `cake`.`name` HAVING `count` > 6\"\n    /// );\n    /// ```\n    fn having<F>(mut self, filter: F) -> Self\n    where\n        F: IntoCondition,\n    {\n        self.query().cond_having(filter.into_condition());\n        self\n    }\n\n    /// Add a DISTINCT expression\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    /// struct Input {\n    ///     name: Option<String>,\n    /// }\n    /// let input = Input {\n    ///     name: Some(\"cheese\".to_owned()),\n    /// };\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(\n    ///             Condition::all().add_option(input.name.map(|n| cake::Column::Name.contains(&n)))\n    ///         )\n    ///         .distinct()\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT DISTINCT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE '%cheese%'\"\n    /// );\n    /// ```\n    fn distinct(mut self) -> Self {\n        self.query().distinct();\n        self\n    }\n\n    /// Add a DISTINCT ON expression\n    /// NOTE: this function is only supported by `sqlx-postgres`\n    /// ```\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake, DbBackend};\n    /// struct Input {\n    ///     name: Option<String>,\n    /// }\n    /// let input = Input {\n    ///     name: Some(\"cheese\".to_owned()),\n    /// };\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(\n    ///             Condition::all().add_option(input.name.map(|n| cake::Column::Name.contains(&n)))\n    ///         )\n    ///         .distinct_on([(cake::Entity, cake::Column::Name)])\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT DISTINCT ON (\"cake\".\"name\") \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"name\" LIKE '%cheese%'\"#\n    /// );\n    /// ```\n    fn distinct_on<T, I>(mut self, cols: I) -> Self\n    where\n        T: IntoColumnRef,\n        I: IntoIterator<Item = T>,\n    {\n        self.query().distinct_on(cols);\n        self\n    }\n\n    #[doc(hidden)]\n    fn join_join(mut self, join: JoinType, rel: RelationDef, via: Option<RelationDef>) -> Self {\n        if let Some(via) = via {\n            self = self.join(join, via)\n        }\n        self.join(join, rel)\n    }\n\n    #[doc(hidden)]\n    fn join_join_rev(mut self, join: JoinType, rel: RelationDef, via: Option<RelationDef>) -> Self {\n        self = self.join_rev(join, rel);\n        if let Some(via) = via {\n            self = self.join_rev(join, via)\n        }\n        self\n    }\n\n    /// Join via [`RelationDef`].\n    fn join(mut self, join: JoinType, rel: RelationDef) -> Self {\n        self.query().join(join, rel.to_tbl.clone(), rel);\n        self\n    }\n\n    /// Join via [`RelationDef`] but in reverse direction.\n    /// Assume when there exist a relation A to B.\n    /// You can reverse join B from A.\n    fn join_rev(mut self, join: JoinType, rel: RelationDef) -> Self {\n        self.query().join(join, rel.from_tbl.clone(), rel);\n        self\n    }\n\n    /// Join via [`RelationDef`] with table alias.\n    fn join_as<I>(mut self, join: JoinType, mut rel: RelationDef, alias: I) -> Self\n    where\n        I: IntoIden,\n    {\n        let alias = alias.into_iden();\n        rel.to_tbl = rel.to_tbl.alias(alias.clone());\n        self.query().join(join, rel.to_tbl.clone(), rel);\n        self\n    }\n\n    /// Join via [`RelationDef`] with table alias but in reverse direction.\n    /// Assume when there exist a relation A to B.\n    /// You can reverse join B from A.\n    fn join_as_rev<I>(mut self, join: JoinType, mut rel: RelationDef, alias: I) -> Self\n    where\n        I: IntoIden,\n    {\n        let alias = alias.into_iden();\n        rel.from_tbl = rel.from_tbl.alias(alias.clone());\n        self.query().join(join, rel.from_tbl.clone(), rel);\n        self\n    }\n\n    /// Select lock\n    fn lock(mut self, lock_type: LockType) -> Self {\n        self.query().lock(lock_type);\n        self\n    }\n\n    /// Select lock shared\n    fn lock_shared(mut self) -> Self {\n        self.query().lock_shared();\n        self\n    }\n\n    /// Select lock exclusive\n    fn lock_exclusive(mut self) -> Self {\n        self.query().lock_exclusive();\n        self\n    }\n\n    /// Row locking with behavior (if supported).\n    ///\n    /// See [`SelectStatement::lock_with_behavior`](https://docs.rs/sea-query/*/sea_query/query/struct.SelectStatement.html#method.lock_with_behavior).\n    fn lock_with_behavior(mut self, r#type: LockType, behavior: LockBehavior) -> Self {\n        self.query().lock_with_behavior(r#type, behavior);\n        self\n    }\n\n    /// Add an expression to the select expression list.\n    /// ```\n    /// use sea_orm::sea_query::Expr;\n    /// use sea_orm::{DbBackend, QuerySelect, QueryTrait, entity::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .expr(Expr::col((cake::Entity, cake::Column::Id)))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id` FROM `cake`\"\n    /// );\n    /// ```\n    fn expr<T>(mut self, expr: T) -> Self\n    where\n        T: Into<SelectExpr>,\n    {\n        self.query().expr(expr);\n        self\n    }\n\n    /// Add select expressions from vector of [`SelectExpr`].\n    /// ```\n    /// use sea_orm::sea_query::Expr;\n    /// use sea_orm::{DbBackend, QuerySelect, QueryTrait, entity::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .exprs([\n    ///             Expr::col((cake::Entity, cake::Column::Id)),\n    ///             Expr::col((cake::Entity, cake::Column::Name)),\n    ///         ])\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\"\n    /// );\n    /// ```\n    fn exprs<T, I>(mut self, exprs: I) -> Self\n    where\n        T: Into<SelectExpr>,\n        I: IntoIterator<Item = T>,\n    {\n        self.query().exprs(exprs);\n        self\n    }\n\n    /// Select column.\n    /// ```\n    /// use sea_orm::sea_query::{Alias, Expr, Func};\n    /// use sea_orm::{DbBackend, QuerySelect, QueryTrait, entity::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .expr_as(\n    ///             Func::upper(Expr::col((cake::Entity, cake::Column::Name))),\n    ///             \"name_upper\"\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name`, UPPER(`cake`.`name`) AS `name_upper` FROM `cake`\"\n    /// );\n    /// ```\n    fn expr_as<T, A>(mut self, expr: T, alias: A) -> Self\n    where\n        T: Into<SimpleExpr>,\n        A: IntoIdentity,\n    {\n        self.query().expr_as(expr, alias.into_identity());\n        self\n    }\n\n    /// Shorthand of `expr_as(Expr::col((T, C)), A)`.\n    ///\n    /// ```\n    /// use sea_orm::sea_query::{Alias, Expr, Func};\n    /// use sea_orm::{DbBackend, QuerySelect, QueryTrait, entity::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .tbl_col_as((cake::Entity, cake::Column::Name), \"cake_name\")\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`name` AS `cake_name` FROM `cake`\"\n    /// );\n    /// ```\n    fn tbl_col_as<T, C, A>(mut self, (tbl, col): (T, C), alias: A) -> Self\n    where\n        T: IntoIden + 'static,\n        C: IntoIden + 'static,\n        A: IntoIdentity,\n    {\n        self.query()\n            .expr_as(Expr::col((tbl, col)), alias.into_identity());\n        self\n    }\n}\n\n// LINT: when the column does not appear in tables selected from\n/// Performs ORDER BY operations\npub trait QueryOrder: Sized {\n    #[allow(missing_docs)]\n    type QueryStatement: OrderedStatement;\n\n    /// Add the query to perform an ORDER BY operation\n    fn query(&mut self) -> &mut SelectStatement;\n\n    /// Add an order_by expression\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .order_by(cake::Column::Id, Order::Asc)\n    ///         .order_by(cake::Column::Name, Order::Desc)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` ORDER BY `cake`.`id` ASC, `cake`.`name` DESC\"\n    /// );\n    /// ```\n    fn order_by<C>(mut self, col: C, ord: Order) -> Self\n    where\n        C: IntoSimpleExpr,\n    {\n        self.query().order_by_expr(col.into_simple_expr(), ord);\n        self\n    }\n\n    /// Add an order_by expression (ascending)\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .order_by_asc(cake::Column::Id)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` ORDER BY `cake`.`id` ASC\"\n    /// );\n    /// ```\n    fn order_by_asc<C>(mut self, col: C) -> Self\n    where\n        C: IntoSimpleExpr,\n    {\n        self.query()\n            .order_by_expr(col.into_simple_expr(), Order::Asc);\n        self\n    }\n\n    /// Add an order_by expression (descending)\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .order_by_desc(cake::Column::Id)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` ORDER BY `cake`.`id` DESC\"\n    /// );\n    /// ```\n    fn order_by_desc<C>(mut self, col: C) -> Self\n    where\n        C: IntoSimpleExpr,\n    {\n        self.query()\n            .order_by_expr(col.into_simple_expr(), Order::Desc);\n        self\n    }\n\n    /// Add an order_by expression with nulls ordering option\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    /// use sea_query::NullOrdering;\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .order_by_with_nulls(cake::Column::Id, Order::Asc, NullOrdering::First)\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" ORDER BY \"cake\".\"id\" ASC NULLS FIRST\"#\n    /// );\n    /// ```\n    fn order_by_with_nulls<C>(mut self, col: C, ord: Order, nulls: NullOrdering) -> Self\n    where\n        C: IntoSimpleExpr,\n    {\n        self.query()\n            .order_by_expr_with_nulls(col.into_simple_expr(), ord, nulls);\n        self\n    }\n}\n\n// LINT: when the column does not appear in tables selected from\n/// Perform a FILTER opertation on a statement\npub trait QueryFilter: Sized {\n    #[allow(missing_docs)]\n    type QueryStatement: ConditionalStatement;\n\n    /// Add the query to perform a FILTER on\n    fn query(&mut self) -> &mut Self::QueryStatement;\n\n    /// Add an AND WHERE expression\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.eq(4))\n    ///         .filter(cake::Column::Id.eq(5))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = 4 AND `cake`.`id` = 5\"\n    /// );\n    /// ```\n    ///\n    /// Add a condition tree.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(\n    ///             Condition::any()\n    ///                 .add(cake::Column::Id.eq(4))\n    ///                 .add(cake::Column::Id.eq(5))\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = 4 OR `cake`.`id` = 5\"\n    /// );\n    /// ```\n    ///\n    /// Like above, but using the `IN` operator.\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.is_in([4, 5]))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` IN (4, 5)\"\n    /// );\n    /// ```\n    ///\n    /// Like above, but using the `ANY` operator. Postgres only.\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.eq_any([4, 5]))\n    ///         .build(DbBackend::Postgres),\n    ///     Statement::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = ANY($1)\"#,\n    ///         [vec![4, 5].into()]\n    ///     )\n    /// );\n    /// ```\n    ///\n    /// Add a runtime-built condition tree.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    /// struct Input {\n    ///     name: Option<String>,\n    /// }\n    /// let input = Input {\n    ///     name: Some(\"cheese\".to_owned()),\n    /// };\n    ///\n    /// let mut conditions = Condition::all();\n    /// if let Some(name) = input.name {\n    ///     conditions = conditions.add(cake::Column::Name.contains(&name));\n    /// }\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(conditions)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE '%cheese%'\"\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(Condition::all())\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE TRUE\"\n    /// );\n    /// ```\n    ///\n    /// Add a runtime-built condition tree, functional-way.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    /// struct Input {\n    ///     name: Option<String>,\n    /// }\n    /// let input = Input {\n    ///     name: Some(\"cheese\".to_owned()),\n    /// };\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(\n    ///             Condition::all().add_option(input.name.map(|n| cake::Column::Name.contains(&n)))\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE '%cheese%'\"\n    /// );\n    /// ```\n    ///\n    /// A slightly more complex example.\n    /// ```\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake, sea_query::{Expr, ExprTrait}, DbBackend};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(\n    ///             Condition::all()\n    ///                 .add(\n    ///                     Condition::all()\n    ///                         .not()\n    ///                         .add(Expr::val(1).eq(1))\n    ///                         .add(Expr::val(2).eq(2))\n    ///                 )\n    ///                 .add(\n    ///                     Condition::any()\n    ///                         .add(Expr::val(3).eq(3))\n    ///                         .add(Expr::val(4).eq(4))\n    ///                 )\n    ///         )\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE (NOT (1 = 1 AND 2 = 2)) AND (3 = 3 OR 4 = 4)\"#\n    /// );\n    /// ```\n    /// Use a sea_query expression\n    /// ```\n    /// use sea_orm::{entity::*, query::*, sea_query::{Expr, ExprTrait}, tests_cfg::fruit, DbBackend};\n    ///\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .filter(Expr::col(fruit::Column::CakeId).is_null())\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `cake_id` IS NULL\"\n    /// );\n    /// ```\n    fn filter<F>(mut self, filter: F) -> Self\n    where\n        F: IntoCondition,\n    {\n        self.query().cond_where(filter.into_condition());\n        self\n    }\n\n    /// Like [`Self::filter`], but without consuming self\n    fn filter_mut<F>(&mut self, filter: F)\n    where\n        F: IntoCondition,\n    {\n        self.query().cond_where(filter.into_condition());\n    }\n\n    /// Apply a where condition using the model's primary key\n    /// ```\n    /// # use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::{cake, fruit}};\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .left_join(cake::Entity)\n    ///         .belongs_to(&cake::Model {\n    ///             id: 12,\n    ///             name: \"\".into(),\n    ///         })\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     [\n    ///         \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\",\n    ///         \"LEFT JOIN `cake` ON `fruit`.`cake_id` = `cake`.`id`\",\n    ///         \"WHERE `cake`.`id` = 12\",\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    /// ```\n    fn belongs_to<M>(mut self, model: &M) -> Self\n    where\n        M: ModelTrait,\n    {\n        for key in <M::Entity as EntityTrait>::PrimaryKey::iter() {\n            let col = key.into_column();\n            self = self.filter(col.eq(model.get(col)));\n        }\n        self\n    }\n\n    /// Like `belongs_to`, but for an ActiveModel. Panic if primary key is not set.\n    #[doc(hidden)]\n    fn belongs_to_active_model<AM>(mut self, model: &AM) -> Self\n    where\n        AM: ActiveModelTrait,\n    {\n        for key in <AM::Entity as EntityTrait>::PrimaryKey::iter() {\n            let col = key.into_column();\n            self = self.filter(col.eq(model.get(col).unwrap()));\n        }\n        self\n    }\n\n    /// Like `belongs_to`, but via a table alias\n    /// ```\n    /// # use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::{cake, fruit}};\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .join_as(JoinType::LeftJoin, fruit::Relation::Cake.def(), \"puff\")\n    ///         .belongs_to_tbl_alias(\n    ///             &cake::Model {\n    ///                 id: 12,\n    ///                 name: \"\".into(),\n    ///             },\n    ///             \"puff\"\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     [\n    ///         \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\",\n    ///         \"LEFT JOIN `cake` AS `puff` ON `fruit`.`cake_id` = `puff`.`id`\",\n    ///         \"WHERE `puff`.`id` = 12\",\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    /// ```\n    fn belongs_to_tbl_alias<M>(mut self, model: &M, tbl_alias: &str) -> Self\n    where\n        M: ModelTrait,\n    {\n        for key in <M::Entity as EntityTrait>::PrimaryKey::iter() {\n            let col = key.into_column();\n            let expr = Expr::col((Alias::new(tbl_alias), col)).eq(model.get(col));\n            self = self.filter(expr);\n        }\n        self\n    }\n}\n\npub(crate) fn join_tbl_on_condition(\n    from_tbl: DynIden,\n    to_tbl: DynIden,\n    owner_keys: Identity,\n    foreign_keys: Identity,\n) -> Condition {\n    let mut cond = Condition::all();\n    for (owner_key, foreign_key) in owner_keys.into_iter().zip(foreign_keys.into_iter()) {\n        cond = cond\n            .add(Expr::col((from_tbl.clone(), owner_key)).equals((to_tbl.clone(), foreign_key)));\n    }\n    cond\n}\n"
  },
  {
    "path": "sea-orm-sync/src/query/insert.rs",
    "content": "use crate::{\n    ActiveModelTrait, ActiveValue, ColumnTrait, EntityName, EntityTrait, IntoActiveModel, Iterable,\n    PrimaryKeyTrait, QueryTrait,\n};\nuse core::marker::PhantomData;\nuse sea_query::{Expr, InsertStatement, Keyword, OnConflict, SimpleExpr, Value, ValueTuple};\n\n/// Performs INSERT operations on a ActiveModel\n#[derive(Debug)]\npub struct Insert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    pub(crate) query: InsertStatement,\n    pub(crate) primary_key: Option<ValueTuple>,\n    pub(crate) model: PhantomData<A>,\n}\n\n/// Performs INSERT operations on many ActiveModels\n#[derive(Debug)]\npub struct InsertMany<A>\nwhere\n    A: ActiveModelTrait,\n{\n    pub(crate) query: InsertStatement,\n    pub(crate) primary_key: Option<ValueTuple>,\n    pub(crate) empty: bool,\n    pub(crate) model: PhantomData<A>,\n}\n\n/// Wrapper of [`Insert`] / [`InsertMany`], treats \"no row inserted/id returned\" as a normal outcome.\n///\n/// Its `exec*` methods return [`crate::TryInsertResult`].\n/// Mapping empty input to [`crate::TryInsertResult::Empty`] (no SQL executed) and\n/// `DbErr::RecordNotInserted` to [`crate::TryInsertResult::Conflicted`].\n///\n/// Useful for idempotent inserts such as `ON CONFLICT ... DO NOTHING` (Postgres / SQLite) or the\n/// MySQL polyfill (`ON DUPLICATE KEY UPDATE pk = pk`).\n#[derive(Debug)]\npub struct TryInsert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    pub(crate) insert_struct: Insert<A>,\n    pub(crate) empty: bool,\n}\n\nimpl<A> Insert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Insert one Model or ActiveModel\n    ///\n    /// Model\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     Insert::one(cake::Model {\n    ///         id: 1,\n    ///         name: \"Apple Pie\".to_owned(),\n    ///     })\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#,\n    /// );\n    /// ```\n    /// ActiveModel\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     Insert::one(cake::ActiveModel {\n    ///         id: NotSet,\n    ///         name: Set(\"Apple Pie\".to_owned()),\n    ///     })\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"name\") VALUES ('Apple Pie')\"#,\n    /// );\n    /// ```\n    pub fn one<M>(m: M) -> Self\n    where\n        M: IntoActiveModel<A>,\n    {\n        let mut query = InsertStatement::new();\n        query\n            .into_table(A::Entity::default().table_ref())\n            .or_default_values();\n\n        let mut am: A = m.into_active_model();\n        let primary_key =\n            if !<<A::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::auto_increment() {\n                am.get_primary_key_value()\n            } else {\n                None\n            };\n        let mut columns = Vec::new();\n        let mut values = Vec::new();\n\n        for col in <A::Entity as EntityTrait>::Column::iter() {\n            let av = am.take(col);\n\n            match av {\n                ActiveValue::Set(value) | ActiveValue::Unchanged(value) => {\n                    columns.push(col);\n                    values.push(col.save_as(Expr::val(value)));\n                }\n                ActiveValue::NotSet => {}\n            }\n        }\n\n        query.columns(columns);\n        query.values_panic(values);\n\n        Self {\n            query,\n            primary_key,\n            model: PhantomData,\n        }\n    }\n\n    /// Insert many Model or ActiveModel.\n    /// Alias to [`InsertMany::many`].\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     Insert::many([\n    ///         cake::Model {\n    ///             id: 1,\n    ///             name: \"Apple Pie\".to_owned(),\n    ///         },\n    ///         cake::Model {\n    ///             id: 2,\n    ///             name: \"Orange Scone\".to_owned(),\n    ///         }\n    ///     ])\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie'), (2, 'Orange Scone')\"#,\n    /// );\n    /// ```\n    pub fn many<M, I>(models: I) -> InsertMany<A>\n    where\n        M: IntoActiveModel<A>,\n        I: IntoIterator<Item = M>,\n    {\n        InsertMany::many(models)\n    }\n\n    /// Set ON CONFLICT logic\n    ///\n    /// on conflict do nothing\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, sea_query::OnConflict, tests_cfg::cake};\n    ///\n    /// let orange = cake::ActiveModel {\n    ///     id: ActiveValue::set(2),\n    ///     name: ActiveValue::set(\"Orange\".to_owned()),\n    /// };\n    /// assert_eq!(\n    ///     cake::Entity::insert(orange)\n    ///         .on_conflict(\n    ///             OnConflict::column(cake::Column::Name)\n    ///                 .do_nothing()\n    ///                 .to_owned()\n    ///         )\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO NOTHING\"#,\n    /// );\n    /// ```\n    ///\n    /// on conflict do update (upsert)\n    /// ```\n    /// use sea_orm::{entity::*, query::*, sea_query::OnConflict, tests_cfg::cake, DbBackend};\n    ///\n    /// let orange = cake::ActiveModel {\n    ///     id: ActiveValue::set(2),\n    ///     name: ActiveValue::set(\"Orange\".to_owned()),\n    /// };\n    /// let query = cake::Entity::insert(orange)\n    ///     .on_conflict(\n    ///         OnConflict::column(cake::Column::Name)\n    ///             .update_column(cake::Column::Name)\n    ///             .to_owned()\n    ///     );\n    /// assert_eq!(\n    ///     query\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"INSERT INTO `cake` (`id`, `name`) VALUES (2, 'Orange') ON DUPLICATE KEY UPDATE `name` = VALUES(`name`)\"\n    /// );\n    /// assert_eq!(\n    ///     query\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO UPDATE SET \"name\" = \"excluded\".\"name\"\"#,\n    /// );\n    /// assert_eq!(\n    ///     query\n    ///         .build(DbBackend::Sqlite)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO UPDATE SET \"name\" = \"excluded\".\"name\"\"#,\n    /// );\n    /// ```\n    pub fn on_conflict(mut self, on_conflict: OnConflict) -> Self {\n        self.query.on_conflict(on_conflict);\n        self\n    }\n\n    /// Set ON CONFLICT do nothing, but with MySQL specific polyfill.\n    pub fn on_conflict_do_nothing_on<I>(mut self, columns: I) -> TryInsert<A>\n    where\n        I: IntoIterator<Item = <A::Entity as EntityTrait>::Column>,\n    {\n        let primary_keys = <A::Entity as EntityTrait>::PrimaryKey::iter();\n        let mut on_conflict = OnConflict::columns(columns);\n        on_conflict.do_nothing_on(primary_keys);\n        self.query.on_conflict(on_conflict);\n        TryInsert::from_one(self)\n    }\n\n    /// Allow insert statement to return without error if nothing's been inserted.\n    #[deprecated(\n        since = \"2.0.0\",\n        note = \"Please use [`TryInsert::one`] or `on_conflict_do_nothing*` methods that return [`TryInsert`], or [`Insert::try_insert`].\"\n    )]\n    pub fn do_nothing(self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        TryInsert::from_one(self)\n    }\n\n    /// Convert self into a `TryInsert`. It is just a wrapper for converting `DbErr::RecordNotInserted` -> `TryInsertResult::Conflicted`.\n    pub fn try_insert(self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        TryInsert::from_one(self)\n    }\n\n    /// Alias to [`Insert::do_nothing`].\n    #[deprecated(\n        since = \"2.0.0\",\n        note = \"Please use [`TryInsert::one`] or `on_conflict_do_nothing*` methods that return [`TryInsert`]\"\n    )]\n    pub fn on_empty_do_nothing(self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        TryInsert::from_one(self)\n    }\n\n    /// Set ON CONFLICT on primary key do nothing, but with MySQL specific polyfill.\n    ///\n    /// ```\n    /// use sea_orm::{entity::*, query::*, sea_query::OnConflict, tests_cfg::cake, DbBackend};\n    ///\n    /// let orange = cake::ActiveModel {\n    ///     id: ActiveValue::set(2),\n    ///     name: ActiveValue::set(\"Orange\".to_owned()),\n    /// };\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::insert(orange.clone())\n    ///         .on_conflict_do_nothing()\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO `cake` (`id`, `name`) VALUES (2, 'Orange') ON DUPLICATE KEY UPDATE `id` = `id`\"#,\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::insert(orange.clone())\n    ///         .on_conflict_do_nothing()\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"id\") DO NOTHING\"#,\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::insert(orange)\n    ///         .on_conflict_do_nothing()\n    ///         .build(DbBackend::Sqlite)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"id\") DO NOTHING\"#,\n    /// );\n    /// ```\n    pub fn on_conflict_do_nothing(mut self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        self.query.on_conflict(on_conflict_primary_key::<A>());\n\n        TryInsert::from_one(self)\n    }\n}\n\nimpl<A> InsertMany<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Insert many Model or ActiveModel\n    pub fn many<M, I>(models: I) -> Self\n    where\n        M: IntoActiveModel<A>,\n        I: IntoIterator<Item = M>,\n    {\n        let mut query = InsertStatement::new();\n        query.into_table(A::Entity::default().table_ref());\n\n        let mut columns: Vec<_> = <A::Entity as EntityTrait>::Column::iter()\n            .map(|_| None)\n            .collect();\n        let mut null_value: Vec<Option<Value>> = std::iter::repeat_n(None, columns.len()).collect();\n        let mut all_values: Vec<Vec<SimpleExpr>> = Vec::new();\n        let mut primary_key = None;\n\n        for model in models.into_iter() {\n            let mut am: A = model.into_active_model();\n            primary_key =\n                if !<<A::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::auto_increment() {\n                    am.get_primary_key_value()\n                } else {\n                    None\n                };\n            let mut values = Vec::with_capacity(columns.len());\n            for (idx, col) in <A::Entity as EntityTrait>::Column::iter().enumerate() {\n                let av = am.take(col);\n                match av {\n                    ActiveValue::Set(value) | ActiveValue::Unchanged(value) => {\n                        columns[idx] = Some(col); // mark the column as used\n                        null_value[idx] = Some(value.as_null()); // store the null value with the correct type\n                        values.push(col.save_as(Expr::val(value))); // same as add() above\n                    }\n                    ActiveValue::NotSet => {\n                        values.push(SimpleExpr::Keyword(Keyword::Null)); // indicate a missing value\n                    }\n                }\n            }\n            all_values.push(values);\n        }\n\n        let empty = all_values.is_empty();\n\n        if !all_values.is_empty() {\n            // filter only used column\n            query.columns(columns.iter().cloned().flatten());\n        }\n\n        for values in all_values {\n            // since we've aligned the column set, this never panics\n            query.values_panic(values.into_iter().enumerate().filter_map(|(i, v)| {\n                if columns[i].is_some() {\n                    // only if the column is used\n                    if !matches!(v, SimpleExpr::Keyword(Keyword::Null)) {\n                        // use the value expression\n                        Some(v)\n                    } else {\n                        // use null as standin, which must be Some\n                        null_value[i].clone().map(SimpleExpr::Value)\n                    }\n                } else {\n                    None\n                }\n            }));\n        }\n\n        Self {\n            query,\n            primary_key,\n            empty,\n            model: PhantomData,\n        }\n    }\n\n    /// Set ON CONFLICT logic\n    pub fn on_conflict(mut self, on_conflict: OnConflict) -> Self {\n        self.query.on_conflict(on_conflict);\n        self\n    }\n\n    /// Set ON CONFLICT do nothing, but with MySQL specific polyfill.\n    /// ```\n    /// use sea_orm::{entity::*, query::*, sea_query::OnConflict, tests_cfg::cake, DbBackend};\n    /// let orange = cake::ActiveModel {\n    ///     id: ActiveValue::set(2),\n    ///     name: ActiveValue::set(\"Orange\".to_owned()),\n    /// };\n    /// assert_eq!(\n    ///     cake::Entity::insert(orange.clone())\n    ///         .on_conflict_do_nothing_on([cake::Column::Name])\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO NOTHING\"#,\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::insert(orange)\n    ///         .on_conflict_do_nothing_on([cake::Column::Name])\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO `cake` (`id`, `name`) VALUES (2, 'Orange') ON DUPLICATE KEY UPDATE `id` = `id`\"#,\n    /// );\n    /// ```\n    pub fn on_conflict_do_nothing_on<I>(mut self, columns: I) -> TryInsert<A>\n    where\n        I: IntoIterator<Item = <A::Entity as EntityTrait>::Column>,\n    {\n        let primary_keys = <A::Entity as EntityTrait>::PrimaryKey::iter();\n        let mut on_conflict = OnConflict::columns(columns);\n        on_conflict.do_nothing_on(primary_keys);\n        self.query.on_conflict(on_conflict);\n        TryInsert::from_many(self)\n    }\n\n    /// Allow insert statement to return without error if nothing's been inserted.\n    #[deprecated(\n        since = \"2.0.0\",\n        note = \"Please use [`TryInsert::many`] or `on_conflict_do_nothing*` methods that return [`TryInsert`], or [`InsertMany::try_insert`]\"\n    )]\n    pub fn do_nothing(self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        TryInsert::from_many(self)\n    }\n\n    /// Convert self into a `TryInsert`. It is just a wrapper for converting `DbErr::RecordNotInserted` -> `TryInsertResult::Conflicted`.\n    pub fn try_insert(self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        TryInsert::from_many(self)\n    }\n\n    /// Alias to [`InsertMany::do_nothing`].\n    #[deprecated(\n        since = \"2.0.0\",\n        note = \"Empty input is already handled by [`InsertMany::exec`] (no SQL executed). For conflict handling, use [`InsertMany::on_conflict_do_nothing`] or [`InsertMany::on_conflict_do_nothing_on`].\"\n    )]\n    pub fn on_empty_do_nothing(self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        TryInsert::from_many(self)\n    }\n\n    /// Set ON CONFLICT on primary key do nothing, but with MySQL specific polyfill.\n    /// See also [`Insert::on_conflict_do_nothing`].\n    pub fn on_conflict_do_nothing(mut self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        self.query.on_conflict(on_conflict_primary_key::<A>());\n\n        TryInsert::from_many(self)\n    }\n\n    /// panic when self is empty\n    pub(crate) fn into_one(self) -> Insert<A> {\n        assert!(!self.empty);\n\n        let Self {\n            query,\n            primary_key,\n            empty: _,\n            model,\n        } = self;\n\n        Insert {\n            query,\n            primary_key,\n            model,\n        }\n    }\n}\n\nimpl<A> QueryTrait for Insert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    type QueryStatement = InsertStatement;\n\n    fn query(&mut self) -> &mut InsertStatement {\n        &mut self.query\n    }\n\n    fn as_query(&self) -> &InsertStatement {\n        &self.query\n    }\n\n    fn into_query(self) -> InsertStatement {\n        self.query\n    }\n}\n\nimpl<A> QueryTrait for InsertMany<A>\nwhere\n    A: ActiveModelTrait,\n{\n    type QueryStatement = InsertStatement;\n\n    fn query(&mut self) -> &mut InsertStatement {\n        &mut self.query\n    }\n\n    fn as_query(&self) -> &InsertStatement {\n        &self.query\n    }\n\n    fn into_query(self) -> InsertStatement {\n        self.query\n    }\n}\n\nimpl<A> TryInsert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    fn from_one(insert: Insert<A>) -> Self {\n        Self {\n            insert_struct: insert,\n            empty: false,\n        }\n    }\n\n    fn from_many(insert: InsertMany<A>) -> Self {\n        let InsertMany {\n            query,\n            primary_key,\n            empty,\n            model,\n        } = insert;\n\n        Self {\n            insert_struct: Insert {\n                query,\n                primary_key,\n                model,\n            },\n            empty,\n        }\n    }\n\n    /// Try insert one item\n    pub fn one<M>(m: M) -> Self\n    where\n        M: IntoActiveModel<A>,\n    {\n        Self::from_one(Insert::one(m))\n    }\n\n    /// Try insert many items\n    pub fn many<M, I>(models: I) -> Self\n    where\n        M: IntoActiveModel<A>,\n        I: IntoIterator<Item = M>,\n    {\n        Self::from_many(Insert::many(models))\n    }\n\n    /// Set ON CONFLICT logic\n    pub fn on_conflict(mut self, on_conflict: OnConflict) -> Insert<A> {\n        self.insert_struct.query.on_conflict(on_conflict);\n        self.insert_struct\n    }\n\n    /// Set ON CONFLICT on primary key do nothing, but with MySQL specific polyfill.\n    pub fn on_conflict_do_nothing(mut self) -> Self {\n        self.insert_struct\n            .query\n            .on_conflict(on_conflict_primary_key::<A>());\n\n        self\n    }\n\n    /// Set ON CONFLICT do nothing, but with MySQL specific polyfill.\n    pub fn on_conflict_do_nothing_on<I>(mut self, columns: I) -> Self\n    where\n        I: IntoIterator<Item = <A::Entity as EntityTrait>::Column>,\n    {\n        let primary_keys = <A::Entity as EntityTrait>::PrimaryKey::iter();\n        let mut on_conflict = OnConflict::columns(columns);\n        on_conflict.do_nothing_on(primary_keys);\n        self.insert_struct.query.on_conflict(on_conflict);\n        self\n    }\n}\n\nimpl<A> QueryTrait for TryInsert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    type QueryStatement = InsertStatement;\n\n    fn query(&mut self) -> &mut InsertStatement {\n        &mut self.insert_struct.query\n    }\n\n    fn as_query(&self) -> &InsertStatement {\n        &self.insert_struct.query\n    }\n\n    fn into_query(self) -> InsertStatement {\n        self.insert_struct.query\n    }\n}\n\nfn on_conflict_primary_key<A: ActiveModelTrait>() -> OnConflict {\n    let primary_keys = <A::Entity as EntityTrait>::PrimaryKey::iter();\n    let mut on_conflict = OnConflict::columns(primary_keys.clone());\n    on_conflict.do_nothing_on(primary_keys);\n    on_conflict\n}\n\n#[cfg(test)]\nmod tests {\n    use sea_query::OnConflict;\n\n    use crate::tests_cfg::{cake, cake_filling};\n    use crate::{\n        ActiveValue, DbBackend, DbErr, EntityTrait, Insert, IntoActiveModel, NotSet, QueryTrait,\n        Set,\n    };\n\n    #[test]\n    fn insert_1() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::one(cake::ActiveModel {\n                id: ActiveValue::not_set(),\n                name: ActiveValue::set(\"Apple Pie\".to_owned()),\n            })\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"INSERT INTO \"cake\" (\"name\") VALUES ('Apple Pie')\"#,\n        );\n    }\n\n    #[test]\n    fn insert_2() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::one(cake::ActiveModel {\n                id: ActiveValue::set(1),\n                name: ActiveValue::set(\"Apple Pie\".to_owned()),\n            })\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#,\n        );\n    }\n\n    #[test]\n    fn insert_3() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::one(cake::Model {\n                id: 1,\n                name: \"Apple Pie\".to_owned(),\n            })\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#,\n        );\n    }\n\n    #[test]\n    fn insert_many_1() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::many([\n                cake::Model {\n                    id: 1,\n                    name: \"Apple Pie\".to_owned(),\n                },\n                cake::Model {\n                    id: 2,\n                    name: \"Orange Scone\".to_owned(),\n                }\n            ])\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie'), (2, 'Orange Scone')\"#,\n        );\n    }\n\n    #[test]\n    fn insert_many_2() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::many([\n                cake::ActiveModel {\n                    id: NotSet,\n                    name: Set(\"Apple Pie\".to_owned()),\n                },\n                cake::ActiveModel {\n                    id: NotSet,\n                    name: Set(\"Orange Scone\".to_owned()),\n                }\n            ])\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"INSERT INTO \"cake\" (\"name\") VALUES ('Apple Pie'), ('Orange Scone')\"#,\n        );\n    }\n\n    #[test]\n    fn insert_many_3() {\n        let apple = cake_filling::ActiveModel {\n            cake_id: ActiveValue::set(2),\n            filling_id: ActiveValue::NotSet,\n        };\n        let orange = cake_filling::ActiveModel {\n            cake_id: ActiveValue::NotSet,\n            filling_id: ActiveValue::set(3),\n        };\n        assert_eq!(\n            Insert::<cake_filling::ActiveModel>::many([apple, orange])\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"INSERT INTO \"cake_filling\" (\"cake_id\", \"filling_id\") VALUES (2, NULL), (NULL, 3)\"#,\n        );\n    }\n\n    #[test]\n    fn insert_6() {\n        let orange = cake::ActiveModel {\n            id: ActiveValue::set(2),\n            name: ActiveValue::set(\"Orange\".to_owned()),\n        };\n\n        assert_eq!(\n            cake::Entity::insert(orange)\n                .on_conflict(\n                    OnConflict::column(cake::Column::Name)\n                        .do_nothing()\n                        .to_owned()\n                )\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO NOTHING\"#,\n        );\n    }\n\n    #[test]\n    fn insert_7() {\n        let orange = cake::ActiveModel {\n            id: ActiveValue::set(2),\n            name: ActiveValue::set(\"Orange\".to_owned()),\n        };\n\n        assert_eq!(\n            cake::Entity::insert(orange)\n                .on_conflict(\n                    OnConflict::column(cake::Column::Name)\n                        .update_column(cake::Column::Name)\n                        .to_owned()\n                )\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO UPDATE SET \"name\" = \"excluded\".\"name\"\"#,\n        );\n    }\n\n    #[test]\n    fn test_on_conflict_do_nothing_on() {\n        let orange = cake::ActiveModel {\n            id: ActiveValue::set(2),\n            name: ActiveValue::set(\"Orange\".to_owned()),\n        };\n\n        assert_eq!(\n            cake::Entity::insert(orange.clone())\n                .on_conflict_do_nothing_on([cake::Column::Name])\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO NOTHING\"#,\n        );\n        assert_eq!(\n            cake::Entity::insert(orange)\n                .on_conflict_do_nothing_on([cake::Column::Name])\n                .build(DbBackend::MySql)\n                .to_string(),\n            r#\"INSERT INTO `cake` (`id`, `name`) VALUES (2, 'Orange') ON DUPLICATE KEY UPDATE `id` = `id`\"#,\n        );\n    }\n\n    #[test]\n    fn insert_8() -> Result<(), DbErr> {\n        use crate::{DbBackend, MockDatabase, Statement, Transaction};\n\n        mod post {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"posts\")]\n            pub struct Model {\n                #[sea_orm(primary_key, select_as = \"INTEGER\", save_as = \"TEXT\")]\n                pub id: i32,\n                pub title: String,\n                pub text: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        let model = post::Model {\n            id: 1,\n            title: \"News wrap up 2022\".into(),\n            text: \"brbrbrrrbrbrbrr...\".into(),\n        };\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[model.clone()]])\n            .into_connection();\n\n        post::Entity::insert(model.into_active_model()).exec(&db)?;\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                r#\"INSERT INTO \"posts\" (\"id\", \"title\", \"text\") VALUES (CAST($1 AS TEXT), $2, $3) RETURNING CAST(\"id\" AS INTEGER)\"#,\n                [\n                    1.into(),\n                    \"News wrap up 2022\".into(),\n                    \"brbrbrrrbrbrbrr...\".into(),\n                ]\n            )])]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn insert_9() -> Result<(), DbErr> {\n        use crate::{DbBackend, MockDatabase, MockExecResult, Statement, Transaction};\n\n        mod post {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"posts\")]\n            pub struct Model {\n                #[sea_orm(\n                    primary_key,\n                    auto_increment = false,\n                    select_as = \"INTEGER\",\n                    save_as = \"TEXT\"\n                )]\n                pub id_primary: i32,\n                #[sea_orm(\n                    primary_key,\n                    auto_increment = false,\n                    select_as = \"INTEGER\",\n                    save_as = \"TEXT\"\n                )]\n                pub id_secondary: i32,\n                pub title: String,\n                pub text: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        let model = post::Model {\n            id_primary: 1,\n            id_secondary: 1001,\n            title: \"News wrap up 2022\".into(),\n            text: \"brbrbrrrbrbrbrr...\".into(),\n        };\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[model.clone()]])\n            .into_connection();\n\n        post::Entity::insert(model.into_active_model()).exec(&db)?;\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                r#\"INSERT INTO \"posts\" (\"id_primary\", \"id_secondary\", \"title\", \"text\") VALUES (CAST($1 AS TEXT), CAST($2 AS TEXT), $3, $4) RETURNING CAST(\"id_primary\" AS INTEGER), CAST(\"id_secondary\" AS INTEGER)\"#,\n                [\n                    1.into(),\n                    1001.into(),\n                    \"News wrap up 2022\".into(),\n                    \"brbrbrrrbrbrbrr...\".into(),\n                ]\n            )])]\n        );\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/query/join.rs",
    "content": "use crate::{\n    ColumnTrait, EntityTrait, IdenStatic, Iterable, Linked, QueryFilter, QuerySelect, QueryTrait,\n    Related, Select, SelectA, SelectB, SelectThree, SelectTwo, SelectTwoMany, TopologyChain,\n    TopologyStar, find_linked_recursive, join_tbl_on_condition,\n};\npub use sea_query::JoinType;\nuse sea_query::{Condition, Expr, IntoCondition, IntoIden, SelectExpr};\n\nimpl<E> Select<E>\nwhere\n    E: EntityTrait,\n{\n    /// Left Join with a Related Entity.\n    pub fn left_join<R>(self, _: R) -> Self\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.join_join(JoinType::LeftJoin, E::to(), E::via())\n    }\n\n    /// Right Join with a Related Entity.\n    pub fn right_join<R>(self, _: R) -> Self\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.join_join(JoinType::RightJoin, E::to(), E::via())\n    }\n\n    /// Inner Join with a Related Entity.\n    pub fn inner_join<R>(self, _: R) -> Self\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.join_join(JoinType::InnerJoin, E::to(), E::via())\n    }\n\n    /// Join with an Entity Related to me.\n    pub fn reverse_join<R>(self, _: R) -> Self\n    where\n        R: EntityTrait + Related<E>,\n    {\n        self.join_rev(JoinType::InnerJoin, R::to())\n    }\n\n    /// Left Join with a Related Entity and select both Entity.\n    pub fn find_also<R>(self, _: E, r: R) -> SelectTwo<E, R>\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.left_join(r).select_also(r)\n    }\n\n    /// Left Join with a Related Entity and select both Entity.\n    pub fn find_also_related<R>(self, r: R) -> SelectTwo<E, R>\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.left_join(r).select_also(r)\n    }\n\n    /// Left Join with a Related Entity and select the related Entity as a `Vec`\n    pub fn find_with_related<R>(self, r: R) -> SelectTwoMany<E, R>\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.left_join(r).select_with(r)\n    }\n\n    /// Left Join with a Linked Entity and select both Entity.\n    pub fn find_also_linked<L, T>(self, l: L) -> SelectTwo<E, T>\n    where\n        L: Linked<FromEntity = E, ToEntity = T>,\n        T: EntityTrait,\n    {\n        SelectTwo::new_without_prepare(self.left_join_linked(l).into_query())\n    }\n\n    /// Left Join with a Linked Entity and select Entity as a `Vec`.\n    pub fn find_with_linked<L, T>(self, l: L) -> SelectTwoMany<E, T>\n    where\n        L: Linked<FromEntity = E, ToEntity = T>,\n        T: EntityTrait,\n    {\n        SelectTwoMany::new_without_prepare(self.left_join_linked(l).into_query())\n    }\n\n    /// Left Join with a Linked Entity.\n    pub fn left_join_linked<L, T>(mut self, l: L) -> Self\n    where\n        L: Linked<FromEntity = E, ToEntity = T>,\n        T: EntityTrait,\n    {\n        for (i, mut rel) in l.link().into_iter().enumerate() {\n            let r = self.linked_index;\n            self.linked_index += 1;\n            let to_tbl = format!(\"r{r}\").into_iden();\n            let from_tbl = if i > 0 {\n                format!(\"r{}\", i - 1).into_iden()\n            } else {\n                rel.from_tbl.sea_orm_table().clone()\n            };\n            let table_ref = rel.to_tbl;\n\n            let mut condition = Condition::all().add(join_tbl_on_condition(\n                from_tbl.clone(),\n                to_tbl.clone(),\n                rel.from_col,\n                rel.to_col,\n            ));\n            if let Some(f) = rel.on_condition.take() {\n                condition = condition.add(f(from_tbl.clone(), to_tbl.clone()));\n            }\n\n            self.query\n                .join_as(JoinType::LeftJoin, table_ref, to_tbl, condition);\n        }\n        self = self.apply_alias(SelectA.as_str());\n        for col in <T::Column as Iterable>::iter() {\n            let alias = format!(\"{}{}\", SelectB.as_str(), col.as_str());\n            let expr = Expr::col((\n                format!(\"r{}\", self.linked_index - 1).into_iden(),\n                col.into_iden(),\n            ));\n            self.query.expr(SelectExpr {\n                expr: col.select_as(expr),\n                alias: Some(alias.into_iden()),\n                window: None,\n            });\n        }\n        self\n    }\n\n    /// Filter by condition on the related Entity. Uses `EXISTS` SQL statement under the hood.\n    /// ```\n    /// # use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::{cake, fruit, filling}};\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .has_related(fruit::Entity, fruit::Column::Name.eq(\"Mango\"))\n    ///         .build(DbBackend::Sqlite)\n    ///         .to_string(),\n    ///     [\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n    ///         r#\"WHERE EXISTS(SELECT 1 FROM \"fruit\"\"#,\n    ///         r#\"WHERE \"fruit\".\"name\" = 'Mango'\"#,\n    ///         r#\"AND \"cake\".\"id\" = \"fruit\".\"cake_id\")\"#,\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .has_related(filling::Entity, filling::Column::Name.eq(\"Marmalade\"))\n    ///         .build(DbBackend::Sqlite)\n    ///         .to_string(),\n    ///     [\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n    ///         r#\"WHERE EXISTS(SELECT 1 FROM \"filling\"\"#,\n    ///         r#\"INNER JOIN \"cake_filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n    ///         r#\"WHERE \"filling\".\"name\" = 'Marmalade'\"#,\n    ///         r#\"AND \"cake\".\"id\" = \"cake_filling\".\"cake_id\")\"#,\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    /// ```\n    pub fn has_related<R, C>(mut self, _: R, condition: C) -> Self\n    where\n        R: EntityTrait,\n        E: Related<R>,\n        C: IntoCondition,\n    {\n        let mut to = None;\n        let mut condition = condition.into_condition();\n        condition = condition.add(if let Some(via) = E::via() {\n            to = Some(E::to());\n            via\n        } else {\n            E::to()\n        });\n        let mut subquery = R::find()\n            .select_only()\n            .expr(Expr::cust(\"1\"))\n            .filter(condition)\n            .into_query();\n        if let Some(to) = to {\n            // join the junction table\n            subquery.inner_join(to.from_tbl.clone(), to);\n        }\n        self.query.cond_where(Expr::exists(subquery));\n        self\n    }\n\n    #[doc(hidden)]\n    /// Recursive self-join with CTE\n    pub fn find_with_linked_recursive<L>(self, l: L) -> Select<E>\n    where\n        L: Linked<FromEntity = E, ToEntity = E>,\n    {\n        find_linked_recursive(self, l.link())\n    }\n}\n\nimpl<E, F> SelectTwo<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    /// Only used by Entity loader\n    #[doc(hidden)]\n    pub fn select_also_fake<R>(self, _: R) -> SelectThree<E, F, R, TopologyStar>\n    where\n        R: EntityTrait,\n    {\n        // select also but without join\n        SelectThree::new_without_prepare(self.into_query())\n    }\n\n    /// Left Join with a Related Entity and select both Entity.\n    pub fn find_also<G, R>(self, _: G, _: R) -> SelectThree<E, F, R, TopologyStar>\n    where\n        R: EntityTrait,\n        G: EntityTrait + Related<R>,\n    {\n        SelectThree::new(\n            self.join_join(JoinType::LeftJoin, G::to(), G::via())\n                .into_query(),\n        )\n    }\n\n    /// Left Join with an Entity Related to the first Entity\n    pub fn find_also_related<R>(self, _: R) -> SelectThree<E, F, R, TopologyStar>\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        SelectThree::new(\n            self.join_join(JoinType::LeftJoin, E::to(), E::via())\n                .into_query(),\n        )\n    }\n\n    /// Left Join with an Entity Related to the second Entity\n    pub fn and_also_related<R>(self, _: R) -> SelectThree<E, F, R, TopologyChain>\n    where\n        R: EntityTrait,\n        F: Related<R>,\n    {\n        SelectThree::new(\n            self.join_join(JoinType::LeftJoin, F::to(), F::via())\n                .into_query(),\n        )\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::{\n        cake, cake_compact, cake_filling, cake_filling_price, entity_linked, filling, fruit,\n    };\n    use crate::{\n        ColumnTrait, DbBackend, EntityTrait, ModelTrait, QueryFilter, QuerySelect, QueryTrait,\n        RelationTrait,\n    };\n    use pretty_assertions::assert_eq;\n    use sea_query::{ConditionType, Expr, ExprTrait, IntoCondition, JoinType};\n\n    #[test]\n    fn join_1() {\n        assert_eq!(\n            cake::Entity::find()\n                .left_join(fruit::Entity)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_2() {\n        assert_eq!(\n            cake::Entity::find()\n                .inner_join(fruit::Entity)\n                .filter(fruit::Column::Name.contains(\"cherry\"))\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"INNER JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`\",\n                \"WHERE `fruit`.`name` LIKE \\'%cherry%\\'\"\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_3() {\n        assert_eq!(\n            fruit::Entity::find()\n                .reverse_join(cake::Entity)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\",\n                \"INNER JOIN `cake` ON `cake`.`id` = `fruit`.`cake_id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_4() {\n        use crate::{Related, Select};\n\n        let find_fruit: Select<fruit::Entity> = cake::Entity::find_related();\n        assert_eq!(\n            find_fruit\n                .filter(cake::Column::Id.eq(11))\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\",\n                \"INNER JOIN `cake` ON `cake`.`id` = `fruit`.`cake_id`\",\n                \"WHERE `cake`.`id` = 11\",\n            ]\n            .join(\" \")\n        );\n\n        let find_fruit: Select<fruit::Entity> = cake::Entity::find_related_rev();\n        assert_eq!(\n            find_fruit\n                .filter(cake::Column::Id.eq(11))\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\",\n                \"INNER JOIN `cake` ON `fruit`.`cake_id` = `cake`.`id`\",\n                \"WHERE `cake`.`id` = 11\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_5() {\n        let cake_model = cake::Model {\n            id: 12,\n            name: \"\".to_owned(),\n        };\n\n        assert_eq!(\n            cake_model\n                .find_related(fruit::Entity)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\",\n                \"INNER JOIN `cake` ON `cake`.`id` = `fruit`.`cake_id`\",\n                \"WHERE `cake`.`id` = 12\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_6() {\n        assert_eq!(\n            cake::Entity::find()\n                .left_join(filling::Entity)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id`\",\n                \"LEFT JOIN `filling` ON `cake_filling`.`filling_id` = `filling`.`id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_7() {\n        use crate::{Related, Select};\n\n        let find_filling: Select<filling::Entity> = cake::Entity::find_related();\n        assert_eq!(\n            find_filling.build(DbBackend::MySql).to_string(),\n            [\n                \"SELECT `filling`.`id`, `filling`.`name`, `filling`.`vendor_id` FROM `filling`\",\n                \"INNER JOIN `cake_filling` ON `cake_filling`.`filling_id` = `filling`.`id`\",\n                \"INNER JOIN `cake` ON `cake`.`id` = `cake_filling`.`cake_id`\",\n            ]\n            .join(\" \")\n        );\n\n        let find_filling: Select<filling::Entity> = cake::Entity::find_related_rev();\n        assert_eq!(\n            find_filling.build(DbBackend::MySql).to_string(),\n            [\n                \"SELECT `filling`.`id`, `filling`.`name`, `filling`.`vendor_id` FROM `filling`\",\n                \"INNER JOIN `cake_filling` ON `filling`.`id` = `cake_filling`.`filling_id`\",\n                \"INNER JOIN `cake` ON `cake_filling`.`cake_id` = `cake`.`id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_8() {\n        use crate::{Related, Select};\n\n        let find_cake_filling_price: Select<cake_filling_price::Entity> =\n            cake_filling::Entity::find_related();\n        assert_eq!(\n            find_cake_filling_price.build(DbBackend::Postgres).to_string(),\n            [\n                r#\"SELECT \"cake_filling_price\".\"cake_id\", \"cake_filling_price\".\"filling_id\", \"cake_filling_price\".\"price\"\"#,\n                r#\"FROM \"public\".\"cake_filling_price\"\"#,\n                r#\"INNER JOIN \"cake_filling\" ON\"#,\n                r#\"\"cake_filling\".\"cake_id\" = \"cake_filling_price\".\"cake_id\" AND\"#,\n                r#\"\"cake_filling\".\"filling_id\" = \"cake_filling_price\".\"filling_id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_9() {\n        use crate::{Related, Select};\n\n        let find_cake_filling: Select<cake_filling::Entity> =\n            cake_filling_price::Entity::find_related();\n        assert_eq!(\n            find_cake_filling.build(DbBackend::Postgres).to_string(),\n            [\n                r#\"SELECT \"cake_filling\".\"cake_id\", \"cake_filling\".\"filling_id\"\"#,\n                r#\"FROM \"cake_filling\"\"#,\n                r#\"INNER JOIN \"public\".\"cake_filling_price\" ON\"#,\n                r#\"\"cake_filling_price\".\"cake_id\" = \"cake_filling\".\"cake_id\" AND\"#,\n                r#\"\"cake_filling_price\".\"filling_id\" = \"cake_filling\".\"filling_id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_10() {\n        let cake_model = cake::Model {\n            id: 12,\n            name: \"\".to_owned(),\n        };\n\n        assert_eq!(\n            cake_model\n                .find_linked(entity_linked::CakeToFilling)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                r\"SELECT `filling`.`id`, `filling`.`name`, `filling`.`vendor_id`\",\n                r\"FROM `filling`\",\n                r\"INNER JOIN `cake_filling` AS `r0` ON `r0`.`filling_id` = `filling`.`id`\",\n                r\"INNER JOIN `cake` AS `r1` ON `r1`.`id` = `r0`.`cake_id`\",\n                r\"WHERE `r1`.`id` = 12\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_11() {\n        let cake_model = cake::Model {\n            id: 18,\n            name: \"\".to_owned(),\n        };\n\n        assert_eq!(\n            cake_model\n                .find_linked(entity_linked::CakeToFillingVendor)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                r\"SELECT `vendor`.`id`, `vendor`.`name`\",\n                r\"FROM `vendor`\",\n                r\"INNER JOIN `filling` AS `r0` ON `r0`.`vendor_id` = `vendor`.`id`\",\n                r\"INNER JOIN `cake_filling` AS `r1` ON `r1`.`filling_id` = `r0`.`id`\",\n                r\"INNER JOIN `cake` AS `r2` ON `r2`.`id` = `r1`.`cake_id`\",\n                r\"WHERE `r2`.`id` = 18\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_12() {\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CakeToFilling)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                r\"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                r\"`r1`.`id` AS `B_id`, `r1`.`name` AS `B_name`, `r1`.`vendor_id` AS `B_vendor_id`\",\n                r\"FROM `cake`\",\n                r\"LEFT JOIN `cake_filling` AS `r0` ON `cake`.`id` = `r0`.`cake_id`\",\n                r\"LEFT JOIN `filling` AS `r1` ON `r0`.`filling_id` = `r1`.`id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_13() {\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                r\"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                r\"`r2`.`id` AS `B_id`, `r2`.`name` AS `B_name`\",\n                r\"FROM `cake`\",\n                r\"LEFT JOIN `cake_filling` AS `r0` ON `cake`.`id` = `r0`.`cake_id`\",\n                r\"LEFT JOIN `filling` AS `r1` ON `r0`.`filling_id` = `r1`.`id`\",\n                r\"LEFT JOIN `vendor` AS `r2` ON `r1`.`vendor_id` = `r2`.`id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_14() {\n        assert_eq!(\n            cake_compact::Entity::find()\n                .join(JoinType::LeftJoin, cake_compact::Relation::TropicalFruit.def())\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` AND `fruit`.`name` LIKE '%tropical%'\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_15() {\n        let cake_model = cake::Model {\n            id: 18,\n            name: \"\".to_owned(),\n        };\n\n        assert_eq!(\n            cake_model\n                .find_linked(entity_linked::CheeseCakeToFillingVendor)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                r\"SELECT `vendor`.`id`, `vendor`.`name`\",\n                r\"FROM `vendor`\",\n                r\"INNER JOIN `filling` AS `r0` ON `r0`.`vendor_id` = `vendor`.`id`\",\n                r\"INNER JOIN `cake_filling` AS `r1` ON `r1`.`filling_id` = `r0`.`id`\",\n                r\"INNER JOIN `cake` AS `r2` ON `r2`.`id` = `r1`.`cake_id` AND `r2`.`name` LIKE '%cheese%'\",\n                r\"WHERE `r2`.`id` = 18\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_16() {\n        // removed wrong test case\n    }\n\n    #[test]\n    fn join_17() {\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CheeseCakeToFillingVendor)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                r\"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                r\"`r2`.`id` AS `B_id`, `r2`.`name` AS `B_name`\",\n                r\"FROM `cake`\",\n                r\"LEFT JOIN `cake_filling` AS `r0` ON `cake`.`id` = `r0`.`cake_id` AND `cake`.`name` LIKE '%cheese%'\",\n                r\"LEFT JOIN `filling` AS `r1` ON `r0`.`filling_id` = `r1`.`id`\",\n                r\"LEFT JOIN `vendor` AS `r2` ON `r1`.`vendor_id` = `r2`.`id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_18() {\n        // removed wrong test case\n    }\n\n    #[test]\n    fn join_19() {\n        assert_eq!(\n            cake_compact::Entity::find()\n                .join(JoinType::LeftJoin, cake_compact::Relation::TropicalFruit.def())\n                .join(\n                    JoinType::LeftJoin,\n                    cake_filling::Relation::Cake\n                        .def()\n                        .rev()\n                        .on_condition(|_left, right| {\n                            Expr::col((right, cake_filling::Column::CakeId))\n                                .gt(10)\n                                .into_condition()\n                        })\n                )\n                .join(\n                    JoinType::LeftJoin,\n                    cake_filling::Relation::Filling\n                        .def()\n                        .on_condition(|_left, right| {\n                            Expr::col((right, filling::Column::Name))\n                                .like(\"%lemon%\")\n                                .into_condition()\n                        })\n                )\n                .join(JoinType::LeftJoin, filling::Relation::Vendor.def())\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` AND `fruit`.`name` LIKE '%tropical%'\",\n                \"LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id` AND `cake_filling`.`cake_id` > 10\",\n                \"LEFT JOIN `filling` ON `cake_filling`.`filling_id` = `filling`.`id` AND `filling`.`name` LIKE '%lemon%'\",\n                \"LEFT JOIN `vendor` ON `filling`.`vendor_id` = `vendor`.`id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_20() {\n        assert_eq!(\n            cake::Entity::find()\n                .column_as(\n                    Expr::col((\"fruit_alias\", fruit::Column::Name)),\n                    \"fruit_name\"\n                )\n                .join_as(\n                    JoinType::LeftJoin,\n                    cake::Relation::Fruit\n                        .def()\n                        .on_condition(|_left, right| {\n                            Expr::col((right, fruit::Column::Name))\n                                .like(\"%tropical%\")\n                                .into_condition()\n                        }),\n                    \"fruit_alias\"\n                )\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name`, `fruit_alias`.`name` AS `fruit_name` FROM `cake`\",\n                \"LEFT JOIN `fruit` AS `fruit_alias` ON `cake`.`id` = `fruit_alias`.`cake_id` AND `fruit_alias`.`name` LIKE '%tropical%'\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_21() {\n        assert_eq!(\n            cake_compact::Entity::find()\n                .column_as(\n                    Expr::col((\"cake_filling_alias\", cake_filling::Column::CakeId)),\n                    \"cake_filling_cake_id\"\n                )\n                .join(JoinType::LeftJoin, cake_compact::Relation::TropicalFruit.def())\n                .join_as_rev(\n                    JoinType::LeftJoin,\n                    cake_filling::Relation::Cake\n                        .def()\n                        .on_condition(|left, _right| {\n                            Expr::col((left, cake_filling::Column::CakeId))\n                                .gt(10)\n                                .into_condition()\n                        }),\n                    \"cake_filling_alias\"\n                )\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name`, `cake_filling_alias`.`cake_id` AS `cake_filling_cake_id` FROM `cake`\",\n                \"LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` AND `fruit`.`name` LIKE '%tropical%'\",\n                \"LEFT JOIN `cake_filling` AS `cake_filling_alias` ON `cake_filling_alias`.`cake_id` = `cake`.`id` AND `cake_filling_alias`.`cake_id` > 10\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_22() {\n        assert_eq!(\n            cake_compact::Entity::find()\n                .column_as(\n                    Expr::col((\"cake_filling_alias\", cake_filling::Column::CakeId)),\n                    \"cake_filling_cake_id\"\n                )\n                .join(JoinType::LeftJoin, cake_compact::Relation::OrTropicalFruit.def())\n                .join_as_rev(\n                    JoinType::LeftJoin,\n                    cake_filling::Relation::Cake\n                        .def()\n                        .condition_type(ConditionType::Any)\n                        .on_condition(|left, _right| {\n                            Expr::col((left, cake_filling::Column::CakeId))\n                                .gt(10)\n                                .into_condition()\n                        }),\n                    \"cake_filling_alias\"\n                )\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name`, `cake_filling_alias`.`cake_id` AS `cake_filling_cake_id` FROM `cake`\",\n                \"LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` OR `fruit`.`name` LIKE '%tropical%'\",\n                \"LEFT JOIN `cake_filling` AS `cake_filling_alias` ON `cake_filling_alias`.`cake_id` = `cake`.`id` OR `cake_filling_alias`.`cake_id` > 10\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_23() {\n        let cake_model = cake::Model {\n            id: 18,\n            name: \"\".to_owned(),\n        };\n\n        assert_eq!(\n            cake_model\n                .find_linked(entity_linked::CakeToCakeViaFilling)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"INNER JOIN `cake_filling` AS `r0` ON `r0`.`cake_id` = `cake`.`id`\",\n                \"INNER JOIN `filling` AS `r1` ON `r1`.`id` = `r0`.`filling_id`\",\n                \"INNER JOIN `cake_filling` AS `r2` ON `r2`.`filling_id` = `r1`.`id`\",\n                \"INNER JOIN `cake` AS `r3` ON `r3`.`id` = `r2`.`cake_id`\",\n                \"WHERE `r3`.`id` = 18\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_24() {\n        let cake_model = cake::Model {\n            id: 12,\n            name: \"\".to_owned(),\n        };\n\n        assert_eq!(\n            cake_model\n                .find_linked_recursive(entity_linked::CakeToCakeViaFilling)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"WITH `cte` AS (SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"INNER JOIN `cake_filling` AS `r0` ON `r0`.`cake_id` = `cake`.`id`\",\n                \"INNER JOIN `filling` AS `r1` ON `r1`.`id` = `r0`.`filling_id`\",\n                \"INNER JOIN `cake_filling` AS `r2` ON `r2`.`filling_id` = `r1`.`id`\",\n                \"INNER JOIN `cake` AS `r3` ON `r3`.`id` = `r2`.`cake_id`\",\n                \"WHERE `r3`.`id` = 12\",\n                \"UNION ALL (SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"INNER JOIN `cake_filling` AS `r0` ON `r0`.`cake_id` = `cake`.`id`\",\n                \"INNER JOIN `filling` AS `r1` ON `r1`.`id` = `r0`.`filling_id`\",\n                \"INNER JOIN `cake_filling` AS `r2` ON `r2`.`filling_id` = `r1`.`id`\",\n                \"INNER JOIN `cte` AS `r3` ON `r3`.`id` = `r2`.`cake_id`))\",\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cte` AS `cake`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_25() {\n        assert_eq!(\n            cake::Entity::find()\n                .find_with_linked_recursive(entity_linked::CakeToCakeViaFilling)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"WITH `cte` AS (SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"UNION ALL (SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"INNER JOIN `cake_filling` AS `r0` ON `r0`.`cake_id` = `cake`.`id`\",\n                \"INNER JOIN `filling` AS `r1` ON `r1`.`id` = `r0`.`filling_id`\",\n                \"INNER JOIN `cake_filling` AS `r2` ON `r2`.`filling_id` = `r1`.`id`\",\n                \"INNER JOIN `cte` AS `r3` ON `r3`.`id` = `r2`.`cake_id`))\",\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cte` AS `cake`\",\n            ]\n            .join(\" \")\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/query/json.rs",
    "content": "use crate::{FromQueryResult, QueryResult, error::*};\nuse serde_json::Map;\npub use serde_json::Value as JsonValue;\n\nimpl FromQueryResult for JsonValue {\n    #[allow(unused_variables, unused_mut)]\n    fn from_query_result(res: &QueryResult, pre: &str) -> Result<Self, DbErr> {\n        let mut map = Map::new();\n        #[allow(unused_macros)]\n        macro_rules! try_get_type {\n            ( $type: ty, $col: ident ) => {\n                if let Ok(v) = res.try_get::<Option<$type>>(pre, &$col) {\n                    map.insert($col.to_owned(), json!(v));\n                    continue;\n                }\n            };\n        }\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            crate::QueryResultRow::SqlxMySql(row) => {\n                use serde_json::json;\n                use sqlx::{Column, MySql, Row, Type};\n                for column in row.columns() {\n                    let col = if !column.name().starts_with(pre) {\n                        continue;\n                    } else {\n                        column.name().replacen(pre, \"\", 1)\n                    };\n                    let col_type = column.type_info();\n                    macro_rules! match_mysql_type {\n                        ( $type: ty ) => {\n                            if <$type as Type<MySql>>::type_info().eq(col_type) {\n                                try_get_type!($type, col)\n                            }\n                        };\n                    }\n                    macro_rules! match_mysql_compatible_type {\n                        ( $type: ty ) => {\n                            if <$type as Type<MySql>>::compatible(col_type) {\n                                try_get_type!($type, col)\n                            }\n                        };\n                    }\n                    match_mysql_type!(bool);\n                    match_mysql_type!(i8);\n                    match_mysql_type!(i16);\n                    match_mysql_type!(i32);\n                    match_mysql_type!(i64);\n                    match_mysql_type!(u8);\n                    match_mysql_type!(u16);\n                    match_mysql_type!(u32);\n                    match_mysql_type!(u64);\n                    match_mysql_type!(f32);\n                    match_mysql_type!(f64);\n                    match_mysql_type!(String);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_mysql_type!(chrono::NaiveDate);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_mysql_type!(chrono::NaiveTime);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_mysql_type!(chrono::NaiveDateTime);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_mysql_type!(chrono::DateTime<chrono::Utc>);\n                    #[cfg(feature = \"with-time\")]\n                    match_mysql_type!(time::Date);\n                    #[cfg(feature = \"with-time\")]\n                    match_mysql_type!(time::Time);\n                    #[cfg(feature = \"with-time\")]\n                    match_mysql_type!(time::PrimitiveDateTime);\n                    #[cfg(feature = \"with-time\")]\n                    match_mysql_type!(time::OffsetDateTime);\n                    #[cfg(feature = \"with-rust_decimal\")]\n                    match_mysql_type!(rust_decimal::Decimal);\n                    match_mysql_compatible_type!(String);\n                    #[cfg(feature = \"with-json\")]\n                    try_get_type!(serde_json::Value, col);\n                    #[cfg(feature = \"with-uuid\")]\n                    try_get_type!(uuid::Uuid, col);\n                    try_get_type!(Vec<u8>, col);\n                }\n                Ok(JsonValue::Object(map))\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            crate::QueryResultRow::SqlxPostgres(row) => {\n                use serde_json::json;\n                use sqlx::{Column, Postgres, Row, Type, postgres::types::Oid};\n\n                for column in row.columns() {\n                    let col = if !column.name().starts_with(pre) {\n                        continue;\n                    } else {\n                        column.name().replacen(pre, \"\", 1)\n                    };\n                    let col_type = column.type_info();\n\n                    macro_rules! match_postgres_type {\n                        ( $type: ty ) => {\n                            match col_type.kind() {\n                                #[cfg(feature = \"postgres-array\")]\n                                sqlx::postgres::PgTypeKind::Array(_) => {\n                                    if <Vec<$type> as Type<Postgres>>::type_info().eq(col_type) {\n                                        try_get_type!(Vec<$type>, col);\n                                    }\n                                }\n                                _ => {\n                                    if <$type as Type<Postgres>>::type_info().eq(col_type) {\n                                        try_get_type!($type, col);\n                                    }\n                                }\n                            }\n                        };\n                    }\n\n                    match_postgres_type!(bool);\n                    match_postgres_type!(i8);\n                    match_postgres_type!(i16);\n                    match_postgres_type!(i32);\n                    match_postgres_type!(i64);\n                    // match_postgres_type!(u8); // unsupported by SQLx Postgres\n                    // match_postgres_type!(u16); // unsupported by SQLx Postgres\n                    // Since 0.6.0, SQLx has dropped direct mapping from PostgreSQL's OID to Rust's `u32`;\n                    // Instead, `u32` was wrapped by a `sqlx::Oid`.\n                    if <Oid as Type<Postgres>>::type_info().eq(col_type) {\n                        try_get_type!(u32, col)\n                    }\n                    // match_postgres_type!(u64); // unsupported by SQLx Postgres\n                    match_postgres_type!(f32);\n                    match_postgres_type!(f64);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_postgres_type!(chrono::NaiveDate);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_postgres_type!(chrono::NaiveTime);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_postgres_type!(chrono::NaiveDateTime);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_postgres_type!(chrono::DateTime<chrono::FixedOffset>);\n                    #[cfg(feature = \"with-time\")]\n                    match_postgres_type!(time::Date);\n                    #[cfg(feature = \"with-time\")]\n                    match_postgres_type!(time::Time);\n                    #[cfg(feature = \"with-time\")]\n                    match_postgres_type!(time::PrimitiveDateTime);\n                    #[cfg(feature = \"with-time\")]\n                    match_postgres_type!(time::OffsetDateTime);\n                    #[cfg(feature = \"with-rust_decimal\")]\n                    match_postgres_type!(rust_decimal::Decimal);\n                    #[cfg(feature = \"with-json\")]\n                    try_get_type!(serde_json::Value, col);\n                    #[cfg(all(feature = \"with-json\", feature = \"postgres-array\"))]\n                    try_get_type!(Vec<serde_json::Value>, col);\n                    try_get_type!(String, col);\n                    #[cfg(feature = \"postgres-array\")]\n                    try_get_type!(Vec<String>, col);\n                    #[cfg(feature = \"postgres-vector\")]\n                    try_get_type!(pgvector::Vector, col);\n                    #[cfg(feature = \"with-uuid\")]\n                    try_get_type!(uuid::Uuid, col);\n                    #[cfg(all(feature = \"with-uuid\", feature = \"postgres-array\"))]\n                    try_get_type!(Vec<uuid::Uuid>, col);\n                    #[cfg(feature = \"with-ipnetwork\")]\n                    try_get_type!(ipnetwork::IpNetwork, col);\n                    #[cfg(all(feature = \"with-ipnetwork\", feature = \"postgres-array\"))]\n                    try_get_type!(Vec<ipnetwork::IpNetwork>, col);\n                    try_get_type!(Vec<u8>, col);\n                }\n                Ok(JsonValue::Object(map))\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            crate::QueryResultRow::SqlxSqlite(row) => {\n                use serde_json::json;\n                use sqlx::{Column, Row, Sqlite, Type};\n                for column in row.columns() {\n                    let col = if !column.name().starts_with(pre) {\n                        continue;\n                    } else {\n                        column.name().replacen(pre, \"\", 1)\n                    };\n                    let col_type = column.type_info();\n                    macro_rules! match_sqlite_type {\n                        ( $type: ty ) => {\n                            if <$type as Type<Sqlite>>::type_info().eq(col_type) {\n                                try_get_type!($type, col)\n                            }\n                        };\n                    }\n                    match_sqlite_type!(bool);\n                    match_sqlite_type!(i8);\n                    match_sqlite_type!(i16);\n                    match_sqlite_type!(i32);\n                    match_sqlite_type!(i64);\n                    match_sqlite_type!(u8);\n                    match_sqlite_type!(u16);\n                    match_sqlite_type!(u32);\n                    // match_sqlite_type!(u64); // unsupported by SQLx Sqlite\n                    match_sqlite_type!(f32);\n                    match_sqlite_type!(f64);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_sqlite_type!(chrono::NaiveDate);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_sqlite_type!(chrono::NaiveTime);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_sqlite_type!(chrono::NaiveDateTime);\n                    #[cfg(feature = \"with-time\")]\n                    match_sqlite_type!(time::Date);\n                    #[cfg(feature = \"with-time\")]\n                    match_sqlite_type!(time::Time);\n                    #[cfg(feature = \"with-time\")]\n                    match_sqlite_type!(time::PrimitiveDateTime);\n                    #[cfg(feature = \"with-time\")]\n                    match_sqlite_type!(time::OffsetDateTime);\n                    try_get_type!(String, col);\n                    #[cfg(feature = \"with-uuid\")]\n                    try_get_type!(uuid::Uuid, col);\n                    try_get_type!(Vec<u8>, col);\n                }\n                Ok(JsonValue::Object(map))\n            }\n            #[cfg(feature = \"rusqlite\")]\n            crate::QueryResultRow::Rusqlite(row) => {\n                use crate::driver::rusqlite::RusqliteOwnedValue;\n                use serde_json::json;\n\n                for (i, column) in row.columns.iter().enumerate() {\n                    let column = if !column.starts_with(pre) {\n                        continue;\n                    } else {\n                        column.replacen(pre, \"\", 1)\n                    };\n                    map.insert(\n                        column,\n                        match &row.values[i] {\n                            RusqliteOwnedValue::Integer(v) => json!(v),\n                            RusqliteOwnedValue::Real(v) => json!(v),\n                            RusqliteOwnedValue::Text(v) => json!(v),\n                            RusqliteOwnedValue::Blob(v) => json!(v),\n                            RusqliteOwnedValue::Null => json!(null),\n                        },\n                    );\n                }\n                Ok(JsonValue::Object(map))\n            }\n            #[cfg(feature = \"mock\")]\n            crate::QueryResultRow::Mock(row) => {\n                for (column, value) in row.clone().into_column_value_tuples() {\n                    let col = if !column.starts_with(pre) {\n                        continue;\n                    } else {\n                        column.replacen(pre, \"\", 1)\n                    };\n                    map.insert(col, sea_query::sea_value_to_json_value(&value));\n                }\n                Ok(JsonValue::Object(map))\n            }\n            #[cfg(feature = \"proxy\")]\n            crate::QueryResultRow::Proxy(row) => {\n                for (column, value) in row.clone().into_column_value_tuples() {\n                    let col = if !column.starts_with(pre) {\n                        continue;\n                    } else {\n                        column.replacen(pre, \"\", 1)\n                    };\n                    map.insert(col, sea_query::sea_value_to_json_value(&value));\n                }\n                Ok(JsonValue::Object(map))\n            }\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(test)]\n#[cfg(feature = \"mock\")]\nmod tests {\n    use crate::tests_cfg::cake;\n    use crate::{DbBackend, DbErr, MockDatabase, entity::*};\n    use sea_query::Value;\n\n    #[test]\n    fn to_json_1() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[maplit::btreemap! {\n                \"id\" => Into::<Value>::into(128), \"name\" => Into::<Value>::into(\"apple\")\n            }]])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find().into_json().one(&db).unwrap(),\n            Some(serde_json::json!({\n                \"id\": 128,\n                \"name\": \"apple\"\n            }))\n        );\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/query/loader.rs",
    "content": "use super::get_key_from_model;\nuse crate::{\n    ColumnTrait, Condition, ConnectionTrait, DbBackend, DbErr, EntityTrait, Identity, JoinType,\n    ModelTrait, QueryFilter, QuerySelect, Related, RelatedSelfVia, RelationDef, RelationTrait,\n    RelationType, Select, dynamic, query::column_tuple_in_condition, query_err,\n};\nuse sea_query::{ColumnRef, DynIden, Expr, ExprTrait, IntoColumnRef, TableRef, ValueTuple};\nuse std::{collections::HashMap, str::FromStr};\n\n// TODO: Replace DynIden::inner with a better API that without clone\n\n/// Entity, or a Select<Entity>; to be used as parameters in [`LoaderTrait`]\npub trait EntityOrSelect<E: EntityTrait> {\n    /// If self is Entity, use Entity::find()\n    fn select(self) -> Select<E>;\n}\n\ntype LoaderEntity<T> = <<T as LoaderTrait>::Model as ModelTrait>::Entity;\ntype LoaderModel<T> = <<<T as LoaderTrait>::Model as ModelTrait>::Entity as EntityTrait>::Model;\ntype LoaderRelation<T> =\n    <<<T as LoaderTrait>::Model as ModelTrait>::Entity as EntityTrait>::Relation;\n\n/// This trait implements the Data Loader API\npub trait LoaderTrait {\n    /// Source model\n    type Model: ModelTrait;\n\n    /// Used to eager load self_ref relations\n    fn load_self<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Option<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderModel<Self>: Send,\n        LoaderRelation<Self>: Send,\n        S: EntityOrSelect<LoaderEntity<Self>>;\n\n    /// Used to eager load self_ref relations in reverse, output is `Vec<Model>` instead of\n    /// `Option<Model>` of `load_self`.\n    fn load_self_many<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderModel<Self>: Send,\n        LoaderRelation<Self>: Send,\n        S: EntityOrSelect<LoaderEntity<Self>>;\n\n    /// Used to eager load self_ref + via relations\n    fn load_self_via<V, C>(&self, via: V, db: &C) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderModel<Self>: Send,\n        LoaderEntity<Self>: RelatedSelfVia<V>;\n\n    /// Used to eager load self_ref + via relations, but in reverse\n    fn load_self_via_rev<V, C>(&self, via: V, db: &C) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderModel<Self>: Send,\n        LoaderEntity<Self>: RelatedSelfVia<V>;\n\n    /// Used to eager load has_one relations\n    fn load_one<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Option<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n\n    /// Used to eager load has_many relations\n    fn load_many<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n\n    /// Used to eager load many_to_many relations. In SeaORM 2.0 `load_many` already support M-N\n    /// relations so this method is not needed, only kept as legacy.\n    fn load_many_to_many<R, S, V, C>(\n        &self,\n        stmt: S,\n        via: V,\n        db: &C,\n    ) -> Result<Vec<Vec<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        V: EntityTrait,\n        V::Model: Send,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n}\n\ntype LoaderExEntity<T> = <<T as LoaderTraitEx>::Model as ModelTrait>::Entity;\ntype LoaderExModel<T> = <<<T as LoaderTraitEx>::Model as ModelTrait>::Entity as EntityTrait>::Model;\ntype LoaderExModelEx<T> =\n    <<<T as LoaderTraitEx>::Model as ModelTrait>::Entity as EntityTrait>::ModelEx;\ntype LoaderExRelation<T> =\n    <<<T as LoaderTraitEx>::Model as ModelTrait>::Entity as EntityTrait>::Relation;\n\n#[doc(hidden)]\npub trait LoaderTraitEx {\n    type Model: ModelTrait;\n\n    fn load_self_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderExRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Option<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderExModel<Self>: Send,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExRelation<Self>: Send,\n        S: EntityOrSelect<LoaderExEntity<Self>>;\n\n    fn load_self_many_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderExRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderExModel<Self>: Send,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExRelation<Self>: Send,\n        S: EntityOrSelect<LoaderExEntity<Self>>;\n\n    fn load_self_via_ex<V, C>(\n        &self,\n        via: V,\n        is_reverse: bool,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderExModel<Self>: Send,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExEntity<Self>: RelatedSelfVia<V>;\n\n    fn load_one_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Option<R::ModelEx>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n\n    fn load_many_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<R::ModelEx>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n}\n\ntype NestedEntity<T> = <<T as NestedLoaderTrait>::Model as ModelTrait>::Entity;\ntype NestedModel<T> =\n    <<<T as NestedLoaderTrait>::Model as ModelTrait>::Entity as EntityTrait>::Model;\ntype NestedModelEx<T> =\n    <<<T as NestedLoaderTrait>::Model as ModelTrait>::Entity as EntityTrait>::ModelEx;\ntype NestedLoaderRelation<T> =\n    <<<T as NestedLoaderTrait>::Model as ModelTrait>::Entity as EntityTrait>::Relation;\n\n#[doc(hidden)]\npub trait NestedLoaderTrait {\n    type Model: ModelTrait;\n\n    fn load_self_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: NestedLoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<Option<NestedModelEx<Self>>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        NestedModel<Self>: Send,\n        NestedModelEx<Self>: From<NestedModel<Self>>,\n        NestedLoaderRelation<Self>: Send,\n        S: EntityOrSelect<<<Self as NestedLoaderTrait>::Model as ModelTrait>::Entity>;\n\n    fn load_self_many_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: NestedLoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<Vec<NestedModelEx<Self>>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        NestedModel<Self>: Send,\n        NestedModelEx<Self>: From<NestedModel<Self>>,\n        NestedLoaderRelation<Self>: Send,\n        S: EntityOrSelect<<<Self as NestedLoaderTrait>::Model as ModelTrait>::Entity>;\n\n    fn load_self_via_ex<V, C>(\n        &self,\n        via: V,\n        is_reverse: bool,\n        db: &C,\n    ) -> Result<Vec<Vec<Vec<NestedModelEx<Self>>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        NestedModel<Self>: Send,\n        NestedModelEx<Self>: From<NestedModel<Self>>,\n        NestedEntity<Self>: RelatedSelfVia<V>;\n\n    fn load_one_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<Option<R::ModelEx>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n\n    fn load_many_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<Vec<R::ModelEx>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n}\n\nimpl<E> EntityOrSelect<E> for E\nwhere\n    E: EntityTrait,\n{\n    fn select(self) -> Select<E> {\n        E::find().order_by_id_asc()\n    }\n}\n\nimpl<E> EntityOrSelect<E> for Select<E>\nwhere\n    E: EntityTrait,\n{\n    fn select(self) -> Select<E> {\n        self\n    }\n}\n\nimpl<M> LoaderTrait for Vec<M>\nwhere\n    M: ModelTrait,\n{\n    type Model = M;\n\n    fn load_self<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Option<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderModel<Self>: Send,\n        LoaderRelation<Self>: Send,\n        S: EntityOrSelect<LoaderEntity<Self>>,\n    {\n        LoaderTrait::load_self(&self.as_slice(), stmt, relation_enum, db)\n    }\n\n    fn load_self_many<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderModel<Self>: Send,\n        LoaderRelation<Self>: Send,\n        S: EntityOrSelect<LoaderEntity<Self>>,\n    {\n        LoaderTrait::load_self_many(&self.as_slice(), stmt, relation_enum, db)\n    }\n\n    fn load_self_via<V, C>(&self, via: V, db: &C) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderModel<Self>: Send,\n        LoaderEntity<Self>: RelatedSelfVia<V>,\n    {\n        LoaderTrait::load_self_via(&self.as_slice(), via, db)\n    }\n\n    fn load_self_via_rev<V, C>(&self, via: V, db: &C) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderModel<Self>: Send,\n        LoaderEntity<Self>: RelatedSelfVia<V>,\n    {\n        LoaderTrait::load_self_via_rev(&self.as_slice(), via, db)\n    }\n\n    fn load_one<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Option<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        LoaderTrait::load_one(&self.as_slice(), stmt, db)\n    }\n\n    fn load_many<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        LoaderTrait::load_many(&self.as_slice(), stmt, db)\n    }\n\n    fn load_many_to_many<R, S, V, C>(\n        &self,\n        stmt: S,\n        via: V,\n        db: &C,\n    ) -> Result<Vec<Vec<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        V: EntityTrait,\n        V::Model: Send,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        LoaderTrait::load_many_to_many(&self.as_slice(), stmt, via, db)\n    }\n}\n\nimpl<M> LoaderTrait for &[M]\nwhere\n    M: ModelTrait,\n{\n    type Model = M;\n\n    fn load_self<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Option<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderModel<Self>: Send,\n        LoaderRelation<Self>: Send,\n        S: EntityOrSelect<LoaderEntity<Self>>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref(&rel_def)?;\n        loader_impl_impl(self.iter(), stmt.select(), rel_def, None, db)\n    }\n\n    fn load_self_many<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderModel<Self>: Send,\n        LoaderRelation<Self>: Send,\n        S: EntityOrSelect<LoaderEntity<Self>>,\n    {\n        let mut rel_def = relation_enum.def();\n        if rel_def.from_tbl != rel_def.to_tbl {\n            return Err(query_err(\"Relation must be self referencing\"));\n        }\n        if !rel_def.is_owner {\n            // flip belongs_to\n            rel_def = rel_def.rev();\n        }\n        loader_impl_impl(self.iter(), stmt.select(), rel_def, None, db)\n    }\n\n    fn load_self_via<V, C>(&self, _: V, db: &C) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderModel<Self>: Send,\n        LoaderEntity<Self>: RelatedSelfVia<V>,\n    {\n        let rel_def = <LoaderEntity<Self> as RelatedSelfVia<V>>::to();\n        let rel_via = <LoaderEntity<Self> as RelatedSelfVia<V>>::via();\n        loader_impl_impl(\n            self.iter(),\n            EntityOrSelect::select(LoaderEntity::<Self>::default()),\n            rel_def,\n            Some(rel_via),\n            db,\n        )\n    }\n\n    fn load_self_via_rev<V, C>(&self, _: V, db: &C) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderModel<Self>: Send,\n        LoaderEntity<Self>: RelatedSelfVia<V>,\n    {\n        let rel_def = <LoaderEntity<Self> as RelatedSelfVia<V>>::via().rev();\n        let rel_via = <LoaderEntity<Self> as RelatedSelfVia<V>>::to().rev();\n        loader_impl_impl(\n            self.iter(),\n            EntityOrSelect::select(LoaderEntity::<Self>::default()),\n            rel_def,\n            Some(rel_via),\n            db,\n        )\n    }\n\n    fn load_one<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Option<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        let rel_def = <<Self::Model as ModelTrait>::Entity as Related<R>>::to();\n        if rel_def.rel_type != RelationType::HasOne {\n            return Err(query_err(\"Relation is HasMany instead of HasOne\"));\n        }\n        loader_impl(self.iter(), stmt.select(), db)\n    }\n\n    fn load_many<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        loader_impl(self.iter(), stmt.select(), db)\n    }\n\n    fn load_many_to_many<R, S, V, C>(\n        &self,\n        stmt: S,\n        via: V,\n        db: &C,\n    ) -> Result<Vec<Vec<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        V: EntityTrait,\n        V::Model: Send,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        if let Some(via_rel) = <<Self::Model as ModelTrait>::Entity as Related<R>>::via() {\n            let rel_def = <<Self::Model as ModelTrait>::Entity as Related<R>>::to();\n            if rel_def.rel_type != RelationType::HasOne {\n                return Err(query_err(\"Relation to is not HasOne\"));\n            }\n\n            if !cmp_table_ref(&via_rel.to_tbl, &via.table_ref()) {\n                return Err(query_err(format!(\n                    \"The given via Entity is incorrect: expected: {:?}, given: {:?}\",\n                    via_rel.to_tbl,\n                    via.table_ref()\n                )));\n            }\n\n            if self.is_empty() {\n                return Ok(Vec::new());\n            }\n\n            let pkeys = self\n                .iter()\n                .map(|model| get_key_from_model(&via_rel.from_col, model))\n                .collect::<Result<Vec<_>, _>>()?;\n\n            // Map of M::PK -> Vec<R::PK>\n            let mut keymap: HashMap<ValueTuple, Vec<ValueTuple>> = Default::default();\n\n            let keys: Vec<ValueTuple> = {\n                let condition = prepare_condition::<M>(\n                    &via_rel.to_tbl,\n                    &via_rel.from_col,\n                    &via_rel.to_col,\n                    &pkeys,\n                    db.get_database_backend(),\n                )?;\n                let stmt = V::find().filter(condition);\n                let data = stmt.all(db)?;\n                for model in data {\n                    let pk = get_key_from_model(&via_rel.to_col, &model)?;\n                    let entry = keymap.entry(pk).or_default();\n\n                    let fk = get_key_from_model(&rel_def.from_col, &model)?;\n                    entry.push(fk);\n                }\n\n                keymap.values().flatten().cloned().collect()\n            };\n\n            let condition = prepare_condition::<V::Model>(\n                &rel_def.to_tbl,\n                &rel_def.from_col,\n                &rel_def.to_col,\n                &keys,\n                db.get_database_backend(),\n            )?;\n\n            let stmt = QueryFilter::filter(stmt.select(), condition);\n\n            let models = stmt.all(db)?;\n\n            // Map of R::PK -> R::Model\n            let data = models.into_iter().try_fold(\n                HashMap::<ValueTuple, <R as EntityTrait>::Model>::new(),\n                |mut acc, model| {\n                    get_key_from_model(&rel_def.to_col, &model).map(|key| {\n                        acc.insert(key, model);\n\n                        acc\n                    })\n                },\n            )?;\n\n            let result: Vec<Vec<R::Model>> = pkeys\n                .into_iter()\n                .map(|pkey| {\n                    let fkeys = keymap.get(&pkey).cloned().unwrap_or_default();\n\n                    let models: Vec<_> = fkeys\n                        .into_iter()\n                        .filter_map(|fkey| data.get(&fkey).cloned())\n                        .collect();\n\n                    models\n                })\n                .collect();\n\n            Ok(result)\n        } else {\n            return Err(query_err(\"Relation is not ManyToMany\"));\n        }\n    }\n}\n\nimpl<M> LoaderTraitEx for &[M]\nwhere\n    M: ModelTrait,\n{\n    type Model = M;\n\n    fn load_self_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderExRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Option<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderExModel<Self>: Send,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExRelation<Self>: Send,\n        S: EntityOrSelect<LoaderExEntity<Self>>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref(&rel_def)?;\n        loader_impl_impl(self.iter(), stmt.select(), rel_def, None, db)\n    }\n\n    fn load_self_many_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderExRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderExModel<Self>: Send,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExRelation<Self>: Send,\n        S: EntityOrSelect<LoaderExEntity<Self>>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref_many(&rel_def)?;\n        loader_impl_impl(self.iter(), stmt.select(), rel_def, None, db)\n    }\n\n    fn load_self_via_ex<V, C>(\n        &self,\n        _: V,\n        is_reverse: bool,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderExModel<Self>: Send,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExEntity<Self>: RelatedSelfVia<V>,\n    {\n        let (rel_def, rel_via) = if !is_reverse {\n            (\n                <LoaderExEntity<Self> as RelatedSelfVia<V>>::to(),\n                <LoaderExEntity<Self> as RelatedSelfVia<V>>::via(),\n            )\n        } else {\n            (\n                <LoaderEntity<Self> as RelatedSelfVia<V>>::via().rev(),\n                <LoaderEntity<Self> as RelatedSelfVia<V>>::to().rev(),\n            )\n        };\n        loader_impl_impl(\n            self.iter(),\n            EntityOrSelect::select(LoaderExEntity::<Self>::default()),\n            rel_def,\n            Some(rel_via),\n            db,\n        )\n    }\n\n    fn load_one_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Option<R::ModelEx>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        let rel_def = <<Self::Model as ModelTrait>::Entity as Related<R>>::to();\n        if rel_def.rel_type != RelationType::HasOne {\n            return Err(query_err(\"Relation is HasMany instead of HasOne\"));\n        }\n        loader_impl(self.iter(), stmt.select(), db)\n    }\n\n    fn load_many_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<R::ModelEx>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        loader_impl(self.iter(), stmt.select(), db)\n    }\n}\n\nimpl<M> LoaderTraitEx for &[Option<M>]\nwhere\n    M: ModelTrait,\n{\n    type Model = M;\n\n    fn load_self_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderExRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Option<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderExModel<Self>: Send,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExRelation<Self>: Send,\n        S: EntityOrSelect<LoaderExEntity<Self>>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref(&rel_def)?;\n        let items: Vec<Option<_>> = loader_impl_impl(\n            self.iter().filter_map(|o| o.as_ref()),\n            stmt.select(),\n            rel_def,\n            None,\n            db,\n        )?;\n        Ok(assemble_options(self, items))\n    }\n\n    fn load_self_many_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderExRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderExModel<Self>: Send,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExRelation<Self>: Send,\n        S: EntityOrSelect<LoaderExEntity<Self>>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref_many(&rel_def)?;\n        let items: Vec<Vec<_>> = loader_impl_impl(\n            self.iter().filter_map(|o| o.as_ref()),\n            stmt.select(),\n            rel_def,\n            None,\n            db,\n        )?;\n        Ok(assemble_options(self, items))\n    }\n\n    fn load_self_via_ex<V, C>(\n        &self,\n        _: V,\n        is_reverse: bool,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderExModel<Self>: Send,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExEntity<Self>: RelatedSelfVia<V>,\n    {\n        let (rel_def, rel_via) = if !is_reverse {\n            (\n                <LoaderExEntity<Self> as RelatedSelfVia<V>>::to(),\n                <LoaderExEntity<Self> as RelatedSelfVia<V>>::via(),\n            )\n        } else {\n            (\n                <LoaderExEntity<Self> as RelatedSelfVia<V>>::via().rev(),\n                <LoaderExEntity<Self> as RelatedSelfVia<V>>::to().rev(),\n            )\n        };\n        let items: Vec<Vec<_>> = loader_impl_impl(\n            self.iter().filter_map(|o| o.as_ref()),\n            EntityOrSelect::select(LoaderExEntity::<Self>::default()),\n            rel_def,\n            Some(rel_via),\n            db,\n        )?;\n        Ok(assemble_options(self, items))\n    }\n\n    fn load_one_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Option<R::ModelEx>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        let rel_def = <<Self::Model as ModelTrait>::Entity as Related<R>>::to();\n        if rel_def.rel_type != RelationType::HasOne {\n            return Err(query_err(\"Relation is HasMany instead of HasOne\"));\n        }\n        let items: Vec<Option<R::ModelEx>> =\n            loader_impl(self.iter().filter_map(|o| o.as_ref()), stmt.select(), db)?;\n        Ok(assemble_options(self, items))\n    }\n\n    fn load_many_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<R::ModelEx>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        let items: Vec<Vec<R::ModelEx>> =\n            loader_impl(self.iter().filter_map(|o| o.as_ref()), stmt.select(), db)?;\n        Ok(assemble_options(self, items))\n    }\n}\n\nimpl<M> NestedLoaderTrait for &[Vec<M>]\nwhere\n    M: ModelTrait,\n{\n    type Model = M;\n\n    fn load_self_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: NestedLoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<Option<NestedModelEx<Self>>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        NestedModel<Self>: Send,\n        NestedModelEx<Self>: From<NestedModel<Self>>,\n        NestedLoaderRelation<Self>: Send,\n        S: EntityOrSelect<<<Self as NestedLoaderTrait>::Model as ModelTrait>::Entity>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref(&rel_def)?;\n        let items: Vec<Option<_>> =\n            loader_impl_impl(self.iter().flatten(), stmt.select(), rel_def, None, db)?;\n        Ok(assemble_vectors(self, items))\n    }\n\n    fn load_self_many_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: NestedLoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<Vec<NestedModelEx<Self>>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        NestedModel<Self>: Send,\n        NestedModelEx<Self>: From<NestedModel<Self>>,\n        NestedLoaderRelation<Self>: Send,\n        S: EntityOrSelect<<<Self as NestedLoaderTrait>::Model as ModelTrait>::Entity>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref_many(&rel_def)?;\n        let items: Vec<Vec<_>> =\n            loader_impl_impl(self.iter().flatten(), stmt.select(), rel_def, None, db)?;\n        Ok(assemble_vectors(self, items))\n    }\n\n    fn load_self_via_ex<V, C>(\n        &self,\n        _: V,\n        is_reverse: bool,\n        db: &C,\n    ) -> Result<Vec<Vec<Vec<NestedModelEx<Self>>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        NestedModel<Self>: Send,\n        NestedModelEx<Self>: From<NestedModel<Self>>,\n        NestedEntity<Self>: RelatedSelfVia<V>,\n    {\n        let (rel_def, rel_via) = if !is_reverse {\n            (\n                <NestedEntity<Self> as RelatedSelfVia<V>>::to(),\n                <NestedEntity<Self> as RelatedSelfVia<V>>::via(),\n            )\n        } else {\n            (\n                <NestedEntity<Self> as RelatedSelfVia<V>>::via().rev(),\n                <NestedEntity<Self> as RelatedSelfVia<V>>::to().rev(),\n            )\n        };\n        let items: Vec<Vec<_>> = loader_impl_impl(\n            self.iter().flatten(),\n            EntityOrSelect::select(NestedEntity::<Self>::default()),\n            rel_def,\n            Some(rel_via),\n            db,\n        )?;\n        Ok(assemble_vectors(self, items))\n    }\n\n    fn load_one_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<Option<R::ModelEx>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        let rel_def = <<Self::Model as ModelTrait>::Entity as Related<R>>::to();\n        if rel_def.rel_type != RelationType::HasOne {\n            return Err(query_err(\"Relation is HasMany instead of HasOne\"));\n        }\n        let items: Vec<Option<R::ModelEx>> = loader_impl(self.iter().flatten(), stmt.select(), db)?;\n        Ok(assemble_vectors(self, items))\n    }\n\n    fn load_many_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<Vec<R::ModelEx>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        let items: Vec<Vec<R::ModelEx>> = loader_impl(self.iter().flatten(), stmt.select(), db)?;\n        Ok(assemble_vectors(self, items))\n    }\n}\n\nfn assemble_options<I, T: Default>(input: &[Option<I>], items: Vec<T>) -> Vec<T> {\n    let mut items = items.into_iter();\n    let mut output = Vec::new();\n    for input in input.iter() {\n        if input.is_some() {\n            output.push(items.next().unwrap_or_default());\n        } else {\n            output.push(T::default());\n        }\n    }\n    output\n}\n\nfn assemble_vectors<I, T: Default>(input: &[Vec<I>], items: Vec<T>) -> Vec<Vec<T>> {\n    let mut items = items.into_iter();\n\n    let mut output = Vec::new();\n\n    for input in input.iter() {\n        output.push(Vec::new());\n\n        for _inner in input.iter() {\n            output\n                .last_mut()\n                .expect(\"Pushed above\")\n                .push(items.next().unwrap_or_default());\n        }\n    }\n\n    output\n}\n\ntrait Container: Default + Clone {\n    type Item;\n    fn add(&mut self, item: Self::Item);\n}\n\nimpl<T: Clone> Container for Vec<T> {\n    type Item = T;\n    fn add(&mut self, item: Self::Item) {\n        self.push(item);\n    }\n}\n\nimpl<T: Clone> Container for Option<T> {\n    type Item = T;\n    fn add(&mut self, item: Self::Item) {\n        self.replace(item);\n    }\n}\n\nfn loader_impl<'a, Model, Iter, R, C, T, Output>(\n    items: Iter,\n    stmt: Select<R>,\n    db: &C,\n) -> Result<Vec<T>, DbErr>\nwhere\n    Model: ModelTrait + 'a,\n    Iter: Iterator<Item = &'a Model> + 'a,\n    C: ConnectionTrait,\n    R: EntityTrait,\n    Model::Entity: Related<R>,\n    Output: From<R::Model>,\n    T: Container<Item = Output>,\n{\n    loader_impl_impl(\n        items,\n        stmt,\n        <Model::Entity as Related<R>>::to(),\n        <Model::Entity as Related<R>>::via(),\n        db,\n    )\n}\n\n// All variants monomorphizes to this implementation, which is a constant number of variants\n// per Entity, permutating on different shapes, e.g. Vec<Model>, Option<ModelEx>\nfn loader_impl_impl<'a, Model, Iter, R, C, T, Output>(\n    items: Iter,\n    stmt: Select<R>,\n    rel_def: RelationDef,\n    via_def: Option<RelationDef>,\n    db: &C,\n) -> Result<Vec<T>, DbErr>\nwhere\n    Model: ModelTrait + 'a,\n    Iter: Iterator<Item = &'a Model> + 'a,\n    C: ConnectionTrait,\n    R: EntityTrait,\n    Output: From<R::Model>,\n    T: Container<Item = Output>,\n{\n    let (keys, hashmap) = if let Some(via_def) = via_def {\n        let keys = items\n            .map(|model| get_key_from_model(&via_def.from_col, model))\n            .collect::<Result<Vec<_>, _>>()?;\n\n        if keys.is_empty() {\n            return Ok(Vec::new());\n        }\n\n        let condition = prepare_condition::<Model>(\n            &via_def.to_tbl,\n            &via_def.from_col,\n            &via_def.to_col,\n            &keys,\n            db.get_database_backend(),\n        )?;\n\n        let stmt = QueryFilter::filter(stmt.join_rev(JoinType::InnerJoin, rel_def), condition);\n\n        // The idea is to do a SelectTwo with join, then extract key via a dynamic model\n        // i.e. select (baker + cake_baker) and extract cake_id from result rows\n        // SELECT \"baker\".\"id\", \"baker\".\"name\", \"baker\".\"contact_details\", \"baker\".\"bakery_id\",\n        //     \"cakes_bakers\".\"cake_id\" <- extra select\n        // FROM \"baker\" <- target\n        // INNER JOIN \"cakes_bakers\" <- junction\n        //     ON \"cakes_bakers\".\"baker_id\" = \"baker\".\"id\" <- relation\n        // WHERE \"cakes_bakers\".\"cake_id\" IN (..)\n\n        let data = stmt\n            .select_also_dyn_model(\n                via_def.to_tbl.sea_orm_table().clone(),\n                dynamic::ModelType {\n                    // we uses the left Model's type but the right Model's field\n                    fields: extract_col_type::<Model>(&via_def.from_col, &via_def.to_col)?,\n                },\n            )\n            .all(db)?;\n\n        let mut hashmap: HashMap<ValueTuple, T> =\n            keys.iter()\n                .fold(HashMap::new(), |mut acc, key: &ValueTuple| {\n                    acc.insert(key.clone(), T::default());\n                    acc\n                });\n\n        for (item, key) in data {\n            let key = dyn_model_to_key(key)?;\n\n            let vec = hashmap.get_mut(&key).ok_or_else(|| {\n                DbErr::RecordNotFound(format!(\"Loader: failed to find model for {key:?}\"))\n            })?;\n\n            vec.add(item.into());\n        }\n\n        (keys, hashmap)\n    } else {\n        let keys = items\n            .map(|model| get_key_from_model(&rel_def.from_col, model))\n            .collect::<Result<Vec<_>, _>>()?;\n\n        if keys.is_empty() {\n            return Ok(Vec::new());\n        }\n\n        let condition = prepare_condition::<Model>(\n            &rel_def.to_tbl,\n            &rel_def.from_col,\n            &rel_def.to_col,\n            &keys,\n            db.get_database_backend(),\n        )?;\n\n        let stmt = QueryFilter::filter(stmt, condition);\n\n        let data = stmt.all(db)?;\n\n        let mut hashmap: HashMap<ValueTuple, T> = Default::default();\n\n        for item in data {\n            let key = get_key_from_model(&rel_def.to_col, &item)?;\n            let holder = hashmap.entry(key).or_default();\n            holder.add(item.into());\n        }\n\n        (keys, hashmap)\n    };\n\n    let result: Vec<T> = keys\n        .iter()\n        .map(|key: &ValueTuple| hashmap.get(key).cloned().unwrap_or_default())\n        .collect();\n\n    Ok(result)\n}\n\nfn cmp_table_ref(left: &TableRef, right: &TableRef) -> bool {\n    left == right\n}\n\nfn extract_col_type<Model>(\n    left: &Identity,\n    right: &Identity,\n) -> Result<Vec<dynamic::FieldType>, DbErr>\nwhere\n    Model: ModelTrait,\n{\n    use itertools::Itertools;\n\n    if left.arity() != right.arity() {\n        return Err(DbErr::Type(format!(\n            \"Identity mismatch: left: {} != right: {}\",\n            left.arity(),\n            right.arity()\n        )));\n    }\n\n    let vec = left\n        .iter()\n        .zip_eq(right.iter())\n        .map(|(l, r)| {\n            let col_a =\n                <<<Model as ModelTrait>::Entity as EntityTrait>::Column as FromStr>::from_str(\n                    &l.inner(),\n                )\n                .map_err(|_| DbErr::Type(format!(\"Failed at mapping '{l}'\")))?;\n            Ok(dynamic::FieldType::new(\n                r.clone(),\n                Model::get_value_type(col_a),\n            ))\n        })\n        .collect::<Result<Vec<_>, DbErr>>()?;\n\n    Ok(vec)\n}\n\n#[allow(clippy::unwrap_used)]\nfn dyn_model_to_key(dyn_model: dynamic::Model) -> Result<ValueTuple, DbErr> {\n    Ok(match dyn_model.fields.len() {\n        0 => return Err(DbErr::Type(\"Identity zero?\".into())),\n        1 => ValueTuple::One(dyn_model.fields.into_iter().next().unwrap().value),\n        2 => {\n            let mut iter = dyn_model.fields.into_iter();\n            ValueTuple::Two(iter.next().unwrap().value, iter.next().unwrap().value)\n        }\n        3 => {\n            let mut iter = dyn_model.fields.into_iter();\n            ValueTuple::Three(\n                iter.next().unwrap().value,\n                iter.next().unwrap().value,\n                iter.next().unwrap().value,\n            )\n        }\n        _ => ValueTuple::Many(dyn_model.fields.into_iter().map(|v| v.value).collect()),\n    })\n}\n\nfn arity_mismatch(expected: usize, actual: &ValueTuple) -> DbErr {\n    DbErr::Type(format!(\n        \"Loader: arity mismatch: expected {expected}, got {} in {actual:?}\",\n        actual.arity()\n    ))\n}\n\nfn prepare_condition<Model>(\n    table: &TableRef,\n    from: &Identity,\n    to: &Identity,\n    keys: &[ValueTuple],\n    db_backend: DbBackend,\n) -> Result<Condition, DbErr>\nwhere\n    Model: ModelTrait,\n{\n    if matches!(db_backend, DbBackend::Postgres) {\n        prepare_condition_with_save_as::<Model>(table, from, to, keys)\n    } else {\n        column_tuple_in_condition(table, to, keys, db_backend)\n    }\n}\n\nfn prepare_condition_with_save_as<Model>(\n    table: &TableRef,\n    from: &Identity,\n    to: &Identity,\n    keys: &[ValueTuple],\n) -> Result<Condition, DbErr>\nwhere\n    Model: ModelTrait,\n{\n    use itertools::Itertools;\n\n    let keys = keys.iter().unique();\n    let (from_cols, to_cols) = resolve_column_pairs::<Model>(table, from, to)?;\n\n    if from_cols.is_empty() || to_cols.is_empty() {\n        return Err(DbErr::Type(format!(\n            \"Loader: resolved zero columns for identities {from:?} -> {to:?}\"\n        )));\n    }\n\n    let arity = from_cols.len();\n\n    let value_tuples = keys\n        .map(|key| {\n            let key_arity = key.arity();\n            if arity != key_arity {\n                return Err(arity_mismatch(arity, key));\n            }\n\n            // For Postgres, we need to use `AS` to cast the value to the correct type\n            Ok(apply_save_as::<Model>(&from_cols, key.clone()))\n        })\n        .collect::<Result<Vec<_>, DbErr>>()?;\n\n    // Build `(c1, c2, ...) IN ((v11, v12, ...), (v21, v22, ...), ...)`\n    let expr = Expr::tuple(create_table_columns(table, to)).is_in(value_tuples);\n\n    Ok(expr.into())\n}\n\ntype ModelColumn<M> = <<M as ModelTrait>::Entity as EntityTrait>::Column;\n\ntype ColumnPairs<M> = (Vec<ModelColumn<M>>, Vec<ColumnRef>);\n\nfn resolve_column_pairs<Model>(\n    table: &TableRef,\n    from: &Identity,\n    to: &Identity,\n) -> Result<ColumnPairs<Model>, DbErr>\nwhere\n    Model: ModelTrait,\n    ModelColumn<Model>: ColumnTrait,\n{\n    let from_columns = parse_identity_columns::<Model>(from)?;\n    let to_columns = column_refs_from_identity(table, to);\n\n    if from_columns.len() != to_columns.len() {\n        return Err(DbErr::Type(format!(\n            \"Loader: identity column count mismatch between {from:?} and {to:?}\"\n        )));\n    }\n\n    Ok((from_columns, to_columns))\n}\n\nfn check_self_ref(rel_def: &RelationDef) -> Result<(), DbErr> {\n    if rel_def.from_tbl != rel_def.to_tbl {\n        return Err(query_err(\"Relation must be self referencing\"));\n    }\n    if rel_def.is_owner {\n        return Err(query_err(\"Relation must be belongs_to\"));\n    }\n    Ok(())\n}\n\nfn check_self_ref_many(rel_def: &RelationDef) -> Result<(), DbErr> {\n    if rel_def.from_tbl != rel_def.to_tbl {\n        return Err(query_err(\"Relation must be self referencing\"));\n    }\n    if !rel_def.is_owner {\n        return Err(query_err(\"Relation must not be belongs_to\"));\n    }\n    Ok(())\n}\n\nfn column_refs_from_identity(table: &TableRef, identity: &Identity) -> Vec<ColumnRef> {\n    identity\n        .iter()\n        .map(|col| table_column(table, col))\n        .collect()\n}\n\nfn parse_identity_columns<Model>(identity: &Identity) -> Result<Vec<ModelColumn<Model>>, DbErr>\nwhere\n    Model: ModelTrait,\n{\n    identity\n        .iter()\n        .map(|from_col| try_conv_ident_to_column::<Model>(from_col))\n        .collect()\n}\n\nfn try_conv_ident_to_column<Model>(ident: &DynIden) -> Result<ModelColumn<Model>, DbErr>\nwhere\n    Model: ModelTrait,\n{\n    let column_name = ident.inner();\n    ModelColumn::<Model>::from_str(&column_name)\n        .map_err(|_| DbErr::Type(format!(\"Failed at mapping '{column_name}' to column\")))\n}\n\nfn table_column(tbl: &TableRef, col: &DynIden) -> ColumnRef {\n    (tbl.sea_orm_table().to_owned(), col.clone()).into_column_ref()\n}\n\n/// Create a vector of `Expr::col` from the table and identity, e.g. [Expr::col((table, col1)), Expr::col((table, col2)), ...]\nfn create_table_columns(table: &TableRef, cols: &Identity) -> Vec<Expr> {\n    cols.iter()\n        .map(|col| table_column(table, col))\n        .map(Expr::col)\n        .collect()\n}\n\n/// Apply `save_as` to each value in the tuple, e.g. `(Cast(val1 as type1), Cast(val2 as type2), ...)`\nfn apply_save_as<M: ModelTrait>(cols: &[ModelColumn<M>], values: ValueTuple) -> Expr {\n    let values_expr_iter = values.into_iter().map(Expr::val);\n\n    let tuple_exprs: Vec<_> = cols\n        .iter()\n        .zip(values_expr_iter)\n        .map(|(model_column, value)| model_column.save_as(value))\n        .collect();\n\n    Expr::tuple(tuple_exprs)\n}\n\n#[cfg(test)]\nmod tests {\n    fn cake_model(id: i32) -> sea_orm::tests_cfg::cake::Model {\n        let name = match id {\n            1 => \"apple cake\",\n            2 => \"orange cake\",\n            3 => \"fruit cake\",\n            4 => \"chocolate cake\",\n            _ => \"\",\n        }\n        .to_string();\n        sea_orm::tests_cfg::cake::Model { id, name }\n    }\n\n    fn fruit_model(id: i32, cake_id: Option<i32>) -> sea_orm::tests_cfg::fruit::Model {\n        let name = match id {\n            1 => \"apple\",\n            2 => \"orange\",\n            3 => \"grape\",\n            4 => \"strawberry\",\n            _ => \"\",\n        }\n        .to_string();\n        sea_orm::tests_cfg::fruit::Model { id, name, cake_id }\n    }\n\n    fn filling_model(id: i32) -> sea_orm::tests_cfg::filling::Model {\n        let name = match id {\n            1 => \"apple juice\",\n            2 => \"orange jam\",\n            3 => \"chocolate crust\",\n            4 => \"strawberry jam\",\n            _ => \"\",\n        }\n        .to_string();\n        sea_orm::tests_cfg::filling::Model {\n            id,\n            name,\n            vendor_id: Some(1),\n            ignored_attr: 0,\n        }\n    }\n\n    fn cake_filling_model(\n        cake_id: i32,\n        filling_id: i32,\n    ) -> sea_orm::tests_cfg::cake_filling::Model {\n        sea_orm::tests_cfg::cake_filling::Model {\n            cake_id,\n            filling_id,\n        }\n    }\n\n    #[test]\n    fn test_load_one() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_model(1), cake_model(2)]])\n            .into_connection();\n\n        let fruits = vec![fruit_model(1, Some(1))];\n\n        let cakes = fruits\n            .load_one(cake::Entity::find(), &db)\n            .expect(\"Should return something\");\n\n        assert_eq!(cakes, [Some(cake_model(1))]);\n    }\n\n    #[test]\n    fn test_load_one_same_cake() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_model(1), cake_model(2)]])\n            .into_connection();\n\n        let fruits = vec![fruit_model(1, Some(1)), fruit_model(2, Some(1))];\n\n        let cakes = fruits\n            .load_one(cake::Entity::find(), &db)\n            .expect(\"Should return something\");\n\n        assert_eq!(cakes, [Some(cake_model(1)), Some(cake_model(1))]);\n    }\n\n    #[test]\n    fn test_load_one_empty() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_model(1), cake_model(2)]])\n            .into_connection();\n\n        let fruits: Vec<fruit::Model> = vec![];\n\n        let cakes = fruits\n            .load_one(cake::Entity::find(), &db)\n            .expect(\"Should return something\");\n\n        assert_eq!(cakes, []);\n    }\n\n    #[test]\n    fn test_load_many() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[fruit_model(1, Some(1))]])\n            .into_connection();\n\n        let cakes = vec![cake_model(1), cake_model(2)];\n\n        let fruits = cakes\n            .load_many(fruit::Entity::find(), &db)\n            .expect(\"Should return something\");\n\n        assert_eq!(fruits, [vec![fruit_model(1, Some(1))], vec![]]);\n    }\n\n    #[test]\n    fn test_load_many_same_fruit() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[fruit_model(1, Some(1)), fruit_model(2, Some(1))]])\n            .into_connection();\n\n        let cakes = vec![cake_model(1), cake_model(2)];\n\n        let fruits = cakes\n            .load_many(fruit::Entity::find(), &db)\n            .expect(\"Should return something\");\n\n        assert_eq!(\n            fruits,\n            [\n                vec![fruit_model(1, Some(1)), fruit_model(2, Some(1))],\n                vec![]\n            ]\n        );\n    }\n\n    #[test]\n    fn test_load_many_empty() {\n        use sea_orm::{DbBackend, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres).into_connection();\n\n        let cakes: Vec<cake::Model> = vec![];\n\n        let fruits = cakes\n            .load_many(fruit::Entity::find(), &db)\n            .expect(\"Should return something\");\n\n        let empty_vec: Vec<Vec<fruit::Model>> = vec![];\n\n        assert_eq!(fruits, empty_vec);\n    }\n\n    #[test]\n    fn test_load_many_to_many_base() {\n        use sea_orm::{DbBackend, IntoMockRow, LoaderTrait, MockDatabase, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([\n                [cake_filling_model(1, 1).into_mock_row()],\n                [filling_model(1).into_mock_row()],\n            ])\n            .into_connection();\n\n        let cakes = vec![cake_model(1)];\n\n        let fillings = cakes\n            .load_many_to_many(Filling, CakeFilling, &db)\n            .expect(\"Should return something\");\n\n        assert_eq!(fillings, vec![vec![filling_model(1)]]);\n    }\n\n    #[test]\n    fn test_load_many_to_many_complex() {\n        use sea_orm::{DbBackend, IntoMockRow, LoaderTrait, MockDatabase, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([\n                [\n                    cake_filling_model(1, 1).into_mock_row(),\n                    cake_filling_model(1, 2).into_mock_row(),\n                    cake_filling_model(1, 3).into_mock_row(),\n                    cake_filling_model(2, 1).into_mock_row(),\n                    cake_filling_model(2, 2).into_mock_row(),\n                ],\n                [\n                    filling_model(1).into_mock_row(),\n                    filling_model(2).into_mock_row(),\n                    filling_model(3).into_mock_row(),\n                    filling_model(4).into_mock_row(),\n                    filling_model(5).into_mock_row(),\n                ],\n            ])\n            .into_connection();\n\n        let cakes = vec![cake_model(1), cake_model(2), cake_model(3)];\n\n        let fillings = cakes\n            .load_many_to_many(Filling, CakeFilling, &db)\n            .expect(\"Should return something\");\n\n        assert_eq!(\n            fillings,\n            vec![\n                vec![filling_model(1), filling_model(2), filling_model(3)],\n                vec![filling_model(1), filling_model(2)],\n                vec![],\n            ]\n        );\n    }\n\n    #[test]\n    fn test_load_many_to_many_empty() {\n        use sea_orm::{DbBackend, IntoMockRow, LoaderTrait, MockDatabase, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([\n                [cake_filling_model(1, 1).into_mock_row()],\n                [filling_model(1).into_mock_row()],\n            ])\n            .into_connection();\n\n        let cakes: Vec<cake::Model> = vec![];\n\n        let fillings = cakes\n            .load_many_to_many(Filling, CakeFilling, &db)\n            .expect(\"Should return something\");\n\n        let empty_vec: Vec<Vec<filling::Model>> = vec![];\n\n        assert_eq!(fillings, empty_vec);\n    }\n\n    #[test]\n    fn test_load_one_duplicate_keys() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_model(1), cake_model(2)]])\n            .into_connection();\n\n        let fruits = vec![\n            fruit_model(1, Some(1)),\n            fruit_model(2, Some(1)),\n            fruit_model(3, Some(1)),\n            fruit_model(4, Some(1)),\n        ];\n\n        let cakes = fruits\n            .load_one(cake::Entity::find(), &db)\n            .expect(\"Should return something\");\n\n        assert_eq!(cakes.len(), 4);\n        for cake in &cakes {\n            assert_eq!(cake, &Some(cake_model(1)));\n        }\n        let logs = db.into_transaction_log();\n        let sql = format!(\"{:?}\", logs[0]);\n\n        let values_count = sql.matches(\"$1\").count();\n        assert_eq!(values_count, 1, \"Duplicate values were not removed\");\n    }\n\n    #[test]\n    fn test_load_many_duplicate_keys() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                fruit_model(1, Some(1)),\n                fruit_model(2, Some(1)),\n                fruit_model(3, Some(2)),\n            ]])\n            .into_connection();\n\n        let cakes = vec![cake_model(1), cake_model(1), cake_model(2), cake_model(2)];\n\n        let fruits = cakes\n            .load_many(fruit::Entity::find(), &db)\n            .expect(\"Should return something\");\n\n        assert_eq!(fruits.len(), 4);\n\n        let logs = db.into_transaction_log();\n        let sql = format!(\"{:?}\", logs[0]);\n\n        let values_count = sql.matches(\"$1\").count() + sql.matches(\"$2\").count();\n        assert_eq!(values_count, 2, \"Duplicate values were not removed\");\n    }\n\n    #[test]\n    fn test_assemble_vectors() {\n        use super::assemble_vectors;\n\n        assert_eq!(\n            assemble_vectors(&[vec![1], vec![], vec![2, 3], vec![]], vec![11, 22, 33]),\n            [vec![11], vec![], vec![22, 33], vec![]]\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/query/mod.rs",
    "content": "pub(crate) mod combine;\nmod debug;\nmod delete;\nmod helper;\nmod insert;\nmod join;\n#[cfg(feature = \"with-json\")]\nmod json;\nmod loader;\nmod select;\nmod traits;\nmod update;\nmod util;\n\npub use combine::{SelectA, SelectB, SelectC};\npub use debug::*;\npub use delete::*;\npub use helper::*;\npub use insert::*;\n#[cfg(feature = \"with-json\")]\npub use json::*;\npub use loader::*;\npub use select::*;\npub use traits::*;\npub use update::*;\npub(crate) use util::*;\n\npub use crate::{\n    ConnectionTrait, CursorTrait, InsertResult, PaginatorTrait, SelectExt, Statement, StreamTrait,\n    TransactionTrait, UpdateResult, Value, Values,\n};\npub use sea_query::ExprTrait;\n"
  },
  {
    "path": "sea-orm-sync/src/query/select.rs",
    "content": "use crate::{\n    ColumnTrait, EntityTrait, Iterable, Order, PrimaryKeyToColumn, QueryFilter, QueryOrder,\n    QuerySelect, QueryTrait,\n};\nuse core::fmt::Debug;\nuse core::marker::PhantomData;\nuse sea_query::{FunctionCall, IntoColumnRef, SelectStatement, SimpleExpr};\n\n/// Defines a structure to perform select operations\n#[derive(Clone, Debug)]\npub struct Select<E>\nwhere\n    E: EntityTrait,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<E>,\n    pub(crate) linked_index: usize,\n}\n\n/// Defines a structure to perform a SELECT operation on two Models\n#[derive(Clone, Debug)]\npub struct SelectTwo<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F)>,\n}\n\n/// Defines a structure to perform a SELECT operation on many Models\n#[derive(Clone, Debug)]\npub struct SelectTwoMany<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F)>,\n}\n\n/// Topology of multi-joins\npub trait Topology {}\n\n/// A star topology\n#[derive(Debug, Clone)]\npub struct TopologyStar;\n\n/// A chain topology\n#[derive(Debug, Clone)]\npub struct TopologyChain;\n\nimpl Topology for TopologyStar {}\nimpl Topology for TopologyChain {}\n\n/// Perform a SELECT operation on three Models\n#[derive(Clone, Debug)]\npub struct SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F, G, TOP)>,\n}\n\n/// Perform a SELECT operation on three Models with results consolidated\n#[derive(Clone, Debug)]\npub struct SelectThreeMany<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F, G, TOP)>,\n}\n\n/// Perform a SELECT operation on 4 Models\n#[derive(Clone, Debug)]\npub struct SelectFour<E, F, G, H, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F, G, H, TOP)>,\n}\n\n/// Perform a SELECT operation on 5 Models\n#[derive(Clone, Debug)]\npub struct SelectFive<E, F, G, H, I, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F, G, H, I, TOP)>,\n}\n\n/// Perform a SELECT operation on 6 Models\n#[derive(Clone, Debug)]\npub struct SelectSix<E, F, G, H, I, J, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    J: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F, G, H, I, J, TOP)>,\n}\n\n/// Performs a conversion to [SimpleExpr]\npub trait IntoSimpleExpr {\n    /// Method to perform the conversion\n    fn into_simple_expr(self) -> SimpleExpr;\n}\n\n/// Extending [IntoSimpleExpr] to support casting ActiveEnum as TEXT in select expression\npub trait ColumnAsExpr: IntoSimpleExpr {\n    /// Casting ActiveEnum as TEXT in select expression,\n    /// otherwise same as [IntoSimpleExpr::into_simple_expr]\n    fn into_column_as_expr(self) -> SimpleExpr;\n}\n\nmacro_rules! impl_query_trait {\n    ( $trait: ident ) => {\n        impl<E> $trait for Select<E>\n        where\n            E: EntityTrait,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n\n        impl<E, F> $trait for SelectTwo<E, F>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n\n        impl<E, F> $trait for SelectTwoMany<E, F>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n    };\n}\n\nimpl_query_trait!(QuerySelect);\nimpl_query_trait!(QueryFilter);\nimpl_query_trait!(QueryOrder);\n\nimpl<C> ColumnAsExpr for C\nwhere\n    C: ColumnTrait,\n{\n    fn into_column_as_expr(self) -> SimpleExpr {\n        self.select_as(self.as_column_ref().into_column_ref().into())\n    }\n}\n\nimpl ColumnAsExpr for SimpleExpr {\n    fn into_column_as_expr(self) -> SimpleExpr {\n        self.into_simple_expr()\n    }\n}\n\nimpl<C> IntoSimpleExpr for C\nwhere\n    C: ColumnTrait,\n{\n    fn into_simple_expr(self) -> SimpleExpr {\n        SimpleExpr::Column(self.as_column_ref().into_column_ref())\n    }\n}\n\nimpl IntoSimpleExpr for SimpleExpr {\n    fn into_simple_expr(self) -> SimpleExpr {\n        self\n    }\n}\n\nimpl IntoSimpleExpr for FunctionCall {\n    fn into_simple_expr(self) -> SimpleExpr {\n        SimpleExpr::FunctionCall(self)\n    }\n}\n\nimpl<E> Select<E>\nwhere\n    E: EntityTrait,\n{\n    pub(crate) fn new() -> Self {\n        Self {\n            query: SelectStatement::new(),\n            entity: PhantomData,\n            linked_index: 0,\n        }\n        .prepare_select()\n        .prepare_from()\n    }\n\n    fn prepare_select(mut self) -> Self {\n        self.query.exprs(self.column_list());\n        self\n    }\n\n    fn column_list(&self) -> Vec<SimpleExpr> {\n        E::Column::iter()\n            .map(|col| col.select_as(col.into_expr()))\n            .collect()\n    }\n\n    fn prepare_from(mut self) -> Self {\n        self.query.from(E::default().table_ref());\n        self\n    }\n\n    /// Apply order by primary key to the query statement\n    pub fn order_by_id_asc(self) -> Self {\n        self.order_by_id(Order::Asc)\n    }\n\n    /// Apply order by primary key to the query statement\n    pub fn order_by_id_desc(self) -> Self {\n        self.order_by_id(Order::Desc)\n    }\n\n    /// Apply order by primary key to the query statement\n    pub fn order_by_id(mut self, order: Order) -> Self {\n        for key in E::PrimaryKey::iter() {\n            let col = key.into_column();\n            self.query\n                .order_by_expr(col.into_simple_expr(), order.clone());\n        }\n        self\n    }\n}\n\nimpl<E> QueryTrait for Select<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = SelectStatement;\n    fn query(&mut self) -> &mut SelectStatement {\n        &mut self.query\n    }\n    fn as_query(&self) -> &SelectStatement {\n        &self.query\n    }\n    fn into_query(self) -> SelectStatement {\n        self.query\n    }\n}\n\nmacro_rules! select_two {\n    ( $selector: ident ) => {\n        impl<E, F> QueryTrait for $selector<E, F>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n        {\n            type QueryStatement = SelectStatement;\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n            fn as_query(&self) -> &SelectStatement {\n                &self.query\n            }\n            fn into_query(self) -> SelectStatement {\n                self.query\n            }\n        }\n    };\n}\n\nselect_two!(SelectTwo);\nselect_two!(SelectTwoMany);\n"
  },
  {
    "path": "sea-orm-sync/src/query/traits.rs",
    "content": "use crate::{DbBackend, Statement, StatementBuilder};\n\n/// A Trait for any type performing queries on a Model or ActiveModel\npub trait QueryTrait {\n    /// Constrain the QueryStatement to [StatementBuilder] trait\n    type QueryStatement: StatementBuilder;\n\n    /// Get a mutable ref to the query builder\n    fn query(&mut self) -> &mut Self::QueryStatement;\n\n    /// Get an immutable ref to the query builder\n    fn as_query(&self) -> &Self::QueryStatement;\n\n    /// Take ownership of the query builder\n    fn into_query(self) -> Self::QueryStatement;\n\n    /// Build the query as [`Statement`]\n    fn build(&self, db_backend: DbBackend) -> Statement {\n        StatementBuilder::build(self.as_query(), &db_backend)\n    }\n\n    /// Apply an operation on the [QueryTrait::QueryStatement] if the given `Option<T>` is `Some(_)`\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .apply_if(Some(3), |query, v| { query.filter(cake::Column::Id.eq(v)) })\n    ///         .apply_if(Some(100), QuerySelect::limit)\n    ///         .apply_if(None, QuerySelect::offset::<Option<u64>>) // no-op\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = 3 LIMIT 100\"#\n    /// );\n    /// ```\n    fn apply_if<T, F>(self, val: Option<T>, if_some: F) -> Self\n    where\n        Self: Sized,\n        F: FnOnce(Self, T) -> Self,\n    {\n        if let Some(val) = val {\n            if_some(self, val)\n        } else {\n            self\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/query/update.rs",
    "content": "use crate::{\n    ActiveModelTrait, ActiveValue, ColumnTrait, DbErr, EntityTrait, Iterable, PrimaryKeyToColumn,\n    QueryFilter, QueryTrait,\n};\nuse core::marker::PhantomData;\nuse sea_query::{Expr, IntoIden, SimpleExpr, UpdateStatement};\n\n/// Defines a structure to perform UPDATE query operations on a ActiveModel\n#[derive(Clone, Debug)]\npub struct Update;\n\n/// A request to update an [`ActiveModel`](ActiveModelTrait).\n///\n/// The primary key must be set.\n/// Otherwise, it's impossible to generate the SQL condition and find the record.\n/// In that case, [`exec`][Self::exec] will return an error and not send any queries to the database.\n///\n/// If you want to use [`QueryTrait`] and access the generated SQL query,\n/// you need to convert into [`ValidatedUpdateOne`] first.\n#[derive(Clone, Debug)]\npub struct UpdateOne<A: ActiveModelTrait>(pub(crate) Result<ValidatedUpdateOne<A>, DbErr>);\n\n/// A validated [`UpdateOne`] request, where the primary key is set\n/// and it's possible to generate the right SQL condition.\n#[derive(Clone, Debug)]\npub struct ValidatedUpdateOne<A: ActiveModelTrait> {\n    pub(crate) query: UpdateStatement,\n    pub(crate) model: A,\n}\n\nimpl<A: ActiveModelTrait> TryFrom<UpdateOne<A>> for ValidatedUpdateOne<A> {\n    type Error = DbErr;\n\n    fn try_from(value: UpdateOne<A>) -> Result<Self, Self::Error> {\n        value.0\n    }\n}\n\nimpl<A: ActiveModelTrait> UpdateOne<A> {\n    /// Check whether the primary key is set and we can proceed with the operation.\n    pub fn validate(self) -> Result<ValidatedUpdateOne<A>, DbErr> {\n        self.try_into()\n    }\n}\n\n/// Defines an UPDATE operation on multiple ActiveModels\n#[derive(Clone, Debug)]\npub struct UpdateMany<E>\nwhere\n    E: EntityTrait,\n{\n    pub(crate) query: UpdateStatement,\n    pub(crate) entity: PhantomData<E>,\n}\n\nimpl Update {\n    /// Update one ActiveModel\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     Update::one(cake::ActiveModel {\n    ///         id: ActiveValue::set(1),\n    ///         name: ActiveValue::set(\"Apple Pie\".to_owned()),\n    ///     })\n    ///     .validate()\n    ///     .unwrap()\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"UPDATE \"cake\" SET \"name\" = 'Apple Pie' WHERE \"cake\".\"id\" = 1\"#,\n    /// );\n    /// ```\n    //\n    // (non-doc comment for maintainers)\n    // Ideally, we would make this method fallible instead of stashing and delaying the error.\n    // But that's a bigger breaking change.\n    pub fn one<E, A>(model: A) -> UpdateOne<A>\n    where\n        E: EntityTrait,\n        A: ActiveModelTrait<Entity = E>,\n    {\n        let mut myself = ValidatedUpdateOne {\n            query: UpdateStatement::new()\n                .table(A::Entity::default().table_ref())\n                .to_owned(),\n            model,\n        };\n        // Build the SQL condition from the primary key columns.\n        for key in <A::Entity as EntityTrait>::PrimaryKey::iter() {\n            let col = key.into_column();\n            match myself.model.get(col) {\n                ActiveValue::Set(value) | ActiveValue::Unchanged(value) => {\n                    myself = myself.filter(col.eq(value));\n                }\n                ActiveValue::NotSet => {\n                    return UpdateOne(Err(DbErr::PrimaryKeyNotSet { ctx: \"UpdateOne\" }));\n                }\n            }\n        }\n        // Set the values to update (from the other columns).\n        for col in <A::Entity as EntityTrait>::Column::iter() {\n            if <A::Entity as EntityTrait>::PrimaryKey::from_column(col).is_some() {\n                continue;\n            }\n            match myself.model.get(col) {\n                ActiveValue::Set(value) => {\n                    let expr = col.save_as(Expr::val(value));\n                    myself.query.value(col, expr);\n                }\n                ActiveValue::Unchanged(_) | ActiveValue::NotSet => {}\n            }\n        }\n        UpdateOne(Ok(myself))\n    }\n\n    /// Update many ActiveModel\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, sea_query::Expr, tests_cfg::fruit};\n    ///\n    /// assert_eq!(\n    ///     Update::many(fruit::Entity)\n    ///         .col_expr(fruit::Column::Name, Expr::value(\"Golden Apple\"))\n    ///         .filter(fruit::Column::Name.contains(\"Apple\"))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"UPDATE \"fruit\" SET \"name\" = 'Golden Apple' WHERE \"fruit\".\"name\" LIKE '%Apple%'\"#,\n    /// );\n    /// ```\n    pub fn many<E>(entity: E) -> UpdateMany<E>\n    where\n        E: EntityTrait,\n    {\n        UpdateMany {\n            query: UpdateStatement::new().table(entity.table_ref()).to_owned(),\n            entity: PhantomData,\n        }\n    }\n}\n\nimpl<A> QueryFilter for ValidatedUpdateOne<A>\nwhere\n    A: ActiveModelTrait,\n{\n    type QueryStatement = UpdateStatement;\n\n    fn query(&mut self) -> &mut UpdateStatement {\n        &mut self.query\n    }\n}\n\nimpl<E> QueryFilter for UpdateMany<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = UpdateStatement;\n\n    fn query(&mut self) -> &mut UpdateStatement {\n        &mut self.query\n    }\n}\n\nimpl<A> QueryTrait for ValidatedUpdateOne<A>\nwhere\n    A: ActiveModelTrait,\n{\n    type QueryStatement = UpdateStatement;\n\n    fn query(&mut self) -> &mut UpdateStatement {\n        &mut self.query\n    }\n\n    fn as_query(&self) -> &UpdateStatement {\n        &self.query\n    }\n\n    fn into_query(self) -> UpdateStatement {\n        self.query\n    }\n}\n\nimpl<E> QueryTrait for UpdateMany<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = UpdateStatement;\n\n    fn query(&mut self) -> &mut UpdateStatement {\n        &mut self.query\n    }\n\n    fn as_query(&self) -> &UpdateStatement {\n        &self.query\n    }\n\n    fn into_query(self) -> UpdateStatement {\n        self.query\n    }\n}\n\nimpl<E> UpdateMany<E>\nwhere\n    E: EntityTrait,\n{\n    /// Add the models to update to Self\n    pub fn set<A>(mut self, model: A) -> Self\n    where\n        A: ActiveModelTrait<Entity = E>,\n    {\n        for col in E::Column::iter() {\n            match model.get(col) {\n                ActiveValue::Set(value) => {\n                    let expr = col.save_as(Expr::val(value));\n                    self.query.value(col, expr);\n                }\n                ActiveValue::Unchanged(_) | ActiveValue::NotSet => {}\n            }\n        }\n        self\n    }\n\n    /// Creates a [SimpleExpr] from a column\n    pub fn col_expr<T>(mut self, col: T, expr: SimpleExpr) -> Self\n    where\n        T: IntoIden,\n    {\n        self.query.value(col, expr);\n        self\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::{cake, fruit, lunch_set, sea_orm_active_enums::Tea};\n    use crate::{DbBackend, entity::*, query::*};\n    use sea_query::{Expr, Value};\n\n    #[test]\n    fn update_1() {\n        assert_eq!(\n            Update::one(cake::ActiveModel {\n                id: ActiveValue::set(1),\n                name: ActiveValue::set(\"Apple Pie\".to_owned()),\n            })\n            .validate()\n            .unwrap()\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"UPDATE \"cake\" SET \"name\" = 'Apple Pie' WHERE \"cake\".\"id\" = 1\"#,\n        );\n    }\n\n    #[test]\n    fn update_2() {\n        assert_eq!(\n            Update::one(fruit::ActiveModel {\n                id: ActiveValue::set(1),\n                name: ActiveValue::set(\"Orange\".to_owned()),\n                cake_id: ActiveValue::not_set(),\n            })\n            .validate()\n            .unwrap()\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"UPDATE \"fruit\" SET \"name\" = 'Orange' WHERE \"fruit\".\"id\" = 1\"#,\n        );\n    }\n\n    #[test]\n    fn update_3() {\n        assert_eq!(\n            Update::one(fruit::ActiveModel {\n                id: ActiveValue::set(2),\n                name: ActiveValue::unchanged(\"Apple\".to_owned()),\n                cake_id: ActiveValue::set(Some(3)),\n            })\n            .validate()\n            .unwrap()\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"UPDATE \"fruit\" SET \"cake_id\" = 3 WHERE \"fruit\".\"id\" = 2\"#,\n        );\n    }\n\n    #[test]\n    fn update_4() {\n        assert_eq!(\n            Update::many(fruit::Entity)\n                .col_expr(fruit::Column::CakeId, Expr::value(Value::Int(None)))\n                .filter(fruit::Column::Id.eq(2))\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"UPDATE \"fruit\" SET \"cake_id\" = NULL WHERE \"fruit\".\"id\" = 2\"#,\n        );\n    }\n\n    #[test]\n    fn update_5() {\n        assert_eq!(\n            Update::many(fruit::Entity)\n                .set(fruit::ActiveModel {\n                    name: ActiveValue::set(\"Apple\".to_owned()),\n                    cake_id: ActiveValue::set(Some(3)),\n                    ..Default::default()\n                })\n                .filter(fruit::Column::Id.eq(2))\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"UPDATE \"fruit\" SET \"name\" = 'Apple', \"cake_id\" = 3 WHERE \"fruit\".\"id\" = 2\"#,\n        );\n    }\n\n    #[test]\n    fn update_6() {\n        assert_eq!(\n            Update::many(fruit::Entity)\n                .set(fruit::ActiveModel {\n                    id: ActiveValue::set(3),\n                    ..Default::default()\n                })\n                .filter(fruit::Column::Id.eq(2))\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"UPDATE \"fruit\" SET \"id\" = 3 WHERE \"fruit\".\"id\" = 2\"#,\n        );\n    }\n\n    #[test]\n    fn update_7() {\n        assert_eq!(\n            Update::many(lunch_set::Entity)\n                .set(lunch_set::ActiveModel {\n                    tea: Set(Tea::EverydayTea),\n                    ..Default::default()\n                })\n                .filter(lunch_set::Column::Tea.eq(Tea::BreakfastTea))\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"UPDATE \"lunch_set\" SET \"tea\" = CAST('EverydayTea' AS \"tea\") WHERE \"lunch_set\".\"tea\" = (CAST('BreakfastTea' AS \"tea\"))\"#,\n        );\n    }\n\n    #[test]\n    fn update_8() {\n        assert_eq!(\n            Update::one(lunch_set::ActiveModel {\n                id: Unchanged(1),\n                tea: Set(Tea::EverydayTea),\n                ..Default::default()\n            })\n            .validate()\n            .unwrap()\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"UPDATE \"lunch_set\" SET \"tea\" = CAST('EverydayTea' AS \"tea\") WHERE \"lunch_set\".\"id\" = 1\"#,\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/query/util.rs",
    "content": "use crate::{\n    ActiveModelTrait, ColumnTrait, Condition, DbBackend, DbErr, EntityTrait, ExprTrait, IdenStatic,\n    Identity, ModelTrait, Value,\n};\nuse sea_query::{ColumnRef, DynIden, Expr, IntoColumnRef, TableRef, ValueTuple};\nuse std::str::FromStr;\n\n#[derive(Default)]\npub struct ValueTupleBuilder(Option<ValueTuple>);\n\nimpl ValueTupleBuilder {\n    pub fn push(&mut self, value: Value) {\n        match self.0.take() {\n            None => {\n                self.0 = Some(ValueTuple::One(value));\n            }\n            Some(ValueTuple::One(a)) => {\n                self.0 = Some(ValueTuple::Two(a, value));\n            }\n            Some(ValueTuple::Two(a, b)) => {\n                self.0 = Some(ValueTuple::Three(a, b, value));\n            }\n            Some(ValueTuple::Three(a, b, c)) => {\n                self.0 = Some(ValueTuple::Many(vec![a, b, c, value]));\n            }\n            Some(ValueTuple::Many(mut items)) => {\n                items.push(value);\n                self.0 = Some(ValueTuple::Many(items));\n            }\n        }\n    }\n\n    pub fn into_inner(self) -> Option<ValueTuple> {\n        self.0\n    }\n}\n\npub fn get_key_from_model<Model>(columns: &Identity, model: &Model) -> Result<ValueTuple, DbErr>\nwhere\n    Model: ModelTrait,\n{\n    let mut values = ValueTupleBuilder::default();\n\n    for col in columns.iter() {\n        let col_name = col.inner();\n        let column = <<Model::Entity as EntityTrait>::Column as FromStr>::from_str(&col_name)\n            .map_err(|_| DbErr::Type(format!(\"Failed at mapping '{col_name}' to column\")))?;\n        values.push(model.get(column));\n    }\n\n    match values.into_inner() {\n        Some(values) => Ok(values),\n        None => Err(DbErr::Type(\"Identity zero?\".into())),\n    }\n}\n\npub fn get_key_from_active_model<ActiveModel>(\n    columns: &Identity,\n    model: &ActiveModel,\n) -> Result<ValueTuple, DbErr>\nwhere\n    ActiveModel: ActiveModelTrait,\n{\n    let mut values = ValueTupleBuilder::default();\n\n    for col in columns.iter() {\n        let col_name = col.inner();\n        let column = <<ActiveModel::Entity as EntityTrait>::Column as FromStr>::from_str(&col_name)\n            .map_err(|_| DbErr::Type(format!(\"Failed at mapping '{col_name}' to column\")))?;\n        values.push(match model.get(column).into_value() {\n            Some(value) => value,\n            None => {\n                return Err(DbErr::AttrNotSet(format!(\n                    \"{}.{}\",\n                    <ActiveModel::Entity as Default>::default().as_str(),\n                    col_name\n                )));\n            }\n        });\n    }\n\n    match values.into_inner() {\n        Some(values) => Ok(values),\n        None => Err(DbErr::Type(\"Identity zero?\".into())),\n    }\n}\n\npub fn set_key_on_active_model<ActiveModel>(\n    columns: &Identity,\n    model: &mut ActiveModel,\n    values: ValueTuple,\n) -> Result<(), DbErr>\nwhere\n    ActiveModel: ActiveModelTrait,\n{\n    if values.arity() != columns.arity() {\n        return Err(DbErr::Type(format!(\n            \"Arity mismatch: {} != {}\",\n            values.arity(),\n            columns.arity(),\n        )));\n    }\n\n    for (column, value) in columns.iter().zip(values) {\n        let col_name = column.inner();\n        let column = <<ActiveModel::Entity as EntityTrait>::Column as FromStr>::from_str(&col_name)\n            .map_err(|_| DbErr::Type(format!(\"Failed at mapping '{col_name}' to column\")))?;\n        model.set_if_not_equals(column, value);\n    }\n\n    Ok(())\n}\n\n/// Set null on the key columns. Return true if succeeded, false if column is not nullable.\npub fn clear_key_on_active_model<ActiveModel>(\n    columns: &Identity,\n    model: &mut ActiveModel,\n) -> Result<bool, DbErr>\nwhere\n    ActiveModel: ActiveModelTrait,\n{\n    for col in columns.iter() {\n        let col_name = col.inner();\n        let column = <<ActiveModel::Entity as EntityTrait>::Column as FromStr>::from_str(&col_name)\n            .map_err(|_| DbErr::Type(format!(\"Failed at mapping '{col_name}' to column\")))?;\n        if !column.def().is_null() {\n            return Ok(false);\n        }\n        model.set(\n            column,\n            match model.get(column).into_value() {\n                Some(value) => value.as_null(),\n                None => {\n                    return Err(DbErr::AttrNotSet(format!(\n                        \"{}.{}\",\n                        <ActiveModel::Entity as Default>::default().as_str(),\n                        col_name\n                    )));\n                }\n            },\n        );\n    }\n\n    Ok(true)\n}\n\n/// Constructs a `WHERE (c1, c2, ...) IN ((v11, v12, ...), (v21, v22, ...), ...)` expression.\n/// Degenerates to `WHERE col IN (v1, v2, ...)` when arity = 1.\npub fn column_tuple_in_condition(\n    table: &TableRef,\n    to: &Identity,\n    keys: &[ValueTuple],\n    backend: DbBackend,\n) -> Result<Condition, DbErr> {\n    use itertools::Itertools;\n\n    let arity = to.arity();\n    let keys = keys.iter().unique();\n\n    if arity == 1 {\n        let values = keys\n            .map(|key| match key {\n                ValueTuple::One(v) => Ok(Expr::val(v.to_owned())),\n                _ => Err(arity_mismatch(arity, key)),\n            })\n            .collect::<Result<Vec<_>, DbErr>>()?;\n\n        let expr = Expr::col(table_column(\n            table,\n            to.iter().next().expect(\"Checked above\"),\n        ))\n        .is_in(values);\n\n        Ok(expr.into())\n    } else if cfg!(feature = \"sqlite-no-row-value-before-3_15\")\n        && matches!(backend, DbBackend::Sqlite)\n    {\n        // SQLite supports row value expressions since 3.15.0\n        // https://www.sqlite.org/releaselog/3_15_0.html\n\n        let table_columns = create_table_columns(table, to);\n\n        let mut outer = Condition::any();\n\n        for key in keys {\n            let key_arity = key.arity();\n            if arity != key_arity {\n                return Err(arity_mismatch(arity, key));\n            }\n\n            let table_columns = table_columns.iter().cloned();\n            let values = key.clone().into_iter().map(Expr::val);\n\n            let inner = table_columns\n                .zip(values)\n                .fold(Condition::all(), |cond, (column, value)| {\n                    cond.add(column.eq(value))\n                });\n\n            // Build `(c1 = v11 AND c2 = v12) OR (c1 = v21 AND c2 = v22) ...`\n            outer = outer.add(inner);\n        }\n\n        Ok(outer)\n    } else {\n        let table_columns = create_table_columns(table, to);\n\n        // A vector of tuples of values, e.g. [(v11, v12, ...), (v21, v22, ...), ...]\n        let value_tuples = keys\n            .map(|key| {\n                let key_arity = key.arity();\n                if arity != key_arity {\n                    return Err(arity_mismatch(arity, key));\n                }\n\n                let tuple_exprs = key.clone().into_iter().map(Expr::val);\n\n                Ok(Expr::tuple(tuple_exprs))\n            })\n            .collect::<Result<Vec<_>, DbErr>>()?;\n\n        // Build `(c1, c2, ...) IN ((v11, v12, ...), (v21, v22, ...), ...)`\n        let expr = Expr::tuple(table_columns).is_in(value_tuples);\n\n        Ok(expr.into())\n    }\n}\n\nfn arity_mismatch(expected: usize, actual: &ValueTuple) -> DbErr {\n    DbErr::Type(format!(\n        \"Loader: arity mismatch: expected {expected}, got {} in {actual:?}\",\n        actual.arity()\n    ))\n}\n\nfn table_column(tbl: &TableRef, col: &DynIden) -> ColumnRef {\n    (tbl.sea_orm_table().to_owned(), col.clone()).into_column_ref()\n}\n\n/// Create a vector of `Expr::col` from the table and identity, e.g. [Expr::col((table, col1)), Expr::col((table, col2)), ...]\nfn create_table_columns(table: &TableRef, cols: &Identity) -> Vec<Expr> {\n    cols.iter()\n        .map(|col| table_column(table, col))\n        .map(Expr::col)\n        .collect()\n}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/context.rs",
    "content": "use super::{\n    AccessType, RbacError, RbacUserId,\n    entity::{\n        permission::{self, ActiveModel as Permission, PermissionId},\n        resource::{self, ActiveModel as Resource, ResourceId},\n        role::{self, ActiveModel as Role, RoleId},\n        role_hierarchy::{self, ActiveModel as RoleHierarchy},\n        role_permission::{self, ActiveModel as RolePermission},\n        user_override::{self, ActiveModel as UserOverride},\n        user_role::{self, ActiveModel as UserRole},\n    },\n};\nuse crate::{\n    AccessMode, EntityTrait, IsolationLevel, Set, TransactionSession, TransactionTrait,\n    error::DbErr, sea_query::OnConflict,\n};\nuse std::collections::HashMap;\n\n/// Helper class for manipulation of RBAC tables\n#[derive(Debug)]\npub struct RbacContext {\n    tables: HashMap<String, ResourceId>,\n    permissions: HashMap<String, PermissionId>,\n    roles: HashMap<String, RoleId>,\n}\n\n#[derive(Debug)]\npub struct RbacAddRoleHierarchy {\n    pub super_role: &'static str,\n    pub role: &'static str,\n}\n\n#[derive(Debug)]\npub struct RbacAddUserOverride {\n    pub user_id: i64,\n    pub table: &'static str,\n    pub action: &'static str,\n    pub grant: bool,\n}\n\nimpl RbacContext {\n    /// Load context from database connection\n    pub fn load<C: TransactionTrait>(db: &C) -> Result<Self, DbErr> {\n        // ensure snapshot is consistent across all tables\n        let txn = &db.begin_with_config(\n            Some(IsolationLevel::ReadCommitted),\n            Some(AccessMode::ReadOnly),\n        )?;\n\n        let tables = resource::Entity::find()\n            .all(txn)?\n            .into_iter()\n            .map(|t| (t.table, t.id))\n            .collect();\n\n        let permissions = permission::Entity::find()\n            .all(txn)?\n            .into_iter()\n            .map(|p| (p.action, p.id))\n            .collect();\n\n        let roles = role::Entity::find()\n            .all(txn)?\n            .into_iter()\n            .map(|r| (r.role, r.id))\n            .collect();\n\n        Ok(Self {\n            tables,\n            permissions,\n            roles,\n        })\n    }\n\n    /// Add multiple tables as resources\n    pub fn add_tables<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        tables: &[&'static str],\n    ) -> Result<(), DbErr> {\n        let txn = db.begin()?;\n\n        for table_name in tables {\n            if let Some(table_id) = resource::Entity::insert(Resource {\n                table: Set(table_name.to_string()),\n                ..Default::default()\n            })\n            .on_conflict_do_nothing()\n            .exec(&txn)?\n            .last_insert_id()?\n            {\n                self.tables.insert(table_name.to_string(), table_id);\n            }\n        }\n\n        txn.commit()\n    }\n\n    /// Add CRUD actions\n    pub fn add_crud_permissions<C: TransactionTrait>(&mut self, db: &C) -> Result<(), DbErr> {\n        let txn = db.begin()?;\n\n        for action in [\n            AccessType::Select,\n            AccessType::Insert,\n            AccessType::Update,\n            AccessType::Delete,\n        ] {\n            if let Some(permission_id) = permission::Entity::insert(Permission {\n                action: Set(action.as_str().to_owned()),\n                ..Default::default()\n            })\n            .on_conflict_do_nothing()\n            .exec(&txn)?\n            .last_insert_id()?\n            {\n                self.permissions\n                    .insert(action.as_str().to_owned(), permission_id);\n            }\n        }\n\n        txn.commit()\n    }\n\n    /// Add multiple roles\n    pub fn add_roles<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        roles: &[&'static str],\n    ) -> Result<(), DbErr> {\n        let txn = db.begin()?;\n\n        for role in roles {\n            if let Some(role_id) = role::Entity::insert(Role {\n                role: Set(role.to_string()),\n                ..Default::default()\n            })\n            .on_conflict_do_nothing()\n            .exec(&txn)?\n            .last_insert_id()?\n            {\n                self.roles.insert(role.to_string(), role_id);\n            }\n        }\n\n        txn.commit()\n    }\n\n    pub fn get_role(&self, role: &'static str) -> Result<&RoleId, DbErr> {\n        self.roles\n            .get(role)\n            .ok_or_else(|| DbErr::RbacError(RbacError::RoleNotFound(role.to_string()).to_string()))\n    }\n\n    /// Add permissions to roles. Will take cartesian product of tables and actions.\n    pub fn add_role_permissions<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        role: &'static str,\n        actions: &[&'static str],\n        tables: &[&'static str],\n    ) -> Result<(), DbErr> {\n        self.update_role_permissions(db, role, actions, tables, true)\n    }\n\n    /// Remove permissions from roles. Will take cartesian product of tables and actions.\n    pub fn remove_role_permissions<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        role: &'static str,\n        actions: &[&'static str],\n        tables: &[&'static str],\n    ) -> Result<(), DbErr> {\n        self.update_role_permissions(db, role, actions, tables, false)\n    }\n\n    fn update_role_permissions<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        role: &'static str,\n        actions: &[&'static str],\n        tables: &[&'static str],\n        grant: bool,\n    ) -> Result<(), DbErr> {\n        let txn = db.begin()?;\n\n        for table_name in tables {\n            for action in actions {\n                let model = RolePermission {\n                    role_id: Set(*self.roles.get(role).ok_or_else(|| {\n                        DbErr::RbacError(RbacError::RoleNotFound(role.to_string()).to_string())\n                    })?),\n                    permission_id: Set(*self.permissions.get(*action).ok_or_else(|| {\n                        DbErr::RbacError(\n                            RbacError::PermissionNotFound(action.to_string()).to_string(),\n                        )\n                    })?),\n                    resource_id: Set(*self.tables.get(*table_name).ok_or_else(|| {\n                        DbErr::RbacError(\n                            RbacError::ResourceNotFound(table_name.to_string()).to_string(),\n                        )\n                    })?),\n                };\n                if grant {\n                    role_permission::Entity::insert(model)\n                        .on_conflict_do_nothing()\n                        .exec(&txn)?;\n                } else {\n                    role_permission::Entity::delete(model).exec(&txn)?;\n                }\n            }\n        }\n\n        txn.commit()\n    }\n\n    pub fn add_user_override<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        rows: &[RbacAddUserOverride],\n    ) -> Result<(), DbErr> {\n        let txn = db.begin()?;\n\n        for RbacAddUserOverride {\n            user_id,\n            table,\n            action,\n            grant,\n        } in rows\n        {\n            user_override::Entity::insert(UserOverride {\n                user_id: Set(RbacUserId(*user_id)),\n                permission_id: Set(*self.permissions.get(*action).ok_or_else(|| {\n                    DbErr::RbacError(RbacError::PermissionNotFound(action.to_string()).to_string())\n                })?),\n                resource_id: Set(*self.tables.get(*table).ok_or_else(|| {\n                    DbErr::RbacError(RbacError::ResourceNotFound(table.to_string()).to_string())\n                })?),\n                grant: Set(*grant),\n            })\n            .on_conflict(\n                OnConflict::columns([\n                    user_override::Column::UserId,\n                    user_override::Column::PermissionId,\n                    user_override::Column::ResourceId,\n                ])\n                .update_column(user_override::Column::Grant)\n                .to_owned(),\n            )\n            .try_insert()\n            .exec(&txn)?;\n        }\n\n        txn.commit()\n    }\n\n    pub fn add_role_hierarchy<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        rows: &[RbacAddRoleHierarchy],\n    ) -> Result<(), DbErr> {\n        let txn = db.begin()?;\n\n        for RbacAddRoleHierarchy { super_role, role } in rows {\n            role_hierarchy::Entity::insert(RoleHierarchy {\n                super_role_id: Set(*self.roles.get(*super_role).ok_or_else(|| {\n                    DbErr::RbacError(RbacError::RoleNotFound(super_role.to_string()).to_string())\n                })?),\n                role_id: Set(*self.roles.get(*role).ok_or_else(|| {\n                    DbErr::RbacError(RbacError::RoleNotFound(role.to_string()).to_string())\n                })?),\n            })\n            .on_conflict_do_nothing()\n            .exec(&txn)?;\n        }\n\n        txn.commit()\n    }\n\n    /// Assign role to users. Note that each user can only have 1 role,\n    /// so this assignment replaces current role.\n    /// `rows: (UserId, role)`\n    pub fn assign_user_role<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        rows: &[(i64, &'static str)],\n    ) -> Result<(), DbErr> {\n        let txn = db.begin()?;\n\n        for (user_id, role) in rows {\n            user_role::Entity::insert(UserRole {\n                user_id: Set(RbacUserId(*user_id)),\n                role_id: Set(*self.roles.get(*role).ok_or_else(|| {\n                    DbErr::RbacError(RbacError::RoleNotFound(role.to_string()).to_string())\n                })?),\n            })\n            .on_conflict(\n                OnConflict::column(user_role::Column::UserId)\n                    .update_column(user_role::Column::RoleId)\n                    .to_owned(),\n            )\n            .try_insert()\n            .exec(&txn)?;\n        }\n\n        txn.commit()\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/engine/loader.rs",
    "content": "use super::super::entity::{\n    permission::Entity as Permission, resource::Entity as Resource, role::Entity as Role,\n    role_hierarchy::Entity as RoleHierarchy, role_permission::Entity as RolePermission,\n    user_override::Entity as UserOverride, user_role::Entity as UserRole,\n};\nuse super::{RbacEngine, RbacSnapshot};\nuse crate::{AccessMode, DbConn, DbErr, EntityTrait, IsolationLevel, TransactionTrait};\n\nimpl RbacEngine {\n    pub fn load_from(db: &DbConn) -> Result<Self, DbErr> {\n        // ensure snapshot is consistent across all tables\n        let txn = &db.begin_with_config(\n            Some(IsolationLevel::ReadCommitted),\n            Some(AccessMode::ReadOnly),\n        )?;\n\n        let resources = Resource::find().all(txn)?;\n        let permissions = Permission::find().all(txn)?;\n        let roles = Role::find().all(txn)?;\n        let user_roles = UserRole::find().all(txn)?;\n        let role_permissions = RolePermission::find().all(txn)?;\n        let user_overrides = UserOverride::find().all(txn)?;\n        let role_hierarchy = RoleHierarchy::find().all(txn)?;\n\n        let snapshot = RbacSnapshot {\n            resources,\n            permissions,\n            roles,\n            user_roles,\n            role_permissions,\n            user_overrides,\n            role_hierarchy,\n        };\n\n        Ok(Self::from_snapshot(snapshot))\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/engine/mod.rs",
    "content": "use super::entity::{\n    permission::{Model as Permission, PermissionId},\n    resource::{Model as Resource, ResourceId},\n    role::{Model as Role, RoleId},\n    role_hierarchy::Model as RoleHierarchy,\n    role_permission::Model as RolePermission,\n    user::UserId,\n    user_override::Model as UserOverride,\n    user_role::Model as UserRole,\n};\nuse super::{Error, WILDCARD};\n\nmod loader;\nmod permission_request;\nmod resource_request;\nmod role_hierarchy_impl;\nmod snapshot;\n\npub use permission_request::*;\npub use resource_request::*;\nuse role_hierarchy_impl::*;\npub use snapshot::*;\n\nuse std::collections::{HashMap, HashSet};\n\npub struct RbacEngine {\n    resources: HashMap<ResourceRequest, Resource>,\n    permissions: HashMap<PermissionRequest, Permission>,\n    wildcard_resources: HashMap<ResourceId, Resource>,\n    wildcard_permissions: HashMap<PermissionId, Permission>,\n    roles: HashMap<RoleId, Role>,\n    user_roles: HashMap<UserId, RoleId>,\n    role_permissions: HashMap<RoleId, HashSet<(PermissionId, ResourceId)>>,\n    user_overrides: HashMap<UserId, Vec<UserOverride>>,\n    role_hierarchy: HashMap<RoleId, Vec<RoleId>>, // Role -> ChildRole\n}\n\nimpl std::fmt::Debug for RbacEngine {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"RbacEngine\")\n    }\n}\n\n#[derive(Debug, PartialEq, Eq)]\npub struct RbacUserRolePermissions {\n    pub role: Role,\n    pub resource_permissions: RbacPermissionsByResources,\n}\n\npub type RbacRolesAndRanks = Vec<(Role, u32)>;\n\npub type RbacRoleHierarchyList = Vec<RoleHierarchy>;\n\npub type RbacResourcesAndPermissions = (Vec<Resource>, Vec<Permission>);\n\npub type RbacPermissionsByResources = Vec<(Resource, Vec<Permission>)>;\n\nimpl RbacEngine {\n    pub fn from_snapshot(\n        RbacSnapshot {\n            resources: resources_rows,\n            permissions: permissions_rows,\n            roles: roles_rows,\n            user_roles: user_roles_rows,\n            role_permissions: role_permissions_rows,\n            user_overrides: user_overrides_rows,\n            role_hierarchy: role_hierarchy_rows,\n        }: RbacSnapshot,\n    ) -> Self {\n        let mut resources: HashMap<ResourceRequest, Resource> = Default::default();\n        let mut wildcard_resources = HashMap::new();\n        for resource in resources_rows {\n            if resource.schema.as_deref() == Some(WILDCARD) || resource.table == WILDCARD {\n                wildcard_resources.insert(resource.id, resource);\n            } else {\n                resources.insert(resource.clone().into(), resource);\n            }\n        }\n\n        let mut permissions: HashMap<PermissionRequest, Permission> = Default::default();\n        let mut wildcard_permissions = HashMap::new();\n        for permission in permissions_rows {\n            if permission.action == WILDCARD {\n                wildcard_permissions.insert(permission.id, permission);\n            } else {\n                permissions.insert(permission.clone().into(), permission);\n            }\n        }\n\n        let roles: HashMap<RoleId, Role> = roles_rows.into_iter().map(|r| (r.id, r)).collect();\n\n        let mut user_roles: HashMap<UserId, RoleId> = Default::default();\n        for user_role in user_roles_rows {\n            user_roles.insert(user_role.user_id, user_role.role_id);\n        }\n\n        let mut role_permissions: HashMap<RoleId, HashSet<(PermissionId, ResourceId)>> =\n            Default::default();\n        for rp in role_permissions_rows {\n            let set = role_permissions.entry(rp.role_id).or_default();\n            set.insert((rp.permission_id, rp.resource_id));\n        }\n\n        let mut user_overrides: HashMap<UserId, Vec<UserOverride>> = Default::default();\n        for user_override in user_overrides_rows {\n            user_overrides\n                .entry(user_override.user_id)\n                .or_default()\n                .push(user_override);\n        }\n\n        let mut role_hierarchy: HashMap<RoleId, Vec<RoleId>> = Default::default();\n        for rh in role_hierarchy_rows {\n            role_hierarchy\n                .entry(rh.super_role_id)\n                .or_default()\n                .push(rh.role_id);\n        }\n\n        RbacEngine {\n            resources,\n            permissions,\n            wildcard_resources,\n            wildcard_permissions,\n            roles,\n            user_roles,\n            role_permissions,\n            user_overrides,\n            role_hierarchy,\n        }\n    }\n\n    /// get user's role and walk the hierarchy, returning all assigned roles\n    fn get_user_role_ids(&self, user_id: &UserId) -> Result<HashSet<RoleId>, Error> {\n        if let Some(role) = self.user_roles.get(&user_id) {\n            let mut user_roles = HashSet::new();\n            for role in enumerate_role(*role, &self.role_hierarchy) {\n                if !self.roles.contains_key(&role) {\n                    return Err(Error::RoleNotFound(format!(\"{role:?}\")));\n                }\n                user_roles.insert(role);\n            }\n            Ok(user_roles)\n        } else {\n            Err(Error::UserNotFound(format!(\"{user_id:?}\")))\n        }\n    }\n\n    pub fn get_roles_and_ranks(&self) -> Result<RbacRolesAndRanks, Error> {\n        let mut all_roles = Vec::new();\n        for role_id in self.roles.keys() {\n            all_roles.push((\n                self.roles\n                    .get(role_id)\n                    .cloned()\n                    .ok_or_else(|| Error::RoleNotFound(format!(\"{role_id:?}\")))?,\n                enumerate_role(*role_id, &self.role_hierarchy).len() as u32,\n            ));\n        }\n        // descending rank but ascending role\n        all_roles.sort_by_key(|r| (-(r.1 as i64), r.0.id));\n        Ok(all_roles)\n    }\n\n    pub fn get_user_role_permissions(\n        &self,\n        user_id: UserId,\n    ) -> Result<RbacUserRolePermissions, Error> {\n        let mut user_roles: Vec<RoleId> = self.get_user_role_ids(&user_id)?.into_iter().collect();\n        user_roles.sort();\n\n        let mut role_permissions: HashSet<(PermissionId, ResourceId)> = Default::default();\n\n        for role_id in user_roles {\n            if let Some(items) = self.role_permissions.get(&role_id) {\n                role_permissions.extend(items.into_iter());\n            }\n        }\n\n        if let Some(user_overrides) = self.user_overrides.get(&user_id) {\n            for over in user_overrides {\n                let role_permission = (over.permission_id, over.resource_id);\n                if role_permissions.contains(&role_permission) {\n                    if !over.grant {\n                        role_permissions.remove(&role_permission);\n                    }\n                } else if over.grant {\n                    role_permissions.insert(role_permission);\n                }\n            }\n        }\n\n        Ok(RbacUserRolePermissions {\n            role: self\n                .roles\n                .get(&self.user_roles.get(&user_id).expect(\"Checked above\"))\n                .expect(\"Checked above\")\n                .to_owned(),\n            resource_permissions: self.group_permissions_by_resources(\n                role_permissions.into_iter().map(|(p, r)| (r, p)),\n            )?,\n        })\n    }\n\n    pub fn list_resources_and_permissions(&self) -> RbacResourcesAndPermissions {\n        (\n            self.resources\n                .values()\n                .chain(self.wildcard_resources.values())\n                .cloned()\n                .collect(),\n            self.permissions\n                .values()\n                .chain(self.wildcard_permissions.values())\n                .cloned()\n                .collect(),\n        )\n    }\n\n    pub fn list_role_hierarchy_edges(&self, role_id: RoleId) -> Vec<RoleHierarchy> {\n        list_role_hierarchy_edges(role_id, &self.role_hierarchy)\n    }\n\n    fn group_permissions_by_resources(\n        &self,\n        items: impl Iterator<Item = (ResourceId, PermissionId)>,\n    ) -> Result<RbacPermissionsByResources, Error> {\n        let mut map: HashMap<ResourceId, (Resource, Vec<Permission>)> = Default::default();\n\n        for item in items {\n            let permission = if let Some(p) = self.wildcard_permissions.get(&item.1) {\n                p\n            } else {\n                self.permissions\n                    .values()\n                    .find(|p| p.id == item.1)\n                    .ok_or_else(|| Error::PermissionNotFound(format!(\"{:?}\", item.1)))?\n            };\n\n            let resource = if let Some(r) = self.wildcard_resources.get(&item.0) {\n                r\n            } else {\n                self.resources\n                    .values()\n                    .find(|r| r.id == item.0)\n                    .ok_or_else(|| Error::ResourceNotFound(format!(\"{:?}\", item.0)))?\n            };\n\n            map.entry(item.0)\n                .or_insert_with(|| (resource.to_owned(), Default::default()))\n                .1\n                .push(permission.to_owned());\n        }\n\n        let mut vec: Vec<_> = map.into_values().collect();\n        vec.sort_by_key(|r| r.0.id);\n        vec.iter_mut().for_each(|r| r.1.sort_by_key(|p| p.id));\n        Ok(vec)\n    }\n\n    pub fn list_role_permissions_by_resources(\n        &self,\n        role_id: RoleId,\n    ) -> Result<RbacPermissionsByResources, Error> {\n        self.group_permissions_by_resources(\n            self.role_permissions\n                .get(&role_id)\n                .ok_or_else(|| Error::RoleNotFound(format!(\"{role_id:?}\")))?\n                .iter()\n                .map(|(p, r)| (*r, *p)),\n        )\n    }\n\n    pub fn user_can<P, R>(&self, user_id: UserId, permission: P, resource: R) -> Result<bool, Error>\n    where\n        P: Into<PermissionRequest>,\n        R: Into<ResourceRequest>,\n    {\n        let resource = resource.into();\n        let permission = permission.into();\n        let resource = self.resources.get(&resource);\n        let permission = self.permissions.get(&permission);\n\n        // get user roles and flatten hierarchy\n        let user_roles = self.get_user_role_ids(&user_id)?;\n\n        if let (Some(permission), Some(resource)) = (permission, resource) {\n            if let Some(user_overrides) = self.user_overrides.get(&user_id) {\n                for user_override in user_overrides {\n                    if user_override.permission_id == permission.id\n                        && user_override.resource_id == resource.id\n                    {\n                        return Ok(user_override.grant);\n                    }\n                }\n            }\n        }\n\n        for role_id in user_roles {\n            if let Some(role_permissions) = self.role_permissions.get(&role_id) {\n                if let (Some(permission), Some(resource)) = (permission, resource) {\n                    if role_permissions.contains(&(permission.id, resource.id)) {\n                        return Ok(true);\n                    }\n                }\n                for (permission_id, resource_id) in role_permissions {\n                    let is_wildcard_permission =\n                        self.is_wildcard_permission(*permission_id, permission);\n                    let is_wildcard_resource = self.is_wildcard_resource(*resource_id, resource);\n                    if let Some(resource) = &resource {\n                        if resource_id == &resource.id && is_wildcard_permission {\n                            return Ok(true);\n                        }\n                    }\n                    if let Some(permission) = &permission {\n                        if permission_id == &permission.id && is_wildcard_resource {\n                            return Ok(true);\n                        }\n                    }\n                    if is_wildcard_permission && is_wildcard_resource {\n                        return Ok(true);\n                    }\n                }\n            }\n        }\n\n        if resource.is_none() {\n            return Err(Error::ResourceNotFound(format!(\"{resource:?}\")));\n        }\n\n        if permission.is_none() {\n            return Err(Error::PermissionNotFound(format!(\"{permission:?}\")));\n        }\n\n        Ok(false)\n    }\n\n    fn is_wildcard_resource(&self, id: ResourceId, target: Option<&Resource>) -> bool {\n        if let Some(resource) = self.wildcard_resources.get(&id) {\n            if let Some(target) = target {\n                let schema_match = resource.schema.is_none()\n                    || resource.schema.as_ref().unwrap() == WILDCARD\n                    || resource.schema == target.schema;\n                let table_match = resource.table == WILDCARD || resource.table == target.table;\n                schema_match && table_match\n            } else {\n                (resource.schema.is_none() || resource.schema.as_ref().unwrap() == WILDCARD)\n                    && resource.table == WILDCARD\n            }\n        } else {\n            false\n        }\n    }\n\n    fn is_wildcard_permission(&self, id: PermissionId, _: Option<&Permission>) -> bool {\n        if let Some(permission) = self.wildcard_permissions.get(&id) {\n            return permission.action == WILDCARD;\n        }\n        false\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[allow(non_snake_case)]\n    fn Object(r: &str) -> Table<'_> {\n        Table(r)\n    }\n\n    fn resource(table: &str) -> Resource {\n        Resource {\n            id: ResourceId(0),\n            schema: None,\n            table: table.to_owned(),\n        }\n    }\n\n    fn permission(action: &str) -> Permission {\n        Permission {\n            id: PermissionId(0),\n            action: action.to_owned(),\n        }\n    }\n\n    fn role(role: &str) -> Role {\n        Role {\n            id: RoleId(0),\n            role: role.to_owned(),\n        }\n    }\n\n    fn seed_1() -> RbacSnapshot {\n        let mut snapshot = RbacSnapshot::default();\n        snapshot.set_resources(vec![\n            resource(\"book\"),\n            resource(\"paper\"),\n            resource(\"pen\"),\n            resource(\"*\"),\n        ]);\n        snapshot.set_permissions(vec![\n            permission(\"browse\"),  // read\n            permission(\"buy\"),     // create\n            permission(\"replace\"), // update\n            permission(\"dispose\"), // delete\n            permission(\"*\"),       // anything\n        ]);\n        snapshot.set_roles(vec![\n            role(\"admin\"),\n            role(\"manager\"),\n            role(\"clerk\"),\n            role(\"auditor\"),\n        ]);\n        snapshot.set_user_role(UserId(1), \"admin\");\n        snapshot.set_user_role(UserId(2), \"manager\");\n        snapshot.set_user_role(UserId(3), \"clerk\");\n        snapshot.set_user_role(UserId(4), \"auditor\");\n        snapshot.set_user_role(UserId(5), \"clerk\");\n\n        snapshot.add_role_hierarchy(\"manager\", \"admin\");\n        snapshot.add_role_hierarchy(\"clerk\", \"manager\");\n        snapshot.add_role_hierarchy(\"auditor\", \"admin\");\n\n        snapshot.add_role_permission(\"clerk\", Action(\"browse\"), Object(\"pen\"));\n        snapshot.add_role_permission(\"clerk\", Action(\"browse\"), Object(\"paper\"));\n        snapshot.add_role_permission(\"clerk\", Action(\"dispose\"), Object(\"paper\"));\n\n        snapshot.add_role_permission(\"manager\", Action(\"browse\"), Object(\"book\"));\n        snapshot.add_role_permission(\"manager\", Action(\"buy\"), Object(\"book\"));\n        snapshot.add_role_permission(\"manager\", Action(\"dispose\"), Object(\"book\"));\n        snapshot.add_role_permission(\"manager\", Action(\"replace\"), Object(\"paper\"));\n\n        snapshot.add_role_permission(\"auditor\", Action(\"browse\"), Object(\"*\"));\n\n        snapshot.add_user_override(UserId(5), Action(\"buy\"), Object(\"pen\"), true);\n        snapshot.add_user_override(UserId(5), Action(\"dispose\"), Object(\"paper\"), false);\n\n        snapshot.add_role_permission(\"admin\", Action(\"*\"), Object(\"*\"));\n\n        snapshot\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_rbac_engine_basic() {\n        let admin = UserId(1);\n        let manager = UserId(2);\n        let clerk = UserId(3);\n        let auditor = UserId(4);\n        let designer = UserId(5);\n\n        let engine = RbacEngine::from_snapshot(seed_1());\n\n        // anyone can use pen and paper\n        for item in [\"pen\", \"paper\"] {\n            assert!(engine.user_can(clerk, Action(\"browse\"), Object(item)).unwrap());\n            assert!(engine.user_can(manager, Action(\"browse\"), Object(item)).unwrap());\n            assert!(engine.user_can(admin, Action(\"browse\"), Object(item)).unwrap());\n            // auditor can browse anything\n            assert!(engine.user_can(auditor, Action(\"browse\"), Object(item)).unwrap());\n        }\n\n        // anyone can dispose paper except auditor and designer\n        for user in [clerk, manager, admin] {\n            assert!(engine.user_can(user, Action(\"dispose\"), Object(\"paper\")).unwrap());\n        }\n        for user in [designer, auditor] {\n            assert!(!engine.user_can(user, Action(\"dispose\"), Object(\"paper\")).unwrap());\n        }\n\n        // clerk cannot browse books\n        for user in [clerk, designer] {\n            assert!(!engine.user_can(user, Action(\"browse\"), Object(\"book\")).unwrap());\n        }\n\n        for user in [admin, manager] {\n            assert!(engine.user_can(user, Action(\"browse\"), Object(\"book\")).unwrap());\n            assert!(engine.user_can(user, Action(\"buy\"), Object(\"book\")).unwrap());\n            assert!(engine.user_can(user, Action(\"dispose\"), Object(\"book\")).unwrap());\n        }\n\n        // auditor cannot alter things\n        for action in [\"buy\", \"replace\", \"dispose\"] {\n            for item in [\"book\", \"paper\", \"pen\"] {\n                assert!(!engine.user_can(auditor, Action(action), Object(item)).unwrap());\n            }\n        }\n\n        // manager cannot replace books, but admin can\n        assert!(!engine.user_can(manager, Action(\"replace\"), Object(\"book\")).unwrap());\n        assert!(engine.user_can(admin, Action(\"replace\"), Object(\"book\")).unwrap());\n\n        // manager can replace paper\n        assert!(!engine.user_can(clerk, Action(\"replace\"), Object(\"paper\")).unwrap());\n        assert!(!engine.user_can(designer, Action(\"replace\"), Object(\"paper\")).unwrap());\n        assert!(engine.user_can(manager, Action(\"replace\"), Object(\"paper\")).unwrap());\n        assert!(engine.user_can(admin, Action(\"replace\"), Object(\"paper\")).unwrap());\n\n        // only admin can buy paper\n        for user in [clerk, manager, designer] {\n            assert!(!engine.user_can(user, Action(\"buy\"), Object(\"paper\")).unwrap());\n        }\n        assert!(engine.user_can(admin, Action(\"buy\"), Object(\"paper\")).unwrap());\n\n        // designer has an exception can buy pen\n        for user in [designer, admin] {\n            assert!(engine.user_can(user, Action(\"buy\"), Object(\"pen\")).unwrap());\n        }\n        for user in [clerk, manager] {\n            assert!(!engine.user_can(user, Action(\"buy\"), Object(\"pen\")).unwrap());\n        }\n\n        // only admin can replace / dispose pen\n        for action in [\"replace\", \"dispose\"] {\n            assert!(engine.user_can(admin, Action(action), Object(\"pen\")).unwrap());\n        }\n\n        // unknown action / object; admin has wildcard\n        assert!(engine.user_can(admin, Action(\"?\"), Object(\"?\")).is_ok());\n        assert!(engine.user_can(manager, Action(\"?\"), Object(\"?\")).is_err());\n        assert!(engine.user_can(clerk, Action(\"?\"), Object(\"?\")).is_err());\n\n        assert_eq!(engine.get_user_role_permissions(clerk).unwrap(), RbacUserRolePermissions {\n            role: Role {\n                id: RoleId(3),\n                role: \"clerk\".to_owned(),\n            },\n            resource_permissions: vec![\n                (\n                    Resource { id: ResourceId(2), schema: None, table: \"paper\".to_owned() },\n                    vec![\n                        Permission { id: PermissionId(1), action: \"browse\".to_owned() },\n                        Permission { id: PermissionId(4), action: \"dispose\".to_owned() },\n                    ]\n                ),\n                (\n                    Resource { id: ResourceId(3), schema: None, table: \"pen\".to_owned() },\n                    vec![Permission { id: PermissionId(1), action: \"browse\".to_owned() }]\n                ),\n            ],\n        });\n\n        assert_eq!(engine.get_user_role_permissions(designer).unwrap(), RbacUserRolePermissions {\n            role: Role {\n                id: RoleId(3),\n                role: \"clerk\".to_owned(),\n            },\n            resource_permissions: vec![\n                (\n                    Resource { id: ResourceId(2), schema: None, table: \"paper\".to_owned() },\n                    vec![Permission { id: PermissionId(1), action: \"browse\".to_owned() }]\n                ),\n                (\n                    Resource { id: ResourceId(3), schema: None, table: \"pen\".to_owned() },\n                    vec![\n                        Permission { id: PermissionId(1), action: \"browse\".to_owned() },\n                        Permission { id: PermissionId(2), action: \"buy\".to_owned() },\n                    ]\n                ),\n            ],\n        });\n\n        assert_eq!(engine.get_roles_and_ranks().unwrap(), vec![\n            (Role { id: RoleId(1), role: \"admin\".to_owned()   }, 4), // <- manager | auditor\n            (Role { id: RoleId(2), role: \"manager\".to_owned() }, 2), // <- clerk\n            (Role { id: RoleId(3), role: \"clerk\".to_owned()   }, 1), //\n            (Role { id: RoleId(4), role: \"auditor\".to_owned() }, 1), //\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(1)), vec![\n            RoleHierarchy { super_role_id: RoleId(1), role_id: RoleId(2) },\n            RoleHierarchy { super_role_id: RoleId(1), role_id: RoleId(4) },\n            RoleHierarchy { super_role_id: RoleId(2), role_id: RoleId(3) },\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(2)), vec![\n            RoleHierarchy { super_role_id: RoleId(2), role_id: RoleId(3) },\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(3)), vec![]);\n\n        assert_eq!(engine.list_role_permissions_by_resources(RoleId(2)).unwrap(), vec![\n            (Resource { id: ResourceId(1), schema: None, table: \"book\".into() }, vec![\n                Permission { id: PermissionId(1), action: \"browse\".into() },\n                Permission { id: PermissionId(2), action: \"buy\".into() },\n                Permission { id: PermissionId(4), action: \"dispose\".into() },\n            ]),\n            (Resource { id: ResourceId(2), schema: None, table: \"paper\".into() }, vec![\n                Permission { id: PermissionId(3), action: \"replace\".into() },\n            ]),\n        ]);\n\n        assert_eq!(engine.list_role_permissions_by_resources(RoleId(4)).unwrap(), vec![\n            (Resource { id: ResourceId(4), schema: None, table: \"*\".into() }, vec![\n                Permission { id: PermissionId(1), action: \"browse\".into() },\n            ]),\n        ]);\n    }\n\n    #[rustfmt::skip]\n    fn seed_2() -> RbacSnapshot {\n        fn resource(schema: &str, table: &str) -> Resource {\n            Resource {\n                id: ResourceId(0),\n                schema: Some(schema.to_owned()),\n                table: table.to_owned(),\n            }\n        }\n\n        let mut snapshot = RbacSnapshot::default();\n        snapshot.set_resources(vec![\n            resource(\"departmentA\", \"book\"),\n            resource(\"departmentB\", \"book\"),\n            resource(\"departmentB\", \"CD\"),\n            resource(\"*\", \"book\"),\n            resource(\"departmentB\", \"*\"),\n            resource(\"*\", \"*\"),\n        ]);\n        snapshot.set_permissions(vec![\n            permission(\"browse\"),\n        ]);\n        snapshot.set_roles(vec![\n            role(\"silver\"),\n            role(\"gold\"),\n            role(\"platinum\"),\n            role(\"reader\"),\n            role(\"admin\"),\n        ]);\n        snapshot.set_user_role(UserId(1), \"silver\");\n        snapshot.set_user_role(UserId(2), \"gold\");\n        snapshot.set_user_role(UserId(3), \"platinum\");\n        snapshot.set_user_role(UserId(4), \"reader\");\n        snapshot.set_user_role(UserId(5), \"admin\");\n\n        snapshot.add_role_permission(\"silver\", Action(\"browse\"), SchemaTable(\"departmentA\", \"book\"));\n        snapshot.add_role_permission(\"gold\", Action(\"browse\"), SchemaTable(\"departmentB\", \"book\"));\n        snapshot.add_role_permission(\"platinum\", Action(\"browse\"), SchemaTable(\"departmentA\", \"book\"));\n        snapshot.add_role_permission(\"platinum\", Action(\"browse\"), SchemaTable(\"departmentB\", \"*\"));\n\n        snapshot.add_role_permission(\"reader\", Action(\"browse\"), SchemaTable(\"*\", \"book\"));\n\n        snapshot.add_role_permission(\"admin\", Action(\"browse\"), SchemaTable(\"*\", \"*\"));\n\n        snapshot\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_rbac_engine_wildcard() {\n        let silver = UserId(1);\n        let gold = UserId(2);\n        let platinum = UserId(3);\n        let reader = UserId(4);\n        let admin = UserId(5);\n\n        let engine = RbacEngine::from_snapshot(seed_2());\n\n        assert!(engine.user_can(silver, Action(\"browse\"), SchemaTable(\"departmentA\", \"book\")).unwrap());\n        assert!(!engine.user_can(silver, Action(\"browse\"), SchemaTable(\"departmentB\", \"book\")).unwrap());\n        assert!(!engine.user_can(silver, Action(\"browse\"), SchemaTable(\"departmentB\", \"CD\")).unwrap());\n\n        assert!(!engine.user_can(gold, Action(\"browse\"), SchemaTable(\"departmentA\", \"book\")).unwrap());\n        assert!(engine.user_can(gold, Action(\"browse\"), SchemaTable(\"departmentB\", \"book\")).unwrap());\n        assert!(!engine.user_can(gold, Action(\"browse\"), SchemaTable(\"departmentB\", \"CD\")).unwrap());\n\n        assert!(engine.user_can(platinum, Action(\"browse\"), SchemaTable(\"departmentA\", \"book\")).unwrap());\n        assert!(engine.user_can(platinum, Action(\"browse\"), SchemaTable(\"departmentB\", \"book\")).unwrap());\n        assert!(engine.user_can(platinum, Action(\"browse\"), SchemaTable(\"departmentB\", \"CD\")).unwrap());\n\n        assert!(engine.user_can(reader, Action(\"browse\"), SchemaTable(\"departmentA\", \"book\")).unwrap());\n        assert!(engine.user_can(reader, Action(\"browse\"), SchemaTable(\"departmentB\", \"book\")).unwrap());\n        assert!(!engine.user_can(reader, Action(\"browse\"), SchemaTable(\"departmentB\", \"CD\")).unwrap());\n\n        assert!(engine.user_can(admin, Action(\"browse\"), SchemaTable(\"departmentA\", \"book\")).unwrap());\n        assert!(engine.user_can(admin, Action(\"browse\"), SchemaTable(\"departmentB\", \"book\")).unwrap());\n        assert!(engine.user_can(admin, Action(\"browse\"), SchemaTable(\"departmentB\", \"CD\")).unwrap());\n    }\n\n    #[rustfmt::skip]\n    fn seed_3() -> RbacSnapshot {\n        let mut snapshot = RbacSnapshot::default();\n        snapshot.set_resources(vec![\n            resource(\"book\"),\n            resource(\"CD\"),\n            resource(\"magazine\"),\n        ]);\n        snapshot.set_permissions(vec![\n            permission(\"browse\"),\n        ]);\n        snapshot.set_roles(vec![\n            role(\"A\"),\n            role(\"B\"),\n            role(\"C\"),\n            role(\"A+B\"),\n            role(\"A+C\"),\n            role(\"A+B+C\"),\n            role(\"(A+B)+C\"),\n        ]);\n        snapshot.set_user_role(UserId(1), \"A\");\n        snapshot.set_user_role(UserId(2), \"B\");\n        snapshot.set_user_role(UserId(3), \"C\");\n        snapshot.set_user_role(UserId(4), \"A+B\");\n        snapshot.set_user_role(UserId(5), \"A+C\");\n        snapshot.set_user_role(UserId(6), \"A+B+C\");\n        snapshot.set_user_role(UserId(7), \"(A+B)+C\");\n\n        snapshot.add_role_permission(\"A\", Action(\"browse\"), Object(\"book\"));\n        snapshot.add_role_permission(\"B\", Action(\"browse\"), Object(\"CD\"));\n        snapshot.add_role_permission(\"C\", Action(\"browse\"), Object(\"magazine\"));\n\n        snapshot.add_role_hierarchy(\"A\", \"A+B\");\n        snapshot.add_role_hierarchy(\"B\", \"A+B\");\n\n        snapshot.add_role_hierarchy(\"A\", \"A+C\");\n        snapshot.add_role_hierarchy(\"C\", \"A+C\");\n\n        snapshot.add_role_hierarchy(\"A\", \"A+B+C\");\n        snapshot.add_role_hierarchy(\"B\", \"A+B+C\");\n        snapshot.add_role_hierarchy(\"C\", \"A+B+C\");\n\n        snapshot.add_role_hierarchy(\"A+B\", \"(A+B)+C\");\n        snapshot.add_role_hierarchy(\"C\", \"(A+B)+C\");\n\n        snapshot\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    #[allow(non_snake_case)]\n    fn test_rbac_engine_hierarchy() {\n        let A = UserId(1);\n        let B = UserId(2);\n        let C = UserId(3);\n        let A_B = UserId(4);\n        let A_C = UserId(5);\n        let A_B_C = UserId(6);\n        let A_B_C_ = UserId(7);\n\n        let engine = RbacEngine::from_snapshot(seed_3());\n\n        assert!(engine.user_can(A, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(!engine.user_can(A, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(!engine.user_can(A, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert!(!engine.user_can(B, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(engine.user_can(B, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(!engine.user_can(B, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert!(!engine.user_can(C, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(!engine.user_can(C, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(engine.user_can(C, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert!(engine.user_can(A_B, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(engine.user_can(A_B, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(!engine.user_can(A_B, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert!(engine.user_can(A_C, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(!engine.user_can(A_C, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(engine.user_can(A_C, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert!(engine.user_can(A_B_C, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(engine.user_can(A_B_C, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(engine.user_can(A_B_C, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert!(engine.user_can(A_B_C_, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(engine.user_can(A_B_C_, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(engine.user_can(A_B_C_, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert_eq!(engine.get_roles_and_ranks().unwrap(), vec![\n            (Role { id: RoleId(7), role: \"(A+B)+C\".into() }, 5),\n            (Role { id: RoleId(6), role: \"A+B+C\".into() }, 4),\n            (Role { id: RoleId(4), role: \"A+B\".into() }, 3),\n            (Role { id: RoleId(5), role: \"A+C\".into() }, 3),\n            (Role { id: RoleId(1), role: \"A\".into() }, 1),\n            (Role { id: RoleId(2), role: \"B\".into() }, 1),\n            (Role { id: RoleId(3), role: \"C\".into() }, 1),\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(1)), vec![]);\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(2)), vec![]);\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(3)), vec![]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(4)), vec![\n            RoleHierarchy { super_role_id: RoleId(4), role_id: RoleId(1) },\n            RoleHierarchy { super_role_id: RoleId(4), role_id: RoleId(2) },\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(5)), vec![\n            RoleHierarchy { super_role_id: RoleId(5), role_id: RoleId(1) },\n            RoleHierarchy { super_role_id: RoleId(5), role_id: RoleId(3) },\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(6)), vec![\n            RoleHierarchy { super_role_id: RoleId(6), role_id: RoleId(1) },\n            RoleHierarchy { super_role_id: RoleId(6), role_id: RoleId(2) },\n            RoleHierarchy { super_role_id: RoleId(6), role_id: RoleId(3) },\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(7)), vec![\n            RoleHierarchy { super_role_id: RoleId(7), role_id: RoleId(4) },\n            RoleHierarchy { super_role_id: RoleId(7), role_id: RoleId(3) },\n            RoleHierarchy { super_role_id: RoleId(4), role_id: RoleId(1) },\n            RoleHierarchy { super_role_id: RoleId(4), role_id: RoleId(2) },\n        ]);\n    }\n\n    #[test]\n    fn test_unrestricted() {\n        let engine = RbacEngine::from_snapshot(RbacSnapshot::danger_unrestricted());\n        assert!(\n            engine\n                .user_can(UserId(0), Action(\"browse\"), Object(\"book\"))\n                .unwrap()\n        );\n        assert_eq!(\n            engine.get_user_role_permissions(UserId(0)).unwrap(),\n            RbacUserRolePermissions {\n                role: Role {\n                    id: RoleId(1),\n                    role: \"unrestricted\".to_owned(),\n                },\n                resource_permissions: vec![(\n                    Resource {\n                        id: ResourceId(1),\n                        schema: None,\n                        table: \"*\".to_owned(),\n                    },\n                    vec![Permission {\n                        id: PermissionId(1),\n                        action: \"*\".to_owned(),\n                    }]\n                ),],\n            }\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/engine/permission_request.rs",
    "content": "use crate::rbac::entity::permission::Model as Permission;\n\n#[derive(Debug)]\npub struct Action<'a>(pub &'a str);\n\n#[derive(Debug, Clone, PartialEq, Eq, Hash)]\npub struct PermissionRequest {\n    pub action: String,\n}\n\nimpl<'a> From<Action<'a>> for PermissionRequest {\n    fn from(action: Action<'a>) -> PermissionRequest {\n        PermissionRequest {\n            action: action.0.to_owned(),\n        }\n    }\n}\n\nimpl From<Permission> for PermissionRequest {\n    fn from(permission: Permission) -> Self {\n        Self {\n            action: permission.action,\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/engine/resource_request.rs",
    "content": "use crate::rbac::entity::resource::Model as Resource;\n\n#[derive(Debug)]\npub struct Table<'a>(pub &'a str);\n\n#[derive(Debug)]\npub struct SchemaTable<'a, 'b>(pub &'a str, pub &'b str);\n\n#[derive(Debug, Clone, PartialEq, Eq, Hash)]\npub struct ResourceRequest {\n    pub schema: Option<String>,\n    pub table: String,\n}\n\nimpl<'a> From<Table<'a>> for ResourceRequest {\n    fn from(table: Table<'a>) -> ResourceRequest {\n        ResourceRequest {\n            schema: None,\n            table: table.0.to_owned(),\n        }\n    }\n}\n\nimpl<'a, 'b> From<SchemaTable<'a, 'b>> for ResourceRequest {\n    fn from(schema_table: SchemaTable<'a, 'b>) -> ResourceRequest {\n        ResourceRequest {\n            schema: Some(schema_table.0.to_owned()),\n            table: schema_table.1.to_owned(),\n        }\n    }\n}\n\nimpl From<Resource> for ResourceRequest {\n    fn from(resource: Resource) -> Self {\n        Self {\n            schema: resource.schema,\n            table: resource.table,\n        }\n    }\n}\n\nimpl std::fmt::Display for ResourceRequest {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(\n            f,\n            \"{}{}{}\",\n            if let Some(schema) = &self.schema {\n                schema\n            } else {\n                \"\"\n            },\n            if self.schema.is_some() { \".\" } else { \"\" },\n            self.table\n        )\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/engine/role_hierarchy_impl.rs",
    "content": "use super::{RoleHierarchy, RoleId};\nuse std::collections::{HashMap, HashSet, VecDeque};\n\n/// Role -> [ChildRole]\npub type RoleHierarchyMap = HashMap<RoleId, Vec<RoleId>>;\n\n/// walk the hierarchy tree and enumerate all the children roles given a role.\n/// this is a non-recursive tree walk impl.\npub fn enumerate_role(role: RoleId, role_hierarchy: &RoleHierarchyMap) -> Vec<RoleId> {\n    let mut roles = Vec::new();\n    let mut queue = VecDeque::new();\n    let mut seen = HashSet::new();\n\n    queue.push_back(role);\n    seen.insert(role);\n\n    while let Some(role) = queue.pop_front() {\n        roles.push(role);\n        if let Some(children) = role_hierarchy.get(&role) {\n            for child in children {\n                if !seen.contains(child) {\n                    queue.push_back(*child);\n                }\n            }\n        }\n    }\n\n    roles\n}\n\n/// walk the hierarchy tree and enumerate all the children roles given a role.\n/// return the edges instead.\npub fn list_role_hierarchy_edges(\n    role: RoleId,\n    role_hierarchy: &RoleHierarchyMap,\n) -> Vec<RoleHierarchy> {\n    let mut edges = Vec::new();\n    let mut roles = Vec::new();\n    let mut queue = VecDeque::new();\n    let mut seen = HashSet::new();\n\n    queue.push_back(role);\n    seen.insert(role);\n\n    while let Some(role) = queue.pop_front() {\n        roles.push(role);\n        if let Some(children) = role_hierarchy.get(&role) {\n            for child in children {\n                if !seen.contains(child) {\n                    queue.push_back(*child);\n                }\n                edges.push(RoleHierarchy {\n                    super_role_id: role,\n                    role_id: *child,\n                });\n            }\n        }\n    }\n\n    edges\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn test_enumerate_role() {\n        let role_hierarchy = [\n            (RoleId(1), vec![RoleId(2)]),\n            (RoleId(2), vec![RoleId(3), RoleId(4)]),\n            (RoleId(4), vec![RoleId(5)]),\n            (RoleId(6), vec![]),\n        ]\n        .into_iter()\n        .collect();\n\n        assert_eq!(\n            enumerate_role(RoleId(1), &role_hierarchy),\n            [RoleId(1), RoleId(2), RoleId(3), RoleId(4), RoleId(5)]\n        );\n        assert_eq!(\n            enumerate_role(RoleId(2), &role_hierarchy),\n            [RoleId(2), RoleId(3), RoleId(4), RoleId(5)]\n        );\n        assert_eq!(enumerate_role(RoleId(3), &role_hierarchy), [RoleId(3)]);\n        assert_eq!(\n            enumerate_role(RoleId(4), &role_hierarchy),\n            [RoleId(4), RoleId(5)]\n        );\n        assert_eq!(enumerate_role(RoleId(5), &role_hierarchy), [RoleId(5)]);\n        assert_eq!(enumerate_role(RoleId(6), &role_hierarchy), [RoleId(6)]);\n        assert_eq!(enumerate_role(RoleId(7), &role_hierarchy), [RoleId(7)]);\n    }\n\n    #[test]\n    fn test_enumerate_role_cyclic() {\n        let role_hierarchy = [\n            (RoleId(1), vec![RoleId(2)]),\n            (RoleId(2), vec![RoleId(3)]),\n            (RoleId(3), vec![RoleId(1), RoleId(4)]),\n        ]\n        .into_iter()\n        .collect();\n\n        assert_eq!(\n            enumerate_role(RoleId(1), &role_hierarchy),\n            [RoleId(1), RoleId(2), RoleId(3), RoleId(4)]\n        );\n        assert_eq!(\n            enumerate_role(RoleId(2), &role_hierarchy),\n            [RoleId(2), RoleId(3), RoleId(1), RoleId(4)]\n        );\n        assert_eq!(\n            enumerate_role(RoleId(3), &role_hierarchy),\n            [RoleId(3), RoleId(1), RoleId(4), RoleId(2)]\n        );\n        assert_eq!(enumerate_role(RoleId(4), &role_hierarchy), [RoleId(4)]);\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/engine/snapshot.rs",
    "content": "use super::*;\n\n#[derive(Debug, Default)]\npub struct RbacSnapshot {\n    pub(super) resources: Vec<Resource>,\n    pub(super) permissions: Vec<Permission>,\n    pub(super) roles: Vec<Role>,\n    pub(super) user_roles: Vec<UserRole>,\n    pub(super) role_permissions: Vec<RolePermission>,\n    pub(super) user_overrides: Vec<UserOverride>,\n    pub(super) role_hierarchy: Vec<RoleHierarchy>,\n}\n\nimpl RbacSnapshot {\n    /// Create an unrestricted system where `UserId(0)` can perform any action on any resource.\n    /// This is intended to be an escape hatch to bypass RBAC restrictions.\n    /// Use at your own risk.\n    pub fn danger_unrestricted() -> Self {\n        let mut snapshot = Self::default();\n\n        snapshot.set_resources(vec![Resource {\n            id: ResourceId(0),\n            schema: None,\n            table: WILDCARD.to_owned(),\n        }]);\n        snapshot.set_permissions(vec![Permission {\n            id: PermissionId(0),\n            action: WILDCARD.to_owned(),\n        }]);\n        snapshot.set_roles(vec![Role {\n            id: RoleId(0),\n            role: \"unrestricted\".to_owned(),\n        }]);\n        snapshot.set_user_role(UserId(0), \"unrestricted\");\n        snapshot.add_role_permission(\"unrestricted\", Action(\"*\"), Table(\"*\"));\n\n        snapshot\n    }\n\n    pub(super) fn set_resources(&mut self, mut resources: Vec<Resource>) {\n        for (i, r) in resources.iter_mut().enumerate() {\n            r.id = ResourceId(i as i64 + 1);\n        }\n        self.resources = resources;\n    }\n\n    pub(super) fn set_permissions(&mut self, mut permissions: Vec<Permission>) {\n        for (i, r) in permissions.iter_mut().enumerate() {\n            r.id = PermissionId(i as i64 + 1);\n        }\n        self.permissions = permissions;\n    }\n\n    pub(super) fn set_roles(&mut self, mut roles: Vec<Role>) {\n        for (i, r) in roles.iter_mut().enumerate() {\n            r.id = RoleId(i as i64 + 1);\n        }\n        self.roles = roles;\n    }\n\n    pub(super) fn set_user_role(&mut self, user_id: UserId, role: &str) {\n        self.user_roles.push(UserRole {\n            user_id,\n            role_id: self.find_role(role),\n        });\n    }\n\n    pub(super) fn add_role_permission<P, R>(&mut self, role: &str, permission: P, resource: R)\n    where\n        P: Into<PermissionRequest>,\n        R: Into<ResourceRequest>,\n    {\n        let permission = permission.into();\n        let resource = resource.into();\n        let role_id = self.find_role(role);\n        self.role_permissions.push(RolePermission {\n            role_id,\n            permission_id: self.find_permission(&permission),\n            resource_id: self.find_resource(&resource),\n        });\n    }\n\n    #[cfg(test)]\n    pub(super) fn add_user_override<P, R>(\n        &mut self,\n        user_id: UserId,\n        permission: P,\n        resource: R,\n        grant: bool,\n    ) where\n        P: Into<PermissionRequest>,\n        R: Into<ResourceRequest>,\n    {\n        let permission = permission.into();\n        let resource = resource.into();\n        self.user_overrides.push(UserOverride {\n            user_id,\n            permission_id: self.find_permission(&permission),\n            resource_id: self.find_resource(&resource),\n            grant,\n        });\n    }\n\n    #[cfg(test)]\n    pub(super) fn add_role_hierarchy(&mut self, role: &str, super_role: &str) {\n        self.role_hierarchy.push(RoleHierarchy {\n            role_id: self.find_role(role),\n            super_role_id: self.find_role(super_role),\n        })\n    }\n\n    pub(super) fn find_role(&self, role: &str) -> RoleId {\n        self.roles.iter().find(|r| r.role == role).unwrap().id\n    }\n\n    pub(super) fn find_permission(&self, permission: &PermissionRequest) -> PermissionId {\n        self.permissions\n            .iter()\n            .find(|r| r.action == permission.action)\n            .unwrap()\n            .id\n    }\n\n    pub(super) fn find_resource(&self, resource: &ResourceRequest) -> ResourceId {\n        self.resources\n            .iter()\n            .find(|r| r.schema == resource.schema && r.table == resource.table)\n            .unwrap()\n            .id\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/entity/mod.rs",
    "content": "pub mod permission;\npub mod resource;\npub mod role;\npub mod role_hierarchy;\npub mod role_permission;\npub mod user;\npub mod user_override;\npub mod user_role;\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/entity/permission.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::DeriveValueType;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_permission\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: PermissionId,\n    #[sea_orm(unique)]\n    pub action: String,\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, DeriveValueType)]\npub struct PermissionId(pub i64);\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/entity/resource.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::DeriveValueType;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_resource\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: ResourceId,\n    #[sea_orm(unique_group = \"1\")]\n    pub schema: Option<String>,\n    #[sea_orm(unique_group = \"1\")]\n    pub table: String,\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, DeriveValueType)]\npub struct ResourceId(pub i64);\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/entity/role.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::DeriveValueType;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_role\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: RoleId,\n    #[sea_orm(unique)]\n    pub role: String,\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, DeriveValueType)]\npub struct RoleId(pub i64);\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/entity/role_hierarchy.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\nuse super::role::RoleId;\n\n#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_role_hierarchy\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub super_role_id: RoleId,\n    #[sea_orm(primary_key)]\n    pub role_id: RoleId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::role::Entity\",\n        from = \"Column::RoleId\",\n        to = \"super::role::Column::Id\"\n    )]\n    Role,\n    #[sea_orm(\n        belongs_to = \"super::role::Entity\",\n        from = \"Column::SuperRoleId\",\n        to = \"super::role::Column::Id\"\n    )]\n    SuperRole,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/entity/role_permission.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\nuse super::{permission::PermissionId, resource::ResourceId, role::RoleId};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_role_permission\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub role_id: RoleId,\n    #[sea_orm(primary_key)]\n    pub permission_id: PermissionId,\n    #[sea_orm(primary_key)]\n    pub resource_id: ResourceId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::role::Entity\",\n        from = \"Column::RoleId\",\n        to = \"super::role::Column::Id\"\n    )]\n    Role,\n    #[sea_orm(\n        belongs_to = \"super::permission::Entity\",\n        from = \"Column::PermissionId\",\n        to = \"super::permission::Column::Id\"\n    )]\n    Permission,\n    #[sea_orm(\n        belongs_to = \"super::resource::Entity\",\n        from = \"Column::ResourceId\",\n        to = \"super::resource::Column::Id\"\n    )]\n    Resource,\n}\n\nimpl Related<super::role::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Role.def()\n    }\n}\n\nimpl Related<super::permission::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Permission.def()\n    }\n}\n\nimpl Related<super::resource::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Resource.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/entity/user.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::DeriveValueType;\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, DeriveValueType)]\npub struct UserId(pub i64);\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/entity/user_override.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\nuse super::{permission::PermissionId, resource::ResourceId, user::UserId};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_user_override\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub user_id: UserId,\n    #[sea_orm(primary_key)]\n    pub permission_id: PermissionId,\n    #[sea_orm(primary_key)]\n    pub resource_id: ResourceId,\n    /// true to allow, false to deny\n    pub grant: bool,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::permission::Entity\",\n        from = \"Column::PermissionId\",\n        to = \"super::permission::Column::Id\"\n    )]\n    Permission,\n    #[sea_orm(\n        belongs_to = \"super::resource::Entity\",\n        from = \"Column::ResourceId\",\n        to = \"super::resource::Column::Id\"\n    )]\n    Resource,\n}\n\nimpl Related<super::permission::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Permission.def()\n    }\n}\n\nimpl Related<super::resource::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Resource.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/entity/user_role.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\nuse super::{role::RoleId, user::UserId};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_user_role\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub user_id: UserId,\n    pub role_id: RoleId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::role::Entity\",\n        from = \"Column::RoleId\",\n        to = \"super::role::Column::Id\"\n    )]\n    Role,\n}\n\nimpl Related<super::role::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Role.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/error.rs",
    "content": "use thiserror::Error;\n\n/// An error from unsuccessful database operations\n#[derive(Error, Debug, Clone, PartialEq, Eq)]\npub enum Error {\n    /// Resource not found\n    #[error(\"Resource Not Found: {0}\")]\n    ResourceNotFound(String),\n    /// Permission not found\n    #[error(\"Permission Not Found: {0}\")]\n    PermissionNotFound(String),\n    /// Role not found\n    #[error(\"Role Not Found: {0}\")]\n    RoleNotFound(String),\n    /// User not found\n    #[error(\"User Not Found: {0}\")]\n    UserNotFound(String),\n}\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/mod.rs",
    "content": "#![allow(missing_docs)]\n\nmod engine;\npub use engine::*;\n\npub mod entity;\npub use entity::user::UserId as RbacUserId;\n\npub mod context;\npub use context::*;\n\nmod error;\npub use error::Error as RbacError;\nuse error::*;\n\npub mod schema;\n\n/// This could be used to denote any permission or any resources.\npub const WILDCARD: &str = \"*\";\n\npub use sea_query::audit::{AccessType, SchemaOper};\n"
  },
  {
    "path": "sea-orm-sync/src/rbac/schema.rs",
    "content": "use super::entity;\nuse crate::{ConnectionTrait, DbErr, EntityTrait, ExecResult, RelationDef, Schema};\n\n#[derive(Debug, Default)]\npub struct RbacCreateTablesParams {\n    pub user_override_relation: Option<RelationDef>,\n    pub user_role_relation: Option<RelationDef>,\n}\n\n/// Create RBAC tables, will currently fail if any of them already exsits\npub fn create_tables<C: ConnectionTrait>(\n    db: &C,\n    RbacCreateTablesParams {\n        user_override_relation,\n        user_role_relation,\n    }: RbacCreateTablesParams,\n) -> Result<(), DbErr> {\n    create_table(db, entity::permission::Entity, None)?;\n    create_table(db, entity::resource::Entity, None)?;\n    create_table(db, entity::role::Entity, None)?;\n    create_table(db, entity::role_hierarchy::Entity, None)?;\n    create_table(db, entity::role_permission::Entity, None)?;\n    create_table(db, entity::user_override::Entity, user_override_relation)?;\n    create_table(db, entity::user_role::Entity, user_role_relation)?;\n\n    Ok(())\n}\n\n/// All tables associated with RBAC, created by SeaORM\npub fn all_tables() -> Vec<&'static str> {\n    use crate::EntityName;\n\n    vec![\n        entity::permission::Entity.table_name(),\n        entity::resource::Entity.table_name(),\n        entity::role::Entity.table_name(),\n        entity::role_hierarchy::Entity.table_name(),\n        entity::role_permission::Entity.table_name(),\n        entity::user_override::Entity.table_name(),\n        entity::user_role::Entity.table_name(),\n    ]\n}\n\nfn create_table<C, E>(db: &C, entity: E, rel: Option<RelationDef>) -> Result<ExecResult, DbErr>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait,\n{\n    let backend = db.get_database_backend();\n    let schema = Schema::new(backend);\n\n    let mut stmt = schema.create_table_from_entity(entity);\n    if let Some(rel) = rel {\n        stmt.foreign_key(&mut rel.into());\n    }\n    let res = db.execute(&stmt)?;\n\n    for stmt in schema.create_index_from_entity(entity) {\n        db.execute(&stmt)?;\n    }\n\n    Ok(res)\n}\n"
  },
  {
    "path": "sea-orm-sync/src/schema/builder.rs",
    "content": "use super::{Schema, TopologicalSort};\nuse crate::{ConnectionTrait, DbBackend, DbErr, EntityTrait, Statement};\nuse sea_query::{\n    ForeignKeyCreateStatement, Index, IndexCreateStatement, IntoIden, TableAlterStatement,\n    TableCreateStatement, TableName, TableRef, extension::postgres::TypeCreateStatement,\n};\n\n/// A schema builder that can take a registry of Entities and synchronize it with database.\npub struct SchemaBuilder {\n    helper: Schema,\n    entities: Vec<EntitySchemaInfo>,\n}\n\n/// Schema info for Entity. Can be used to re-create schema in database.\npub struct EntitySchemaInfo {\n    table: TableCreateStatement,\n    enums: Vec<TypeCreateStatement>,\n    indexes: Vec<IndexCreateStatement>,\n}\n\nimpl std::fmt::Debug for SchemaBuilder {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"SchemaBuilder {{\")?;\n        write!(f, \" entities: [\")?;\n        for (i, entity) in self.entities.iter().enumerate() {\n            if i > 0 {\n                write!(f, \", \")?;\n            }\n            entity.debug_print(f, &self.helper.backend)?;\n        }\n        write!(f, \" ]\")?;\n        write!(f, \" }}\")\n    }\n}\n\nimpl std::fmt::Debug for EntitySchemaInfo {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        self.debug_print(f, &DbBackend::Sqlite)\n    }\n}\n\nimpl SchemaBuilder {\n    /// Creates a new schema builder\n    pub fn new(schema: Schema) -> Self {\n        Self {\n            helper: schema,\n            entities: Default::default(),\n        }\n    }\n\n    /// Register an entity to this schema\n    pub fn register<E: EntityTrait>(mut self, entity: E) -> Self {\n        let entity = EntitySchemaInfo::new(entity, &self.helper);\n        if !self\n            .entities\n            .iter()\n            .any(|e| e.table.get_table_name() == entity.table.get_table_name())\n        {\n            self.entities.push(entity);\n        }\n        self\n    }\n\n    #[cfg(feature = \"entity-registry\")]\n    pub(crate) fn helper(&self) -> &Schema {\n        &self.helper\n    }\n\n    #[cfg(feature = \"entity-registry\")]\n    pub(crate) fn register_entity(&mut self, entity: EntitySchemaInfo) {\n        self.entities.push(entity);\n    }\n\n    /// Synchronize the schema with database, will create missing tables, columns, unique keys, and foreign keys.\n    /// This operation is addition only, will not drop any table / columns.\n    #[cfg(feature = \"schema-sync\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"schema-sync\")))]\n    pub fn sync<C>(self, db: &C) -> Result<(), DbErr>\n    where\n        C: ConnectionTrait + sea_schema::Connection,\n    {\n        let _existing = match db.get_database_backend() {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DbBackend::MySql => {\n                use sea_schema::{mysql::discovery::SchemaDiscovery, probe::SchemaProbe};\n\n                let current_schema: String = db\n                    .query_one(\n                        sea_query::SelectStatement::new()\n                            .expr(sea_schema::mysql::MySql::get_current_schema()),\n                    )?\n                    .ok_or_else(|| DbErr::RecordNotFound(\"Can't get current schema\".into()))?\n                    .try_get_by_index(0)?;\n                let schema_discovery = SchemaDiscovery::new_no_exec(&current_schema);\n\n                let schema = schema_discovery\n                    .discover_with(db)\n                    .map_err(|err| DbErr::Query(crate::RuntimeErr::SqlxError(err.into())))?;\n\n                DiscoveredSchema {\n                    tables: schema.tables.iter().map(|table| table.write()).collect(),\n                    enums: vec![],\n                }\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            DbBackend::Postgres => {\n                use sea_schema::{postgres::discovery::SchemaDiscovery, probe::SchemaProbe};\n\n                let current_schema: String = db\n                    .query_one(\n                        sea_query::SelectStatement::new()\n                            .expr(sea_schema::postgres::Postgres::get_current_schema()),\n                    )?\n                    .ok_or_else(|| DbErr::RecordNotFound(\"Can't get current schema\".into()))?\n                    .try_get_by_index(0)?;\n                let schema_discovery = SchemaDiscovery::new_no_exec(&current_schema);\n\n                let schema = schema_discovery\n                    .discover_with(db)\n                    .map_err(|err| DbErr::Query(crate::RuntimeErr::SqlxError(err.into())))?;\n\n                DiscoveredSchema {\n                    tables: schema.tables.iter().map(|table| table.write()).collect(),\n                    enums: schema.enums.iter().map(|def| def.write()).collect(),\n                }\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DbBackend::Sqlite => {\n                use sea_schema::sqlite::{SqliteDiscoveryError, discovery::SchemaDiscovery};\n                let schema = SchemaDiscovery::discover_with(db)\n                    .map_err(|err| {\n                        DbErr::Query(match err {\n                            SqliteDiscoveryError::SqlxError(err) => {\n                                crate::RuntimeErr::SqlxError(err.into())\n                            }\n                            _ => crate::RuntimeErr::Internal(format!(\"{err:?}\")),\n                        })\n                    })?\n                    .merge_indexes_into_table();\n                DiscoveredSchema {\n                    tables: schema.tables.iter().map(|table| table.write()).collect(),\n                    enums: vec![],\n                }\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DbBackend::Sqlite => {\n                use sea_schema::sqlite::{SqliteDiscoveryError, discovery::SchemaDiscovery};\n                let schema = SchemaDiscovery::discover_with(db)\n                    .map_err(|err| {\n                        DbErr::Query(match err {\n                            SqliteDiscoveryError::RusqliteError(err) => {\n                                crate::RuntimeErr::Rusqlite(err.into())\n                            }\n                            _ => crate::RuntimeErr::Internal(format!(\"{err:?}\")),\n                        })\n                    })?\n                    .merge_indexes_into_table();\n                DiscoveredSchema {\n                    tables: schema.tables.iter().map(|table| table.write()).collect(),\n                    enums: vec![],\n                }\n            }\n            #[allow(unreachable_patterns)]\n            other => {\n                return Err(DbErr::BackendNotSupported {\n                    db: other.as_str(),\n                    ctx: \"SchemaBuilder::sync\",\n                });\n            }\n        };\n\n        #[allow(unreachable_code)]\n        let mut created_enums: Vec<Statement> = Default::default();\n\n        #[allow(unreachable_code)]\n        for table_name in self.sorted_tables() {\n            if let Some(entity) = self\n                .entities\n                .iter()\n                .find(|entity| table_name == get_table_name(entity.table.get_table_name()))\n            {\n                entity.sync(db, &_existing, &mut created_enums)?;\n            }\n        }\n\n        Ok(())\n    }\n\n    /// Apply this schema to a database, will create all registered tables, columns, unique keys, and foreign keys.\n    /// Will fail if any table already exists. Use [`sync`] if you want an incremental version that can perform schema diff.\n    pub fn apply<C: ConnectionTrait>(self, db: &C) -> Result<(), DbErr> {\n        let mut created_enums: Vec<Statement> = Default::default();\n\n        for table_name in self.sorted_tables() {\n            if let Some(entity) = self\n                .entities\n                .iter()\n                .find(|entity| table_name == get_table_name(entity.table.get_table_name()))\n            {\n                entity.apply(db, &mut created_enums)?;\n            }\n        }\n\n        Ok(())\n    }\n\n    fn sorted_tables(&self) -> Vec<TableName> {\n        let mut sorter = TopologicalSort::<TableName>::new();\n\n        for entity in self.entities.iter() {\n            let table_name = get_table_name(entity.table.get_table_name());\n            sorter.insert(table_name);\n        }\n        for entity in self.entities.iter() {\n            let self_table = get_table_name(entity.table.get_table_name());\n            for fk in entity.table.get_foreign_key_create_stmts().iter() {\n                let fk = fk.get_foreign_key();\n                let ref_table = get_table_name(fk.get_ref_table());\n                if self_table != ref_table {\n                    // self cycle is okay\n                    sorter.add_dependency(ref_table, self_table.clone());\n                }\n            }\n        }\n        let mut sorted = Vec::new();\n        while let Some(i) = sorter.pop() {\n            sorted.push(i);\n        }\n        if sorted.len() != self.entities.len() {\n            // push leftover tables\n            for entity in self.entities.iter() {\n                let table_name = get_table_name(entity.table.get_table_name());\n                if !sorted.contains(&table_name) {\n                    sorted.push(table_name);\n                }\n            }\n        }\n\n        sorted\n    }\n}\n\nstruct DiscoveredSchema {\n    tables: Vec<TableCreateStatement>,\n    enums: Vec<TypeCreateStatement>,\n}\n\nimpl EntitySchemaInfo {\n    /// Creates a EntitySchemaInfo object given a generic Entity.\n    pub fn new<E: EntityTrait>(entity: E, helper: &Schema) -> Self {\n        Self {\n            table: helper.create_table_from_entity(entity),\n            enums: helper.create_enum_from_entity(entity),\n            indexes: helper.create_index_from_entity(entity),\n        }\n    }\n\n    fn apply<C: ConnectionTrait>(\n        &self,\n        db: &C,\n        created_enums: &mut Vec<Statement>,\n    ) -> Result<(), DbErr> {\n        for stmt in self.enums.iter() {\n            let new_stmt = db.get_database_backend().build(stmt);\n            if !created_enums.iter().any(|s| s == &new_stmt) {\n                db.execute(stmt)?;\n                created_enums.push(new_stmt);\n            }\n        }\n        db.execute(&self.table)?;\n        for stmt in self.indexes.iter() {\n            db.execute(stmt)?;\n        }\n        Ok(())\n    }\n\n    // better to always compile this function\n    #[allow(dead_code)]\n    fn sync<C: ConnectionTrait>(\n        &self,\n        db: &C,\n        existing: &DiscoveredSchema,\n        created_enums: &mut Vec<Statement>,\n    ) -> Result<(), DbErr> {\n        let db_backend = db.get_database_backend();\n\n        // create enum before creating table\n        for stmt in self.enums.iter() {\n            let mut has_enum = false;\n            let new_stmt = db_backend.build(stmt);\n            for existing_enum in &existing.enums {\n                if db_backend.build(existing_enum) == new_stmt {\n                    has_enum = true;\n                    // TODO add enum variants\n                    break;\n                }\n            }\n            if !has_enum && !created_enums.iter().any(|s| s == &new_stmt) {\n                db.execute(stmt)?;\n                created_enums.push(new_stmt);\n            }\n        }\n        let table_name = get_table_name(self.table.get_table_name());\n        let mut existing_table = None;\n        for tbl in &existing.tables {\n            if get_table_name(tbl.get_table_name()) == table_name {\n                existing_table = Some(tbl);\n                break;\n            }\n        }\n        if let Some(existing_table) = existing_table {\n            for column_def in self.table.get_columns() {\n                let mut column_exists = false;\n                for existing_column in existing_table.get_columns() {\n                    if column_def.get_column_name() == existing_column.get_column_name() {\n                        column_exists = true;\n                        break;\n                    }\n                }\n                if !column_exists {\n                    let mut renamed_from = \"\";\n                    if let Some(comment) = &column_def.get_column_spec().comment {\n                        if let Some((_, suffix)) = comment.rsplit_once(\"renamed_from \\\"\") {\n                            if let Some((prefix, _)) = suffix.split_once('\"') {\n                                renamed_from = prefix;\n                            }\n                        }\n                    }\n                    if renamed_from.is_empty() {\n                        db.execute(\n                            TableAlterStatement::new()\n                                .table(self.table.get_table_name().expect(\"Checked above\").clone())\n                                .add_column(column_def.to_owned()),\n                        )?;\n                    } else {\n                        db.execute(\n                            TableAlterStatement::new()\n                                .table(self.table.get_table_name().expect(\"Checked above\").clone())\n                                .rename_column(\n                                    renamed_from.to_owned(),\n                                    column_def.get_column_name(),\n                                ),\n                        )?;\n                    }\n                }\n            }\n            if db.get_database_backend() != DbBackend::Sqlite {\n                for foreign_key in self.table.get_foreign_key_create_stmts().iter() {\n                    let mut key_exists = false;\n                    for existing_key in existing_table.get_foreign_key_create_stmts().iter() {\n                        if compare_foreign_key(foreign_key, existing_key) {\n                            key_exists = true;\n                            break;\n                        }\n                    }\n                    if !key_exists {\n                        db.execute(foreign_key)?;\n                    }\n                }\n            }\n        } else {\n            db.execute(&self.table)?;\n        }\n        for stmt in self.indexes.iter() {\n            let mut has_index = false;\n            if let Some(existing_table) = existing_table {\n                for existing_index in existing_table.get_indexes() {\n                    if existing_index.get_index_spec().get_column_names()\n                        == stmt.get_index_spec().get_column_names()\n                    {\n                        has_index = true;\n                        break;\n                    }\n                }\n            }\n            if !has_index {\n                // shall we do alter table add constraint for unique index?\n                let mut stmt = stmt.clone();\n                stmt.if_not_exists();\n                db.execute(&stmt)?;\n            }\n        }\n        if let Some(existing_table) = existing_table {\n            // For columns with a column-level UNIQUE constraint (#[sea_orm(unique)]) that\n            // already exist in the table but do not yet have a unique index, create one.\n            for column_def in self.table.get_columns() {\n                if column_def.get_column_spec().unique {\n                    let col_name = column_def.get_column_name();\n                    let col_exists = existing_table\n                        .get_columns()\n                        .iter()\n                        .any(|c| c.get_column_name() == col_name);\n                    if !col_exists {\n                        // Column is being added in this sync pass; the ALTER TABLE ADD COLUMN\n                        // will include the UNIQUE inline, so no separate index needed.\n                        continue;\n                    }\n                    let already_unique = existing_table.get_indexes().iter().any(|idx| {\n                        if !idx.is_unique_key() {\n                            return false;\n                        }\n                        let cols = idx.get_index_spec().get_column_names();\n                        cols.len() == 1 && cols[0] == col_name\n                    });\n                    if !already_unique {\n                        let table_name =\n                            self.table.get_table_name().expect(\"table must have a name\");\n                        let tbl_str = table_name.sea_orm_table().to_string();\n                        let table_ref = table_name.clone();\n                        db.execute(\n                            Index::create()\n                                .name(format!(\"idx-{tbl_str}-{col_name}\"))\n                                .table(table_ref)\n                                .col(col_name.into_iden())\n                                .unique()\n                                .if_not_exists(),\n                        )?;\n                    }\n                }\n            }\n        }\n        if let Some(existing_table) = existing_table {\n            // find all unique keys from existing table\n            // if it no longer exist in new schema, drop it\n            for existing_index in existing_table.get_indexes() {\n                if existing_index.is_unique_key() {\n                    let mut has_index = false;\n                    for stmt in self.indexes.iter() {\n                        if existing_index.get_index_spec().get_column_names()\n                            == stmt.get_index_spec().get_column_names()\n                        {\n                            has_index = true;\n                            break;\n                        }\n                    }\n                    // Also check if the unique index corresponds to a column-level UNIQUE\n                    // constraint (from #[sea_orm(unique)]). These are embedded in the CREATE\n                    // TABLE column definition and not tracked in self.indexes, so we must not\n                    // try to drop them during sync.\n                    if !has_index {\n                        let index_cols = existing_index.get_index_spec().get_column_names();\n                        if index_cols.len() == 1 {\n                            for column_def in self.table.get_columns() {\n                                if column_def.get_column_name() == index_cols[0]\n                                    && column_def.get_column_spec().unique\n                                {\n                                    has_index = true;\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                    if !has_index {\n                        if let Some(drop_existing) = existing_index.get_index_spec().get_name() {\n                            db.execute(sea_query::Index::drop().name(drop_existing))?;\n                        }\n                    }\n                }\n            }\n        }\n        Ok(())\n    }\n\n    fn debug_print(\n        &self,\n        f: &mut std::fmt::Formatter<'_>,\n        backend: &DbBackend,\n    ) -> std::fmt::Result {\n        write!(f, \"EntitySchemaInfo {{\")?;\n        write!(f, \" table: {:?}\", backend.build(&self.table).to_string())?;\n        write!(f, \" enums: [\")?;\n        for (i, stmt) in self.enums.iter().enumerate() {\n            if i > 0 {\n                write!(f, \", \")?;\n            }\n            write!(f, \"{:?}\", backend.build(stmt).to_string())?;\n        }\n        write!(f, \" ]\")?;\n        write!(f, \" indexes: [\")?;\n        for (i, stmt) in self.indexes.iter().enumerate() {\n            if i > 0 {\n                write!(f, \", \")?;\n            }\n            write!(f, \"{:?}\", backend.build(stmt).to_string())?;\n        }\n        write!(f, \" ]\")?;\n        write!(f, \" }}\")\n    }\n}\n\nfn get_table_name(table_ref: Option<&TableRef>) -> TableName {\n    match table_ref {\n        Some(TableRef::Table(table_name, _)) => table_name.clone(),\n        None => panic!(\"Expect TableCreateStatement is properly built\"),\n        _ => unreachable!(\"Unexpected {table_ref:?}\"),\n    }\n}\n\nfn compare_foreign_key(a: &ForeignKeyCreateStatement, b: &ForeignKeyCreateStatement) -> bool {\n    let a = a.get_foreign_key();\n    let b = b.get_foreign_key();\n\n    a.get_name() == b.get_name()\n        || (a.get_ref_table() == b.get_ref_table()\n            && a.get_columns() == b.get_columns()\n            && a.get_ref_columns() == b.get_ref_columns())\n}\n"
  },
  {
    "path": "sea-orm-sync/src/schema/entity.rs",
    "content": "use crate::{\n    ActiveEnum, ColumnTrait, ColumnType, DbBackend, EntityTrait, IdenStatic, Iterable,\n    PrimaryKeyArity, PrimaryKeyToColumn, PrimaryKeyTrait, RelationTrait, Schema,\n};\nuse sea_query::{\n    ColumnDef, DynIden, Iden, Index, IndexCreateStatement, SeaRc, TableCreateStatement,\n    extension::postgres::{Type, TypeCreateStatement},\n};\nuse std::collections::BTreeMap;\n\nimpl Schema {\n    /// Creates Postgres enums from an ActiveEnum. See [`TypeCreateStatement`] for more details.\n    /// Returns None if not Postgres.\n    pub fn create_enum_from_active_enum<A>(&self) -> Option<TypeCreateStatement>\n    where\n        A: ActiveEnum,\n    {\n        create_enum_from_active_enum::<A>(self.backend)\n    }\n\n    /// Creates Postgres enums from an Entity. See [`TypeCreateStatement`] for more details.\n    /// Returns empty vec if not Postgres.\n    pub fn create_enum_from_entity<E>(&self, entity: E) -> Vec<TypeCreateStatement>\n    where\n        E: EntityTrait,\n    {\n        create_enum_from_entity(entity, self.backend)\n    }\n\n    /// Creates a table from an Entity. See [TableCreateStatement] for more details.\n    pub fn create_table_from_entity<E>(&self, entity: E) -> TableCreateStatement\n    where\n        E: EntityTrait,\n    {\n        create_table_from_entity(entity, self.backend)\n    }\n\n    #[doc(hidden)]\n    pub fn create_table_with_index_from_entity<E>(&self, entity: E) -> TableCreateStatement\n    where\n        E: EntityTrait,\n    {\n        let mut table = create_table_from_entity(entity, self.backend);\n        for mut index in create_index_from_entity(entity, self.backend) {\n            table.index(&mut index);\n        }\n        table\n    }\n\n    /// Creates the indexes from an Entity, returning an empty Vec if there are none\n    /// to create. See [IndexCreateStatement] for more details\n    pub fn create_index_from_entity<E>(&self, entity: E) -> Vec<IndexCreateStatement>\n    where\n        E: EntityTrait,\n    {\n        create_index_from_entity(entity, self.backend)\n    }\n\n    /// Creates a column definition for example to update a table.\n    ///\n    /// ```\n    /// use sea_orm::sea_query::TableAlterStatement;\n    /// use sea_orm::{DbBackend, Schema, Statement};\n    ///\n    /// mod post {\n    ///     use sea_orm::entity::prelude::*;\n    ///\n    ///     #[sea_orm::model]\n    ///     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    ///     #[sea_orm(table_name = \"posts\")]\n    ///     pub struct Model {\n    ///         #[sea_orm(primary_key)]\n    ///         pub id: u32,\n    ///         pub title: String,\n    ///     }\n    ///\n    ///     impl ActiveModelBehavior for ActiveModel {}\n    /// }\n    ///\n    /// let schema = Schema::new(DbBackend::MySql);\n    ///\n    /// let alter_table: Statement = DbBackend::MySql.build(\n    ///     TableAlterStatement::new()\n    ///         .table(post::Entity)\n    ///         .add_column(&mut schema.get_column_def::<post::Entity>(post::Column::Title)),\n    /// );\n    /// assert_eq!(\n    ///     alter_table.to_string(),\n    ///     \"ALTER TABLE `posts` ADD COLUMN `title` varchar(255) NOT NULL\"\n    /// );\n    /// ```\n    pub fn get_column_def<E>(&self, column: E::Column) -> ColumnDef\n    where\n        E: EntityTrait,\n    {\n        column_def_from_entity_column::<E>(column, self.backend)\n    }\n}\n\npub(crate) fn create_enum_from_active_enum<A>(backend: DbBackend) -> Option<TypeCreateStatement>\nwhere\n    A: ActiveEnum,\n{\n    if matches!(backend, DbBackend::MySql | DbBackend::Sqlite) {\n        return None;\n    }\n    let col_def = A::db_type();\n    let col_type = col_def.get_column_type();\n    create_enum_from_column_type(col_type)\n}\n\npub(crate) fn create_enum_from_column_type(col_type: &ColumnType) -> Option<TypeCreateStatement> {\n    let (name, values) = match col_type {\n        ColumnType::Enum { name, variants } => (name.clone(), variants.clone()),\n        _ => return None,\n    };\n    Some(Type::create().as_enum(name).values(values).to_owned())\n}\n\n#[allow(clippy::needless_borrow)]\npub(crate) fn create_enum_from_entity<E>(_: E, backend: DbBackend) -> Vec<TypeCreateStatement>\nwhere\n    E: EntityTrait,\n{\n    if matches!(backend, DbBackend::MySql | DbBackend::Sqlite) {\n        return Vec::new();\n    }\n    let mut vec = Vec::new();\n    for col in E::Column::iter() {\n        let col_def = col.def();\n        let col_type = col_def.get_column_type();\n        if !matches!(col_type, ColumnType::Enum { .. }) {\n            continue;\n        }\n        if let Some(stmt) = create_enum_from_column_type(&col_type) {\n            vec.push(stmt);\n        }\n    }\n    vec\n}\n\npub(crate) fn create_index_from_entity<E>(\n    entity: E,\n    _backend: DbBackend,\n) -> Vec<IndexCreateStatement>\nwhere\n    E: EntityTrait,\n{\n    let mut indexes = Vec::new();\n    let mut unique_keys: BTreeMap<String, Vec<DynIden>> = Default::default();\n\n    for column in E::Column::iter() {\n        let column_def = column.def();\n\n        if column_def.indexed && !column_def.unique {\n            let stmt = Index::create()\n                .name(format!(\"idx-{}-{}\", entity.to_string(), column.to_string()))\n                .table(entity)\n                .col(column)\n                .take();\n            indexes.push(stmt);\n        }\n\n        if let Some(key) = column_def.unique_key {\n            unique_keys.entry(key).or_default().push(SeaRc::new(column));\n        }\n    }\n\n    for (key, cols) in unique_keys {\n        let mut stmt = Index::create()\n            .name(format!(\"idx-{}-{}\", entity.to_string(), key))\n            .table(entity)\n            .unique()\n            .take();\n        for col in cols {\n            stmt.col(col);\n        }\n        indexes.push(stmt);\n    }\n\n    indexes\n}\n\npub(crate) fn create_table_from_entity<E>(entity: E, backend: DbBackend) -> TableCreateStatement\nwhere\n    E: EntityTrait,\n{\n    let mut stmt = TableCreateStatement::new();\n\n    if let Some(comment) = entity.comment() {\n        stmt.comment(comment);\n    }\n\n    for column in E::Column::iter() {\n        let mut column_def = column_def_from_entity_column::<E>(column, backend);\n        stmt.col(&mut column_def);\n    }\n\n    if <<E::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY > 1 {\n        let mut idx_pk = Index::create();\n        for primary_key in E::PrimaryKey::iter() {\n            idx_pk.col(primary_key);\n        }\n        stmt.primary_key(idx_pk.name(format!(\"pk-{}\", entity.to_string())).primary());\n    }\n\n    for relation in E::Relation::iter() {\n        let relation = relation.def();\n        if relation.is_owner || relation.skip_fk {\n            continue;\n        }\n        stmt.foreign_key(&mut relation.into());\n    }\n\n    stmt.table(entity.table_ref()).take()\n}\n\nfn column_def_from_entity_column<E>(column: E::Column, backend: DbBackend) -> ColumnDef\nwhere\n    E: EntityTrait,\n{\n    let orm_column_def = column.def();\n    let types = match &orm_column_def.col_type {\n        ColumnType::Enum { name, variants } => match backend {\n            DbBackend::MySql => {\n                let variants: Vec<String> = variants.iter().map(|v| v.to_string()).collect();\n                ColumnType::custom(format!(\"ENUM('{}')\", variants.join(\"', '\")))\n            }\n            DbBackend::Postgres => ColumnType::Custom(name.clone()),\n            DbBackend::Sqlite => orm_column_def.col_type,\n        },\n        _ => orm_column_def.col_type,\n    };\n    let mut column_def = ColumnDef::new_with_type(column, types);\n    if !orm_column_def.null {\n        column_def.not_null();\n    }\n    if orm_column_def.unique {\n        column_def.unique_key();\n    }\n    if let Some(default) = orm_column_def.default {\n        column_def.default(default);\n    }\n    if let Some(comment) = &orm_column_def.comment {\n        column_def.comment(comment);\n    }\n    if let Some(extra) = &orm_column_def.extra {\n        column_def.extra(extra);\n    }\n    match (&orm_column_def.renamed_from, &orm_column_def.comment) {\n        (Some(renamed_from), Some(comment)) => {\n            column_def.comment(format!(\"{comment}; renamed_from \\\"{renamed_from}\\\"\"));\n        }\n        (Some(renamed_from), None) => {\n            column_def.comment(format!(\"renamed_from \\\"{renamed_from}\\\"\"));\n        }\n        (None, _) => {}\n    }\n    for primary_key in E::PrimaryKey::iter() {\n        if column.as_str() == primary_key.into_column().as_str() {\n            if E::PrimaryKey::auto_increment() {\n                column_def.auto_increment();\n            }\n            if <<E::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY == 1 {\n                column_def.primary_key();\n            }\n        }\n    }\n    column_def\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{DbBackend, EntityName, Schema, sea_query::*, tests_cfg::*};\n    use pretty_assertions::assert_eq;\n\n    #[test]\n    fn test_create_table_from_entity_table_ref() {\n        for builder in [DbBackend::MySql, DbBackend::Postgres, DbBackend::Sqlite] {\n            let schema = Schema::new(builder);\n            assert_eq!(\n                builder.build(&schema.create_table_from_entity(CakeFillingPrice)),\n                builder.build(\n                    &get_cake_filling_price_stmt()\n                        .table(CakeFillingPrice.table_ref())\n                        .to_owned()\n                )\n            );\n        }\n    }\n\n    fn get_cake_filling_price_stmt() -> TableCreateStatement {\n        Table::create()\n            .col(\n                ColumnDef::new(cake_filling_price::Column::CakeId)\n                    .integer()\n                    .not_null(),\n            )\n            .col(\n                ColumnDef::new(cake_filling_price::Column::FillingId)\n                    .integer()\n                    .not_null(),\n            )\n            .col(\n                ColumnDef::new(cake_filling_price::Column::Price)\n                    .decimal()\n                    .not_null()\n                    .extra(\"CHECK (price > 0)\"),\n            )\n            .primary_key(\n                Index::create()\n                    .name(\"pk-cake_filling_price\")\n                    .col(cake_filling_price::Column::CakeId)\n                    .col(cake_filling_price::Column::FillingId)\n                    .primary(),\n            )\n            .foreign_key(\n                ForeignKeyCreateStatement::new()\n                    .name(\"fk-cake_filling_price-cake_id-filling_id\")\n                    .from_tbl(CakeFillingPrice)\n                    .from_col(cake_filling_price::Column::CakeId)\n                    .from_col(cake_filling_price::Column::FillingId)\n                    .to_tbl(CakeFilling)\n                    .to_col(cake_filling::Column::CakeId)\n                    .to_col(cake_filling::Column::FillingId),\n            )\n            .to_owned()\n    }\n\n    #[test]\n    fn test_create_index_from_entity_table_ref() {\n        for builder in [DbBackend::MySql, DbBackend::Postgres, DbBackend::Sqlite] {\n            let schema = Schema::new(builder);\n\n            assert_eq!(\n                builder.build(&schema.create_table_from_entity(indexes::Entity)),\n                builder.build(\n                    &get_indexes_table_stmt()\n                        .table(indexes::Entity.table_ref())\n                        .to_owned()\n                )\n            );\n\n            let stmts = schema.create_index_from_entity(indexes::Entity);\n            assert_eq!(stmts.len(), 2);\n\n            let idx: IndexCreateStatement = Index::create()\n                .name(\"idx-indexes-index1_attr\")\n                .table(indexes::Entity)\n                .col(indexes::Column::Index1Attr)\n                .to_owned();\n            assert_eq!(builder.build(&stmts[0]), builder.build(&idx));\n\n            let idx: IndexCreateStatement = Index::create()\n                .name(\"idx-indexes-my_unique\")\n                .table(indexes::Entity)\n                .col(indexes::Column::UniqueKeyA)\n                .col(indexes::Column::UniqueKeyB)\n                .unique()\n                .take();\n            assert_eq!(builder.build(&stmts[1]), builder.build(&idx));\n        }\n    }\n\n    fn get_indexes_table_stmt() -> TableCreateStatement {\n        Table::create()\n            .col(\n                ColumnDef::new(indexes::Column::IndexesId)\n                    .integer()\n                    .not_null()\n                    .auto_increment()\n                    .primary_key(),\n            )\n            .col(\n                ColumnDef::new(indexes::Column::UniqueAttr)\n                    .integer()\n                    .not_null()\n                    .unique_key(),\n            )\n            .col(\n                ColumnDef::new(indexes::Column::Index1Attr)\n                    .integer()\n                    .not_null(),\n            )\n            .col(\n                ColumnDef::new(indexes::Column::Index2Attr)\n                    .integer()\n                    .not_null()\n                    .unique_key(),\n            )\n            .col(\n                ColumnDef::new(indexes::Column::UniqueKeyA)\n                    .string()\n                    .not_null(),\n            )\n            .col(\n                ColumnDef::new(indexes::Column::UniqueKeyB)\n                    .string()\n                    .not_null(),\n            )\n            .to_owned()\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/schema/json.rs",
    "content": "use crate::{ColumnTrait, ColumnType, EntityTrait, Iden, Iterable, Schema};\nuse serde_json::{Map, Value};\n\nimpl Schema {\n    /// Construct a schema description in json for the given Entity.\n    pub fn json_schema_from_entity<E>(&self, entity: E) -> Value\n    where\n        E: EntityTrait,\n    {\n        json_schema_from_entity(entity)\n    }\n}\n\npub(crate) fn json_schema_from_entity<E>(entity: E) -> Value\nwhere\n    E: EntityTrait,\n{\n    let mut obj = Map::new();\n    let mut cols = Vec::new();\n\n    if let Some(comment) = entity.comment() {\n        obj.insert(\"comment\".to_owned(), Value::String(comment.to_owned()));\n    }\n\n    for column in E::Column::iter() {\n        let col = json_schema_from_entity_column::<E>(column);\n        cols.push(col);\n    }\n    obj.insert(\"columns\".to_owned(), Value::Array(cols));\n\n    let mut pk = Vec::new();\n    for col in E::PrimaryKey::iter() {\n        pk.push(Value::String(col.to_string()));\n    }\n    obj.insert(\"primary_key\".to_owned(), Value::Array(pk));\n\n    Value::Object(obj)\n}\n\nfn json_schema_from_entity_column<E>(column: E::Column) -> Value\nwhere\n    E: EntityTrait,\n{\n    let mut obj = Map::new();\n\n    let column_def = column.def();\n    obj.insert(\"name\".to_owned(), Value::String(column.to_string()));\n    obj.insert(\n        \"type\".to_owned(),\n        type_def_from_column_def(&column_def.col_type),\n    );\n    obj.insert(\"nullable\".to_owned(), Value::Bool(column_def.null));\n    if column_def.unique {\n        obj.insert(\"unique\".to_owned(), Value::Bool(true));\n    }\n    if let Some(comment) = column_def.comment {\n        obj.insert(\"comment\".to_owned(), Value::String(comment));\n    }\n\n    Value::Object(obj)\n}\n\nfn type_def_from_column_def(column_type: &ColumnType) -> Value {\n    match column_type {\n        ColumnType::Char(_) | ColumnType::String(_) | ColumnType::Text => {\n            Value::String(\"string\".to_owned())\n        }\n        ColumnType::TinyInteger\n        | ColumnType::SmallInteger\n        | ColumnType::Integer\n        | ColumnType::BigInteger\n        | ColumnType::TinyUnsigned\n        | ColumnType::SmallUnsigned\n        | ColumnType::Unsigned\n        | ColumnType::BigUnsigned => Value::String(\"integer\".to_owned()),\n        ColumnType::Float | ColumnType::Double => Value::String(\"real\".to_owned()),\n        ColumnType::Decimal(_) | ColumnType::Money(_) => Value::String(\"decimal\".to_owned()),\n        ColumnType::DateTime | ColumnType::Timestamp | ColumnType::TimestampWithTimeZone => {\n            Value::String(\"datetime\".to_owned())\n        }\n        ColumnType::Time => Value::String(\"time\".to_owned()),\n        ColumnType::Date => Value::String(\"date\".to_owned()),\n        ColumnType::Year => Value::String(\"year\".to_owned()),\n        ColumnType::Binary(_)\n        | ColumnType::VarBinary(_)\n        | ColumnType::Bit(_)\n        | ColumnType::VarBit(_) => Value::String(\"binary\".to_owned()),\n        ColumnType::Boolean => Value::String(\"bool\".to_owned()),\n        ColumnType::Json | ColumnType::JsonBinary => Value::String(\"json\".to_owned()),\n        ColumnType::Uuid => Value::String(\"uuid\".to_owned()),\n        ColumnType::Custom(typename) => Value::String(typename.to_string()),\n        ColumnType::Enum { name, variants } => {\n            let mut enum_def = Map::new();\n            enum_def.insert(\"name\".to_owned(), Value::String(name.to_string()));\n            let variants: Vec<Value> = variants\n                .iter()\n                .map(|v| Value::String(v.to_string()))\n                .collect();\n            enum_def.insert(\"variants\".to_owned(), Value::Array(variants));\n            Value::Object(enum_def)\n        }\n        ColumnType::Array(inner) => {\n            let mut obj = Map::new();\n            obj.insert(\"array\".to_owned(), type_def_from_column_def(inner));\n            Value::Object(obj)\n        }\n        _ => Value::String(\"other\".to_owned()),\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::{\n        DbBackend,\n        tests_cfg::{cake, lunch_set},\n    };\n\n    #[test]\n    fn test_json_schema_from_entity() {\n        let json = Schema::new(DbBackend::MySql).json_schema_from_entity(cake::Entity);\n        println!(\"{}\", serde_json::to_string_pretty(&json).unwrap());\n        assert_eq!(\n            json,\n            serde_json::from_str::<Value>(\n                r#\"{\n                \"columns\": [\n                    {\n                        \"name\": \"id\",\n                        \"nullable\": false,\n                        \"type\": \"integer\"\n                    },\n                    {\n                        \"name\": \"name\",\n                        \"nullable\": false,\n                        \"type\": \"string\"\n                    }\n                ],\n                \"primary_key\": [\n                    \"id\"\n                ]\n            }\"#\n            )\n            .unwrap()\n        );\n\n        let json = Schema::new(DbBackend::MySql).json_schema_from_entity(lunch_set::Entity);\n        println!(\"{}\", serde_json::to_string_pretty(&json).unwrap());\n        assert_eq!(\n            json,\n            serde_json::from_str::<Value>(\n                r#\"{\n                \"columns\": [\n                    {\n                        \"name\": \"id\",\n                        \"nullable\": false,\n                        \"type\": \"integer\"\n                    },\n                    {\n                        \"name\": \"name\",\n                        \"nullable\": false,\n                        \"type\": \"string\"\n                    },\n                    {\n                        \"name\": \"tea\",\n                        \"nullable\": false,\n                        \"type\": {\n                            \"name\": \"tea\",\n                            \"variants\": [\n                                \"EverydayTea\",\n                                \"BreakfastTea\"\n                            ]\n                        }\n                    }\n                ],\n                \"primary_key\": [\n                    \"id\"\n                ]\n            }\"#\n            )\n            .unwrap()\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/schema/mod.rs",
    "content": "use crate::DbBackend;\n\nmod builder;\nmod entity;\n#[cfg(feature = \"serde_json\")]\nmod json;\nmod topology;\n\npub use builder::*;\nuse topology::*;\n\n/// This is a helper struct to convert [`EntityTrait`](crate::EntityTrait)\n/// into different [`sea_query`](crate::sea_query) statements.\n#[derive(Debug)]\npub struct Schema {\n    backend: DbBackend,\n}\n\nimpl Schema {\n    /// Create a helper for a specific database backend\n    pub fn new(backend: DbBackend) -> Self {\n        Self { backend }\n    }\n\n    /// Creates a schema builder that can apply schema changes to database\n    pub fn builder(self) -> SchemaBuilder {\n        SchemaBuilder::new(self)\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/schema/topology.rs",
    "content": "// Copyright 2016 oauth-client-rs Developers\n//\n// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or\n// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or\n// https://opensource.org/licenses/MIT>, at your option. This file may not be\n// copied, modified, or distributed except according to those terms.\n\n//! Performs topological sorting.\n//!\n//! Vendored from https://github.com/gifnksm/topological-sort-rs\n\n#![warn(bad_style)]\n#![warn(missing_copy_implementations)]\n#![warn(missing_debug_implementations)]\n#![warn(missing_docs)]\n#![warn(trivial_casts)]\n#![warn(trivial_numeric_casts)]\n#![allow(unused)]\n#![warn(unused_extern_crates)]\n#![warn(unused_import_braces)]\n#![warn(unused_qualifications)]\n#![warn(unused_results)]\n#![warn(clippy::if_not_else)]\n#![warn(clippy::invalid_upcast_comparisons)]\n#![warn(clippy::items_after_statements)]\n#![warn(clippy::mut_mut)]\n#![warn(clippy::never_loop)]\n#![warn(clippy::nonminimal_bool)]\n#![warn(clippy::used_underscore_binding)]\n\nuse std::cmp::Ordering;\nuse std::collections::hash_map::Entry;\nuse std::collections::{HashMap, HashSet};\nuse std::fmt;\nuse std::hash::Hash;\nuse std::iter::FromIterator;\n\n#[derive(Clone)]\nstruct Dependency<T> {\n    num_prec: usize,\n    succ: HashSet<T>,\n}\n\nimpl<T: Hash + Eq> Dependency<T> {\n    fn new() -> Dependency<T> {\n        Dependency {\n            num_prec: 0,\n            succ: HashSet::new(),\n        }\n    }\n}\n\n/// Performs topological sorting.\n#[derive(Clone)]\npub struct TopologicalSort<T> {\n    top: HashMap<T, Dependency<T>>,\n}\n\nimpl<T> Default for TopologicalSort<T> {\n    fn default() -> TopologicalSort<T> {\n        TopologicalSort {\n            top: HashMap::new(),\n        }\n    }\n}\n\nimpl<T: Hash + Eq + Clone> TopologicalSort<T> {\n    #[inline]\n    pub fn new() -> TopologicalSort<T> {\n        Default::default()\n    }\n\n    /// Returns the number of elements in the `TopologicalSort`.\n    #[inline]\n    pub fn len(&self) -> usize {\n        self.top.len()\n    }\n\n    /// Returns true if the `TopologicalSort` contains no elements.\n    #[inline]\n    pub fn is_empty(&self) -> bool {\n        self.top.is_empty()\n    }\n\n    /// Registers the two elements' dependency.\n    ///\n    /// # Arguments\n    ///\n    /// * `prec` - The element appears before `succ`. `prec` is depended on by `succ`.\n    /// * `succ` - The element appears after `prec`. `succ` depends on `prec`.\n    pub fn add_dependency<P, S>(&mut self, prec: P, succ: S)\n    where\n        P: Into<T>,\n        S: Into<T>,\n    {\n        self.add_dependency_impl(prec.into(), succ.into())\n    }\n\n    fn add_dependency_impl(&mut self, prec: T, succ: T) {\n        match self.top.entry(prec) {\n            Entry::Vacant(e) => {\n                let mut dep = Dependency::new();\n                let _ = dep.succ.insert(succ.clone());\n                let _ = e.insert(dep);\n            }\n            Entry::Occupied(e) => {\n                if !e.into_mut().succ.insert(succ.clone()) {\n                    // Already registered\n                    return;\n                }\n            }\n        }\n\n        match self.top.entry(succ) {\n            Entry::Vacant(e) => {\n                let mut dep = Dependency::new();\n                dep.num_prec += 1;\n                let _ = e.insert(dep);\n            }\n            Entry::Occupied(e) => {\n                e.into_mut().num_prec += 1;\n            }\n        }\n    }\n\n    /// Registers a dependency link.\n    pub fn add_link(&mut self, link: DependencyLink<T>) {\n        self.add_dependency(link.prec, link.succ)\n    }\n\n    /// Inserts an element, without adding any dependencies from or to it.\n    ///\n    /// If the `TopologicalSort` did not have this element present, `true` is returned.\n    ///\n    /// If the `TopologicalSort` already had this element present, `false` is returned.\n    pub fn insert<U>(&mut self, elt: U) -> bool\n    where\n        U: Into<T>,\n    {\n        match self.top.entry(elt.into()) {\n            Entry::Vacant(e) => {\n                let dep = Dependency::new();\n                let _ = e.insert(dep);\n                true\n            }\n            Entry::Occupied(_) => false,\n        }\n    }\n\n    /// Removes the item that is not depended on by any other items and returns it, or `None` if\n    /// there is no such item.\n    ///\n    /// If `pop` returns `None` and `len` is not 0, there is cyclic dependencies.\n    pub fn pop(&mut self) -> Option<T> {\n        self.peek().cloned().inspect(|key| {\n            let _ = self.remove(key);\n        })\n    }\n\n    /// Removes all items that are not depended on by any other items and returns it, or empty\n    /// vector if there are no such items.\n    ///\n    /// If `pop_all` returns an empty vector and `len` is not 0, there is cyclic dependencies.\n    pub fn pop_all(&mut self) -> Vec<T> {\n        let keys = self\n            .top\n            .iter()\n            .filter(|&(_, v)| v.num_prec == 0)\n            .map(|(k, _)| k.clone())\n            .collect::<Vec<_>>();\n        for k in &keys {\n            let _ = self.remove(k);\n        }\n        keys\n    }\n\n    /// Return a reference to the first item that does not depend on any other items, or `None` if\n    /// there is no such item.\n    pub fn peek(&self) -> Option<&T> {\n        self.top\n            .iter()\n            .filter(|&(_, v)| v.num_prec == 0)\n            .map(|(k, _)| k)\n            .next()\n    }\n\n    /// Return a vector of references to all items that do not depend on any other items, or an\n    /// empty vector if there are no such items.\n    pub fn peek_all(&self) -> Vec<&T> {\n        self.top\n            .iter()\n            .filter(|&(_, v)| v.num_prec == 0)\n            .map(|(k, _)| k)\n            .collect::<Vec<_>>()\n    }\n\n    fn remove(&mut self, prec: &T) -> Option<Dependency<T>> {\n        let result = self.top.remove(prec);\n        if let Some(ref p) = result {\n            for s in &p.succ {\n                if let Some(y) = self.top.get_mut(s) {\n                    y.num_prec -= 1;\n                }\n            }\n        }\n        result\n    }\n}\n\nimpl<T: PartialOrd + Eq + Hash + Clone> FromIterator<T> for TopologicalSort<T> {\n    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> TopologicalSort<T> {\n        let mut top = TopologicalSort::new();\n        let mut seen = Vec::<T>::default();\n        for item in iter {\n            let _ = top.insert(item.clone());\n            for seen_item in seen.iter().cloned() {\n                match seen_item.partial_cmp(&item) {\n                    Some(Ordering::Less) => {\n                        top.add_dependency(seen_item, item.clone());\n                    }\n                    Some(Ordering::Greater) => {\n                        top.add_dependency(item.clone(), seen_item);\n                    }\n                    _ => (),\n                }\n            }\n            seen.push(item);\n        }\n        top\n    }\n}\n\n/// A link between two items in a sort.\n#[derive(Copy, Clone, Debug)]\npub struct DependencyLink<T> {\n    /// The element which is depened upon by `succ`.\n    pub prec: T,\n    /// The element which depends on `prec`.\n    pub succ: T,\n}\n\nimpl<T> From<(T, T)> for DependencyLink<T> {\n    fn from(tuple: (T, T)) -> Self {\n        DependencyLink {\n            succ: tuple.0,\n            prec: tuple.1,\n        }\n    }\n}\n\nimpl<T: Eq + Hash + Clone> FromIterator<DependencyLink<T>> for TopologicalSort<T> {\n    fn from_iter<I: IntoIterator<Item = DependencyLink<T>>>(iter: I) -> TopologicalSort<T> {\n        let mut top = TopologicalSort::new();\n        for link in iter {\n            top.add_link(link);\n        }\n        top\n    }\n}\n\nimpl<T: Hash + Eq + Clone> Iterator for TopologicalSort<T> {\n    type Item = T;\n\n    fn next(&mut self) -> Option<T> {\n        self.pop()\n    }\n}\n\nimpl<T: fmt::Debug + Hash + Eq> fmt::Debug for Dependency<T> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"prec={}, succ={:?}\", self.num_prec, self.succ)\n    }\n}\n\nimpl<T: fmt::Debug + Hash + Eq + Clone> fmt::Debug for TopologicalSort<T> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"{:?}\", self.top)\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::TopologicalSort;\n    use std::iter::FromIterator;\n\n    #[test]\n    fn from_iter() {\n        let t = vec![4, 3, 3, 5, 7, 6, 8];\n        let mut ts = TopologicalSort::<i32>::from_iter(t);\n        assert_eq!(Some(3), ts.next());\n        assert_eq!(Some(4), ts.next());\n        assert_eq!(Some(5), ts.next());\n        assert_eq!(Some(6), ts.next());\n        assert_eq!(Some(7), ts.next());\n        assert_eq!(Some(8), ts.next());\n        assert_eq!(None, ts.next());\n    }\n\n    #[test]\n    fn iter() {\n        let mut ts = TopologicalSort::<i32>::new();\n        ts.add_dependency(1, 2);\n        ts.add_dependency(2, 3);\n        ts.add_dependency(3, 4);\n        assert_eq!(Some(1), ts.next());\n        assert_eq!(Some(2), ts.next());\n        assert_eq!(Some(3), ts.next());\n        assert_eq!(Some(4), ts.next());\n        assert_eq!(None, ts.next());\n    }\n\n    #[test]\n    fn pop_all() {\n        fn check(result: &[i32], ts: &mut TopologicalSort<i32>) {\n            let l = ts.len();\n            let mut v = ts.pop_all();\n            v.sort();\n            assert_eq!(result, &v[..]);\n            assert_eq!(l - result.len(), ts.len());\n        }\n\n        let mut ts = TopologicalSort::new();\n        ts.add_dependency(7, 11);\n        assert_eq!(2, ts.len());\n        ts.add_dependency(7, 8);\n        assert_eq!(3, ts.len());\n        ts.add_dependency(5, 11);\n        assert_eq!(4, ts.len());\n        ts.add_dependency(3, 8);\n        assert_eq!(5, ts.len());\n        ts.add_dependency(3, 10);\n        assert_eq!(6, ts.len());\n        ts.add_dependency(11, 2);\n        assert_eq!(7, ts.len());\n        ts.add_dependency(11, 9);\n        assert_eq!(8, ts.len());\n        ts.add_dependency(11, 10);\n        assert_eq!(8, ts.len());\n        ts.add_dependency(8, 9);\n        assert_eq!(8, ts.len());\n\n        check(&[3, 5, 7], &mut ts);\n        check(&[8, 11], &mut ts);\n        check(&[2, 9, 10], &mut ts);\n        check(&[], &mut ts);\n    }\n\n    #[test]\n    fn cyclic_deadlock() {\n        let mut ts = TopologicalSort::new();\n        ts.add_dependency(\"stone\", \"sharp\");\n\n        ts.add_dependency(\"bucket\", \"hole\");\n        ts.add_dependency(\"hole\", \"straw\");\n        ts.add_dependency(\"straw\", \"axe\");\n        ts.add_dependency(\"axe\", \"sharp\");\n        ts.add_dependency(\"sharp\", \"water\");\n        ts.add_dependency(\"water\", \"bucket\");\n        assert_eq!(ts.pop(), Some(\"stone\"));\n        assert!(ts.pop().is_none());\n        println!(\"{:?}\", ts);\n    }\n\n    #[allow(dead_code)]\n    fn topo_test_quickcheck(n: usize, edges: Vec<(usize, usize)>) {\n        use std::collections::{HashMap, HashSet};\n\n        let n = n.clamp(1, 1000);\n        let mut marked = vec![false; n];\n        let edges = edges\n            .into_iter()\n            .map(|(x, y)| (x % n, y % n))\n            .collect::<Vec<_>>();\n        let mut deps = HashMap::new();\n        let mut toposort = TopologicalSort::<usize>::new();\n\n        for i in 0..n {\n            let _ = deps.insert(i, HashSet::new());\n            assert!(toposort.insert(i));\n        }\n\n        for (op, inp) in edges.iter().map(|(x, y)| (y, x)) {\n            let inps = deps.get_mut(op).unwrap();\n            let _ = inps.insert(*inp);\n        }\n\n        let deps = deps;\n        for (inp, op) in edges {\n            toposort.add_dependency(inp, op);\n        }\n        while let Some(x) = toposort.pop() {\n            for dep in deps.get(&x).unwrap().iter() {\n                assert!(marked[*dep]);\n            }\n            marked[x] = true;\n        }\n\n        if toposort.is_empty() {\n            assert!(marked.into_iter().all(|x| x));\n        } else {\n            let dep_fixed = {\n                let mut ret = (0..n)\n                    .map(|i| (i, HashSet::new()))\n                    .collect::<HashMap<_, _>>();\n                let mut new_to_add = deps;\n\n                while !new_to_add.is_empty() {\n                    for (k, v) in new_to_add.drain() {\n                        let inps = ret.get_mut(&k).unwrap();\n                        inps.extend(v.into_iter());\n                    }\n                    for (k, vs) in ret.iter() {\n                        for k2 in vs.iter() {\n                            for v2 in ret.get(k2).unwrap().iter() {\n                                if !vs.contains(v2) {\n                                    let _ = new_to_add\n                                        .entry(*k)\n                                        .or_insert_with(HashSet::new)\n                                        .insert(*v2);\n                                }\n                            }\n                        }\n                    }\n                }\n\n                ret\n            };\n\n            assert!(dep_fixed.into_iter().any(|(op, deps)| deps.contains(&op)));\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/cake.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[cfg(feature = \"with-json\")]\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(has_one)]\n    pub fruit: HasOne<super::fruit::Entity>,\n    #[sea_orm(has_many, via = \"cake_filling\")]\n    pub fillings: HasMany<super::filling::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/cake_compact.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[cfg(feature = \"with-json\")]\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_name = \"name\", enum_name = \"Name\")]\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n    #[sea_orm(\n        has_many = \"super::fruit::Entity\",\n        on_condition = r#\"super::fruit::Column::Name.like(\"%tropical%\")\"#\n    )]\n    TropicalFruit,\n    #[sea_orm(\n        has_many = \"super::fruit::Entity\",\n        condition_type = \"any\",\n        on_condition = r#\"super::fruit::Column::Name.like(\"%tropical%\")\"#\n    )]\n    OrTropicalFruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/cake_expanded.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> &'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::None).def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/cake_filling.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::compact_model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake_filling\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub filling_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Cake,\n    #[sea_orm(\n        belongs_to = \"super::filling::Entity\",\n        from = \"Column::FillingId\",\n        to = \"super::filling::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Filling,\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Filling.def()\n    }\n}\n\nimpl Related<super::cake_filling_price::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling_price::Relation::CakeFilling.def().rev()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/cake_filling_price.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"public\", table_name = \"cake_filling_price\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub filling_id: i32,\n    #[cfg(feature = \"with-rust_decimal\")]\n    #[sea_orm(extra = \"CHECK (price > 0)\")]\n    pub price: Decimal,\n    #[sea_orm(ignore)]\n    pub ignored_attr: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake_filling::Entity\",\n        from = \"(Column::CakeId, Column::FillingId)\",\n        to = \"(super::cake_filling::Column::CakeId, super::cake_filling::Column::FillingId)\"\n    )]\n    CakeFilling,\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n        skip_fk\n    )]\n    Cake,\n}\n\nimpl Related<super::cake_filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::CakeFilling.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/cake_seaography.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_name = \"name\", enum_name = \"Name\")]\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n    #[sea_orm(\n        has_many = \"super::fruit::Entity\",\n        on_condition = r#\"super::fruit::Column::Name.like(\"%tropical%\")\"#\n    )]\n    TropicalFruit,\n    #[sea_orm(\n        has_many = \"super::fruit::Entity\",\n        condition_type = \"any\",\n        on_condition = r#\"super::fruit::Column::Name.like(\"%tropical%\")\"#\n    )]\n    OrTropicalFruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]\npub enum RelatedEntity {\n    #[sea_orm(entity = \"super::fruit::Entity\")]\n    Fruit,\n    #[sea_orm(entity = \"super::filling::Entity\")]\n    Filling,\n    #[sea_orm(\n        entity = \"super::fruit::Entity\",\n        def = \"Relation::TropicalFruit.def()\"\n    )]\n    TropicalFruit,\n    #[sea_orm(\n        entity = \"super::fruit::Entity\",\n        def = \"Relation::OrTropicalFruit.def()\"\n    )]\n    OrTropicalFruit,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/comment.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"comment\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub comment: String,\n    pub user_id: i32,\n    pub post_id: i32,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub user: HasOne<super::user::Entity>,\n    #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n    pub post: HasOne<super::post::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/entity_linked.rs",
    "content": "use crate::entity::prelude::*;\nuse sea_query::{Expr, ExprTrait, IntoCondition};\n\n#[derive(Debug)]\npub struct CakeToFilling;\n\nimpl Linked for CakeToFilling {\n    type FromEntity = super::cake::Entity;\n\n    type ToEntity = super::filling::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![\n            super::cake_filling::Relation::Cake.def().rev(),\n            super::cake_filling::Relation::Filling.def(),\n        ]\n    }\n}\n\n#[derive(Debug)]\npub struct CakeToFillingVendor;\n\nimpl Linked for CakeToFillingVendor {\n    type FromEntity = super::cake::Entity;\n\n    type ToEntity = super::vendor::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![\n            super::cake_filling::Relation::Cake.def().rev(),\n            super::cake_filling::Relation::Filling.def(),\n            super::filling::Relation::Vendor.def(),\n        ]\n    }\n}\n\n#[derive(Debug)]\npub struct CheeseCakeToFillingVendor;\n\nimpl Linked for CheeseCakeToFillingVendor {\n    type FromEntity = super::cake::Entity;\n\n    type ToEntity = super::vendor::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![\n            super::cake_filling::Relation::Cake\n                .def()\n                .on_condition(|left, _right| {\n                    Expr::col((left, super::cake::Column::Name))\n                        .like(\"%cheese%\")\n                        .into_condition()\n                })\n                .rev(),\n            super::cake_filling::Relation::Filling.def(),\n            super::filling::Relation::Vendor.def(),\n        ]\n    }\n}\n\n#[derive(Debug)]\npub struct CakeToCakeViaFilling;\n\nimpl Linked for CakeToCakeViaFilling {\n    type FromEntity = super::cake::Entity;\n\n    type ToEntity = super::cake::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![\n            super::cake_filling::Relation::Cake.def().rev(),\n            super::cake_filling::Relation::Filling.def(),\n            super::cake_filling::Relation::Filling.def().rev(),\n            super::cake_filling::Relation::Cake.def(),\n        ]\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/filling.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[cfg(feature = \"with-json\")]\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::compact_model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n#[sea_orm(table_name = \"filling\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub vendor_id: Option<i32>,\n    #[sea_orm(ignore)]\n    pub ignored_attr: i32,\n    pub ingredients: HasMany<super::ingredient::Entity>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::vendor::Entity\",\n        from = \"Column::VendorId\",\n        to = \"super::vendor::Column::Id\"\n    )]\n    Vendor,\n    #[sea_orm(has_many = \"super::ingredient::Entity\")]\n    Ingredient,\n}\n\nimpl Related<super::ingredient::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Ingredient.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Cake.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Filling.def().rev())\n    }\n}\n\nimpl Related<super::cake_compact::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Cake.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Filling.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/fruit.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[cfg(feature = \"with-json\")]\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::compact_model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n#[sea_orm(table_name = \"fruit\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[cfg_attr(feature = \"with-json\", serde(skip_deserializing))]\n    pub id: i32,\n    pub name: String,\n    pub cake_id: Option<i32>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\"\n    )]\n    Cake,\n    #[sea_orm(\n        belongs_to = \"super::cake_compact::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake_compact::Column::Id\"\n    )]\n    CakeCompact,\n    #[sea_orm(\n        belongs_to = \"super::cake_expanded::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake_expanded::Column::Id\"\n    )]\n    CakeExpanded,\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl Related<super::cake_compact::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::CakeCompact.def()\n    }\n}\n\nimpl Related<super::cake_expanded::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::CakeExpanded.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/indexes.rs",
    "content": "//! An entity definition for testing table index creation.\nuse crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"public\", table_name = \"indexes\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub indexes_id: i32,\n    #[sea_orm(unique)]\n    pub unique_attr: i32,\n    #[sea_orm(indexed)]\n    pub index1_attr: i32,\n    #[sea_orm(unique, indexed)]\n    pub index2_attr: i32,\n    #[sea_orm(unique_key = \"my_unique\")]\n    pub unique_key_a: String,\n    #[sea_orm(unique_key = \"my_unique\")]\n    pub unique_key_b: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/ingredient.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[cfg(feature = \"with-json\")]\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n#[sea_orm(table_name = \"ingredient\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub filling_id: Option<i32>,\n    pub ingredient_id: Option<i32>,\n    #[sea_orm(belongs_to, from = \"filling_id\", to = \"id\")]\n    pub filling: HasOne<super::filling::Entity>,\n    #[sea_orm(\n        self_ref,\n        relation_enum = \"Ingredient\",\n        from = \"IngredientId\",\n        to = \"Id\"\n    )]\n    pub ingredient: HasOne<Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/lunch_set.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"lunch_set\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub tea: Tea,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/lunch_set_expanded.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> &'static str {\n        \"lunch_set\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n#[sea_orm(table_name = \"lunch_set\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub tea: Tea,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n    Tea,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::None).def(),\n            Self::Tea => Tea::db_type().def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        panic!(\"No RelationDef\")\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/mod.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\n//! Configurations for test cases and examples. Not intended for actual use.\n\n#[cfg(feature = \"entity-registry\")]\nmod registry;\n\npub mod cake;\npub mod cake_compact;\npub mod cake_expanded;\npub mod cake_filling;\npub mod cake_filling_price;\npub mod entity_linked;\npub mod filling;\npub mod fruit;\npub mod indexes;\npub mod ingredient;\npub mod lunch_set;\npub mod lunch_set_expanded;\npub mod rust_keyword;\npub mod sea_orm_active_enums;\n#[cfg(feature = \"with-json\")]\npub mod serde_rename;\npub mod vendor;\n\npub mod comment;\npub mod post;\npub mod post_tag;\npub mod profile;\npub mod tag;\npub mod user;\n\npub use cake::Entity as Cake;\npub use cake_filling::Entity as CakeFilling;\npub use cake_filling_price::Entity as CakeFillingPrice;\npub use filling::Entity as Filling;\npub use fruit::Entity as Fruit;\npub use lunch_set::Entity as LunchSet;\npub use lunch_set_expanded::Entity as LunchSetExpanded;\npub use rust_keyword::Entity as RustKeyword;\npub use vendor::Entity as Vendor;\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/post.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"post\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub user_id: i32,\n    pub title: String,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub author: HasOne<super::user::Entity>,\n    #[sea_orm(has_many)]\n    pub comments: HasMany<super::comment::Entity>,\n    #[sea_orm(has_many, via = \"post_tag\")]\n    pub tags: HasMany<super::tag::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/post_tag.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n#[sea_orm(table_name = \"post_tag\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub post_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub tag_id: i32,\n    #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n    pub post: Option<super::post::Entity>,\n    #[sea_orm(belongs_to, from = \"tag_id\", to = \"id\")]\n    pub tag: Option<super::tag::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/profile.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"profile\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub picture: String,\n    #[sea_orm(unique)]\n    pub user_id: i32,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub user: HasOne<super::user::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/registry.rs",
    "content": "#[cfg(test)]\nmod test {\n    #[test]\n    fn test_entity_registry() {\n        let entities: Vec<_> = inventory::iter::<crate::EntityRegistry>().collect();\n\n        for target in [\n            \"sea_orm::tests_cfg::cake\",\n            \"sea_orm::tests_cfg::cake_compact\",\n            \"sea_orm::tests_cfg::cake_expanded\",\n            \"sea_orm::tests_cfg::cake_filling\",\n            \"sea_orm::tests_cfg::cake_filling_price\",\n            \"sea_orm::tests_cfg::filling\",\n            \"sea_orm::tests_cfg::fruit\",\n            \"sea_orm::tests_cfg::indexes\",\n            \"sea_orm::tests_cfg::ingredient\",\n            \"sea_orm::tests_cfg::lunch_set\",\n            \"sea_orm::tests_cfg::lunch_set_expanded\",\n            \"sea_orm::tests_cfg::rust_keyword\",\n            \"sea_orm::tests_cfg::vendor\",\n        ] {\n            if !entities.iter().any(|e| e.module_path == target) {\n                panic!(\"{target} not found\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/rust_keyword.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"rust_keyword\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub testing: i32,\n    pub rust: i32,\n    pub keywords: i32,\n    pub r#raw_identifier: i32,\n    pub r#as: i32,\n    pub r#async: i32,\n    pub r#await: i32,\n    pub r#break: i32,\n    pub r#const: i32,\n    pub r#continue: i32,\n    pub crate_: i32,\n    pub r#dyn: i32,\n    pub r#else: i32,\n    pub r#enum: i32,\n    pub r#extern: i32,\n    pub r#false: i32,\n    pub r#fn: i32,\n    pub r#for: i32,\n    pub r#if: i32,\n    pub r#impl: i32,\n    pub r#in: i32,\n    pub r#let: i32,\n    pub r#loop: i32,\n    pub r#match: i32,\n    pub r#mod: i32,\n    pub r#move: i32,\n    pub r#mut: i32,\n    pub r#pub: i32,\n    pub r#ref: i32,\n    pub r#return: i32,\n    pub self_: i32,\n    pub r#static: i32,\n    pub r#struct: i32,\n    pub r#trait: i32,\n    pub r#true: i32,\n    pub r#type: i32,\n    pub r#union: i32,\n    pub r#unsafe: i32,\n    pub r#use: i32,\n    pub r#where: i32,\n    pub r#while: i32,\n    pub r#abstract: i32,\n    pub r#become: i32,\n    pub r#box: i32,\n    pub r#do: i32,\n    pub r#final: i32,\n    pub r#macro: i32,\n    pub r#override: i32,\n    pub r#priv: i32,\n    pub r#try: i32,\n    pub r#typeof: i32,\n    pub r#unsized: i32,\n    pub r#virtual: i32,\n    pub r#yield: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::rust_keyword::*;\n    use sea_query::Iden;\n\n    #[test]\n    fn test_columns() {\n        assert_eq!(Column::Id.to_string().as_str(), \"id\");\n        assert_eq!(Column::Testing.to_string().as_str(), \"testing\");\n        assert_eq!(Column::Rust.to_string().as_str(), \"rust\");\n        assert_eq!(Column::Keywords.to_string().as_str(), \"keywords\");\n        assert_eq!(Column::RawIdentifier.to_string().as_str(), \"raw_identifier\");\n        assert_eq!(Column::As.to_string().as_str(), \"as\");\n        assert_eq!(Column::Async.to_string().as_str(), \"async\");\n        assert_eq!(Column::Await.to_string().as_str(), \"await\");\n        assert_eq!(Column::Break.to_string().as_str(), \"break\");\n        assert_eq!(Column::Const.to_string().as_str(), \"const\");\n        assert_eq!(Column::Continue.to_string().as_str(), \"continue\");\n        assert_eq!(Column::Dyn.to_string().as_str(), \"dyn\");\n        assert_eq!(Column::Crate.to_string().as_str(), \"crate\");\n        assert_eq!(Column::Else.to_string().as_str(), \"else\");\n        assert_eq!(Column::Enum.to_string().as_str(), \"enum\");\n        assert_eq!(Column::Extern.to_string().as_str(), \"extern\");\n        assert_eq!(Column::False.to_string().as_str(), \"false\");\n        assert_eq!(Column::Fn.to_string().as_str(), \"fn\");\n        assert_eq!(Column::For.to_string().as_str(), \"for\");\n        assert_eq!(Column::If.to_string().as_str(), \"if\");\n        assert_eq!(Column::Impl.to_string().as_str(), \"impl\");\n        assert_eq!(Column::In.to_string().as_str(), \"in\");\n        assert_eq!(Column::Let.to_string().as_str(), \"let\");\n        assert_eq!(Column::Loop.to_string().as_str(), \"loop\");\n        assert_eq!(Column::Match.to_string().as_str(), \"match\");\n        assert_eq!(Column::Mod.to_string().as_str(), \"mod\");\n        assert_eq!(Column::Move.to_string().as_str(), \"move\");\n        assert_eq!(Column::Mut.to_string().as_str(), \"mut\");\n        assert_eq!(Column::Pub.to_string().as_str(), \"pub\");\n        assert_eq!(Column::Ref.to_string().as_str(), \"ref\");\n        assert_eq!(Column::Return.to_string().as_str(), \"return\");\n        assert_eq!(Column::Self_.to_string().as_str(), \"self\");\n        assert_eq!(Column::Static.to_string().as_str(), \"static\");\n        assert_eq!(Column::Struct.to_string().as_str(), \"struct\");\n        assert_eq!(Column::Trait.to_string().as_str(), \"trait\");\n        assert_eq!(Column::True.to_string().as_str(), \"true\");\n        assert_eq!(Column::Type.to_string().as_str(), \"type\");\n        assert_eq!(Column::Union.to_string().as_str(), \"union\");\n        assert_eq!(Column::Unsafe.to_string().as_str(), \"unsafe\");\n        assert_eq!(Column::Use.to_string().as_str(), \"use\");\n        assert_eq!(Column::Where.to_string().as_str(), \"where\");\n        assert_eq!(Column::While.to_string().as_str(), \"while\");\n        assert_eq!(Column::Abstract.to_string().as_str(), \"abstract\");\n        assert_eq!(Column::Become.to_string().as_str(), \"become\");\n        assert_eq!(Column::Box.to_string().as_str(), \"box\");\n        assert_eq!(Column::Do.to_string().as_str(), \"do\");\n        assert_eq!(Column::Final.to_string().as_str(), \"final\");\n        assert_eq!(Column::Macro.to_string().as_str(), \"macro\");\n        assert_eq!(Column::Override.to_string().as_str(), \"override\");\n        assert_eq!(Column::Priv.to_string().as_str(), \"priv\");\n        assert_eq!(Column::Try.to_string().as_str(), \"try\");\n        assert_eq!(Column::Typeof.to_string().as_str(), \"typeof\");\n        assert_eq!(Column::Unsized.to_string().as_str(), \"unsized\");\n        assert_eq!(Column::Virtual.to_string().as_str(), \"virtual\");\n        assert_eq!(Column::Yield.to_string().as_str(), \"yield\");\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/sea_orm_active_enums.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"tea\")]\npub enum Tea {\n    #[sea_orm(string_value = \"EverydayTea\")]\n    EverydayTea,\n    #[sea_orm(string_value = \"BreakfastTea\")]\n    BreakfastTea,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"String\", db_type = \"String(StringLen::None)\")]\npub enum SeaORM {\n    #[sea_orm(string_value = \"씨오알엠\")]\n    씨오알엠,\n}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/serde_rename.rs",
    "content": "#![allow(clippy::unwrap_used)]\nuse crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[cfg(feature = \"with-json\")]\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n#[sea_orm(table_name = \"user\")]\n#[cfg_attr(feature = \"with-json\", serde(rename_all = \"camelCase\"))]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub first_name: String,\n    pub last_name: String,\n    pub email: String,\n    pub is_admin: bool,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\npub mod field_rename {\n    use crate as sea_orm;\n    use sea_orm::entity::prelude::*;\n\n    #[cfg(feature = \"with-json\")]\n    use serde::{Deserialize, Serialize};\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n    #[sea_orm(table_name = \"order\")]\n    #[cfg_attr(\n        feature = \"with-json\",\n        serde(rename_all = \"camelCase\", rename = \"Model\")\n    )]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub order_date: String,\n        // #[serde(rename = \"...\")] applies to both serialize and deserialize\n        #[cfg_attr(feature = \"with-json\", serde(rename = \"order-id\"))]\n        pub order_id: String,\n        // serialize only - does not affect json_key (uses camelCase)\n        #[cfg_attr(feature = \"with-json\", serde(rename(serialize = \"serializedOnly\")))]\n        pub ser_only: String,\n        // deserialize only - affects json_key\n        #[cfg_attr(feature = \"with-json\", serde(rename(deserialize = \"deOnly\")))]\n        pub de_only: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod no_serde_rename {\n    use crate as sea_orm;\n    use sea_orm::entity::prelude::*;\n\n    #[cfg(feature = \"with-json\")]\n    use serde::{Deserialize, Serialize};\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n    #[sea_orm(table_name = \"legacy\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub field_name: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod directional_rename_all {\n    use crate as sea_orm;\n    use sea_orm::entity::prelude::*;\n\n    #[cfg(feature = \"with-json\")]\n    use serde::{Deserialize, Serialize};\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n    #[sea_orm(table_name = \"directional\")]\n    #[cfg_attr(\n        feature = \"with-json\",\n        serde(rename_all(serialize = \"SCREAMING_SNAKE_CASE\", deserialize = \"camelCase\"))\n    )]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub user_name: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[cfg(all(test, feature = \"with-json\"))]\nmod tests {\n    use super::*;\n    use crate::ActiveValue;\n    use crate::entity::ActiveModelTrait;\n\n    #[test]\n    fn test_rename_all() {\n        // json_key returns camelCase names\n        assert_eq!(Column::Id.json_key(), \"id\");\n        assert_eq!(Column::FirstName.json_key(), \"firstName\");\n        assert_eq!(Column::LastName.json_key(), \"lastName\");\n        assert_eq!(Column::Email.json_key(), \"email\");\n        assert_eq!(Column::IsAdmin.json_key(), \"isAdmin\");\n\n        // from_json uses camelCase keys\n        let json = serde_json::json!({\n            \"id\": 1,\n            \"firstName\": \"Max\",\n            \"lastName\": \"Hermit\",\n            \"email\": \"max@domain.com\",\n            \"isAdmin\": true,\n        });\n\n        let am = ActiveModel::from_json(json).unwrap();\n\n        assert_eq!(am.id, ActiveValue::Set(1));\n        assert_eq!(am.first_name, ActiveValue::Set(\"Max\".to_string()));\n        assert_eq!(am.last_name, ActiveValue::Set(\"Hermit\".to_string()));\n        assert_eq!(am.email, ActiveValue::Set(\"max@domain.com\".to_string()));\n        assert_eq!(am.is_admin, ActiveValue::Set(true));\n    }\n\n    #[test]\n    fn test_field_rename() {\n        use field_rename::{ActiveModel, Column};\n\n        // json_key behavior:\n        // - rename = \"...\" uses that name\n        // - rename(deserialize = \"...\") uses deserialize name\n        // - rename(serialize = \"...\") falls back to rename_all\n        assert_eq!(Column::Id.json_key(), \"id\");\n        assert_eq!(Column::OrderDate.json_key(), \"orderDate\");\n        assert_eq!(Column::OrderId.json_key(), \"order-id\");\n        assert_eq!(Column::SerOnly.json_key(), \"serOnly\"); // camelCase, not \"serializedOnly\"\n        assert_eq!(Column::DeOnly.json_key(), \"deOnly\");\n\n        // from_json uses deserialize names\n        let json = serde_json::json!({\n            \"id\": 1,\n            \"orderDate\": \"2024-01-01\",\n            \"order-id\": \"ORD123\",\n            \"serOnly\": \"ser-value\",\n            \"deOnly\": \"de-value\"\n        });\n\n        let am = ActiveModel::from_json(json).unwrap();\n\n        assert_eq!(am.id, ActiveValue::Set(1));\n        assert_eq!(am.order_date, ActiveValue::Set(\"2024-01-01\".to_string()));\n        assert_eq!(am.order_id, ActiveValue::Set(\"ORD123\".to_string()));\n        assert_eq!(am.ser_only, ActiveValue::Set(\"ser-value\".to_string()));\n        assert_eq!(am.de_only, ActiveValue::Set(\"de-value\".to_string()));\n    }\n\n    #[test]\n    fn test_no_serde_rename() {\n        use no_serde_rename::{ActiveModel, Column};\n\n        assert_eq!(Column::Id.json_key(), \"id\");\n        assert_eq!(Column::FieldName.json_key(), \"field_name\");\n\n        let json = serde_json::json!({\n            \"id\": 1,\n            \"field_name\": \"value\"\n        });\n\n        let am = ActiveModel::from_json(json).unwrap();\n\n        assert_eq!(am.id, ActiveValue::Set(1));\n        assert_eq!(am.field_name, ActiveValue::Set(\"value\".to_string()));\n    }\n\n    #[test]\n    fn test_directional_rename_all() {\n        use directional_rename_all::{ActiveModel, Column, Model};\n\n        assert_eq!(Column::Id.json_key(), \"id\");\n        assert_eq!(Column::UserName.json_key(), \"userName\");\n\n        let json = serde_json::json!({\n            \"id\": 1,\n            \"userName\": \"test_user\"\n        });\n\n        let am = ActiveModel::from_json(json).unwrap();\n\n        assert_eq!(am.id, ActiveValue::Set(1));\n        assert_eq!(am.user_name, ActiveValue::Set(\"test_user\".to_string()));\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/tag.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"tag\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub tag: String,\n    #[sea_orm(has_many, via = \"post_tag\")]\n    pub posts: HasMany<super::post::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/user.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"user\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(unique)]\n    pub email: String,\n    #[sea_orm(has_one)]\n    pub profile: HasOne<super::profile::Entity>,\n    #[sea_orm(has_many)]\n    pub posts: HasMany<super::post::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/tests_cfg/vendor.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"vendor\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::filling::Relation::Vendor.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/src/util.rs",
    "content": "/// Uses the `log` crate to perform logging.\n/// This must be enabled using the feature flag `debug-print`.\n/// ### Usage\n/// ```\n/// use sea_orm::debug_print;\n///\n/// #[derive(Debug)]\n/// enum FooError {\n///     Bar,\n///     Baz,\n/// }\n///\n/// debug_print!(\"{:?}\", FooError::Bar);\n/// ```\n#[macro_export]\n#[cfg(feature = \"debug-print\")]\nmacro_rules! debug_print {\n    ($( $args:expr ),*) => { tracing::debug!( $( $args ),* ); }\n}\n\n#[macro_export]\n/// Non-debug version\n#[cfg(not(feature = \"debug-print\"))]\nmacro_rules! debug_print {\n    ($( $args:expr ),*) => {\n        true;\n    };\n}\n\n#[cfg(all(test, feature = \"sync\"))]\npub trait StreamShim<T> {\n    fn try_next(&mut self) -> Result<Option<T>, crate::DbErr>;\n}\n\n#[cfg(all(test, feature = \"sync\"))]\nimpl<I, T> StreamShim<T> for I\nwhere\n    I: Iterator<Item = Result<T, crate::DbErr>>,\n{\n    fn try_next(&mut self) -> Result<Option<T>, crate::DbErr> {\n        self.next().transpose()\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/value/text_uuid.rs",
    "content": "use std::ops::{Deref, DerefMut};\n\nuse sea_query::{ValueType, ValueTypeErr};\n\nuse crate::TryGetable;\nuse crate::{self as sea_orm, TryFromU64};\nuse crate::{DbErr, TryGetError};\n\n/// Newtype making sure that UUIDs will be stored as `TEXT` columns,\n/// instead of `BLOB` (which is the default).\n/// Advantages:\n/// - TEXT makes it easier to interact with the SQLite DB directly\n/// - Allows for queries like `WHERE id IN (<uuid>, <uuid>, ...)` which are\n///   impossible to write with `BLOB` values\n#[derive(Clone, Debug, PartialEq, Eq, Copy)]\npub struct TextUuid(pub uuid::Uuid);\n\nimpl From<TextUuid> for sea_query::Value {\n    fn from(value: TextUuid) -> Self {\n        value.0.to_string().into()\n    }\n}\n\nimpl TryGetable for TextUuid {\n    fn try_get_by<I: sea_orm::ColIdx>(\n        res: &sea_orm::QueryResult,\n        index: I,\n    ) -> Result<Self, sea_orm::TryGetError> {\n        let uuid_str: String = res.try_get_by(index)?;\n        let uuid = uuid::Uuid::parse_str(&uuid_str).map_err(|e| {\n            TryGetError::DbErr(DbErr::Type(format!(\"Failed to parse string as UUID: {e}\")))\n        })?;\n        Ok(TextUuid(uuid))\n    }\n}\n\nimpl ValueType for TextUuid {\n    fn try_from(v: sea_orm::Value) -> Result<Self, ValueTypeErr> {\n        match v {\n            sea_orm::Value::String(Some(s)) => {\n                let uuid = uuid::Uuid::parse_str(&s).map_err(|_| ValueTypeErr)?;\n                Ok(TextUuid(uuid))\n            }\n            _ => Err(ValueTypeErr),\n        }\n    }\n\n    fn type_name() -> String {\n        \"TextUuid\".to_string()\n    }\n\n    fn array_type() -> sea_query::ArrayType {\n        <String as sea_query::ValueType>::array_type()\n    }\n\n    fn column_type() -> sea_orm::ColumnType {\n        <String as sea_query::ValueType>::column_type()\n    }\n}\n\n// This seems to be required when using TextUuid as a primary key\nimpl TryFromU64 for TextUuid {\n    fn try_from_u64(_n: u64) -> Result<Self, sea_orm::DbErr> {\n        Err(sea_orm::DbErr::ConvertFromU64(\"TextUuid\"))\n    }\n}\n\nimpl sea_query::Nullable for TextUuid {\n    fn null() -> sea_orm::Value {\n        <String as sea_query::Nullable>::null()\n    }\n}\n\nimpl sea_orm::IntoActiveValue<TextUuid> for TextUuid {\n    fn into_active_value(self) -> crate::ActiveValue<TextUuid> {\n        sea_orm::ActiveValue::Set(self)\n    }\n}\n\nimpl Deref for TextUuid {\n    type Target = uuid::Uuid;\n\n    fn deref(&self) -> &uuid::Uuid {\n        &self.0\n    }\n}\n\nimpl DerefMut for TextUuid {\n    fn deref_mut(&mut self) -> &mut uuid::Uuid {\n        &mut self.0\n    }\n}\n\nimpl From<uuid::Uuid> for TextUuid {\n    fn from(value: uuid::Uuid) -> Self {\n        TextUuid(value)\n    }\n}\n\nimpl From<TextUuid> for uuid::Uuid {\n    fn from(value: TextUuid) -> Self {\n        value.0\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/src/value/timestamp.rs",
    "content": "macro_rules! impl_timestamp {\n    ($ty:ident, $inner:ident, $from:ident, $to:ident) => {\n        impl std::convert::From<$inner> for $ty {\n            fn from(value: $inner) -> Self {\n                Self(value)\n            }\n        }\n\n        impl std::convert::From<$ty> for sea_orm::Value {\n            fn from(source: $ty) -> Self {\n                $to(source).into()\n            }\n        }\n\n        impl sea_orm::TryGetable for $ty {\n            fn try_get_by<I: sea_orm::ColIdx>(\n                res: &sea_orm::QueryResult,\n                idx: I,\n            ) -> std::result::Result<Self, TryGetError> {\n                let ts = <i64 as sea_orm::TryGetable>::try_get_by(res, idx)?;\n                $from(ts).ok_or(TryGetError::DbErr(DbErr::Type(\n                    \"Failed to convert i64 to timestamp\".to_owned(),\n                )))\n            }\n        }\n\n        impl sea_orm::sea_query::ValueType for $ty {\n            fn try_from(\n                v: sea_orm::Value,\n            ) -> std::result::Result<Self, sea_orm::sea_query::ValueTypeErr> {\n                let ts = <i64 as sea_orm::sea_query::ValueType>::try_from(v)?;\n                $from(ts).ok_or(sea_orm::sea_query::ValueTypeErr)\n            }\n\n            fn type_name() -> std::string::String {\n                stringify!($ty).to_owned()\n            }\n\n            fn array_type() -> sea_orm::sea_query::ArrayType {\n                <i64 as sea_orm::sea_query::ValueType>::array_type()\n            }\n\n            fn column_type() -> sea_orm::sea_query::ColumnType {\n                <i64 as sea_orm::sea_query::ValueType>::column_type()\n            }\n        }\n\n        impl sea_orm::sea_query::Nullable for $ty {\n            fn null() -> sea_orm::Value {\n                <i64 as sea_orm::sea_query::Nullable>::null()\n            }\n        }\n\n        impl sea_orm::IntoActiveValue<$ty> for $ty {\n            fn into_active_value(self) -> sea_orm::ActiveValue<$ty> {\n                sea_orm::ActiveValue::Set(self)\n            }\n        }\n\n        impl Deref for $ty {\n            type Target = $inner;\n\n            fn deref(&self) -> &Self::Target {\n                &self.0\n            }\n        }\n\n        impl DerefMut for $ty {\n            fn deref_mut(&mut self) -> &mut Self::Target {\n                &mut self.0\n            }\n        }\n\n        impl PartialEq<$inner> for $ty {\n            fn eq(&self, other: &$inner) -> bool {\n                self.0.eq(other)\n            }\n        }\n    };\n}\n\npub(super) use impl_timestamp;\n"
  },
  {
    "path": "sea-orm-sync/src/value/with_chrono.rs",
    "content": "use super::impl_timestamp;\nuse crate as sea_orm;\nuse crate::{DbErr, TryGetError, prelude::ChronoDateTimeUtc};\nuse std::ops::{Deref, DerefMut};\n\n/// A DataTime<Utc> mapped to i64 in database\n#[derive(derive_more::Debug, Copy, Clone, PartialEq, Eq, Hash)]\n#[debug(\"{_0:?}\")]\npub struct ChronoUnixTimestamp(pub ChronoDateTimeUtc);\n\n/// A DataTime<Utc> mapped to i64 in database, but in milliseconds\n#[derive(derive_more::Debug, Copy, Clone, PartialEq, Eq, Hash)]\n#[debug(\"{_0:?}\")]\npub struct ChronoUnixTimestampMillis(pub ChronoDateTimeUtc);\n\nimpl_timestamp!(\n    ChronoUnixTimestamp,\n    ChronoDateTimeUtc,\n    from_timestamp,\n    to_timestamp\n);\n\nimpl_timestamp!(\n    ChronoUnixTimestampMillis,\n    ChronoDateTimeUtc,\n    from_timestamp_millis,\n    to_timestamp_millis\n);\n\nfn from_timestamp(ts: i64) -> Option<ChronoUnixTimestamp> {\n    ChronoDateTimeUtc::from_timestamp(ts, 0).map(ChronoUnixTimestamp)\n}\n\nfn to_timestamp(ts: ChronoUnixTimestamp) -> i64 {\n    ts.0.timestamp()\n}\n\nfn from_timestamp_millis(ts: i64) -> Option<ChronoUnixTimestampMillis> {\n    ChronoDateTimeUtc::from_timestamp_millis(ts).map(ChronoUnixTimestampMillis)\n}\n\nfn to_timestamp_millis(ts: ChronoUnixTimestampMillis) -> i64 {\n    ts.0.timestamp_millis()\n}\n"
  },
  {
    "path": "sea-orm-sync/src/value/with_time.rs",
    "content": "use super::impl_timestamp;\nuse crate as sea_orm;\nuse crate::{DbErr, TryGetError, prelude::TimeDateTimeWithTimeZone};\nuse std::ops::{Deref, DerefMut};\n\n/// A OffsetDateTime mapped to i64 in database\n#[derive(derive_more::Debug, Copy, Clone, PartialEq, Eq, Hash)]\n#[debug(\"{_0:?}\")]\npub struct TimeUnixTimestamp(pub TimeDateTimeWithTimeZone);\n\n/// A OffsetDateTime mapped to i64 in database, but in milliseconds\n#[derive(derive_more::Debug, Copy, Clone, PartialEq, Eq, Hash)]\n#[debug(\"{_0:?}\")]\npub struct TimeUnixTimestampMillis(pub TimeDateTimeWithTimeZone);\n\nimpl_timestamp!(\n    TimeUnixTimestamp,\n    TimeDateTimeWithTimeZone,\n    from_timestamp,\n    to_timestamp\n);\n\nimpl_timestamp!(\n    TimeUnixTimestampMillis,\n    TimeDateTimeWithTimeZone,\n    from_timestamp_millis,\n    to_timestamp_millis\n);\n\nfn from_timestamp(ts: i64) -> Option<TimeUnixTimestamp> {\n    TimeDateTimeWithTimeZone::from_unix_timestamp(ts)\n        .ok()\n        .map(TimeUnixTimestamp)\n}\n\nfn to_timestamp(ts: TimeUnixTimestamp) -> i64 {\n    ts.0.unix_timestamp()\n}\n\nfn from_timestamp_millis(ts: i64) -> Option<TimeUnixTimestampMillis> {\n    TimeDateTimeWithTimeZone::from_unix_timestamp_nanos(ts as i128 * 1_000_000)\n        .ok()\n        .map(TimeUnixTimestampMillis)\n}\n\nfn to_timestamp_millis(ts: TimeUnixTimestampMillis) -> i64 {\n    (ts.0.unix_timestamp_nanos() / 1_000_000) as i64\n}\n"
  },
  {
    "path": "sea-orm-sync/src/value.rs",
    "content": "use crate::sea_query::{Nullable, ValueType};\nuse crate::{ActiveValue, Value};\n\nmod timestamp;\nuse timestamp::*;\n\n#[cfg(feature = \"with-chrono\")]\nmod with_chrono;\n#[cfg(feature = \"with-chrono\")]\npub use with_chrono::*;\n\n#[cfg(feature = \"with-time\")]\nmod with_time;\n#[cfg(feature = \"with-time\")]\npub use with_time::*;\n\n#[cfg(feature = \"with-uuid\")]\nmod text_uuid;\n#[cfg(feature = \"with-uuid\")]\npub use text_uuid::*;\n\n/// Default value for T\npub trait DefaultActiveValue {\n    /// `Default::default()` if implemented, dummy value otherwise\n    fn default_value(&self) -> Self;\n}\n\n/// Default value for Option<T>\npub trait DefaultActiveValueNone {\n    /// Always `None`\n    fn default_value(&self) -> Self;\n}\n\n/// Default value for types that's not nullable\npub trait DefaultActiveValueNotSet {\n    /// The owned value type\n    type Value;\n\n    /// Always `NotSet`\n    fn default_value(&self) -> Self::Value;\n}\n\nimpl<V> DefaultActiveValue for ActiveValue<V>\nwhere\n    V: Into<Value> + ValueType + Nullable,\n{\n    fn default_value(&self) -> Self {\n        match V::try_from(V::null().dummy_value()) {\n            Ok(v) => ActiveValue::Set(v),\n            Err(_) => ActiveValue::NotSet,\n        }\n    }\n}\n\nimpl<V> DefaultActiveValueNone for ActiveValue<Option<V>>\nwhere\n    V: Into<Value> + Nullable,\n{\n    fn default_value(&self) -> Self {\n        ActiveValue::Set(None)\n    }\n}\n\nimpl<V> DefaultActiveValueNotSet for &ActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    type Value = ActiveValue<V>;\n\n    fn default_value(&self) -> Self::Value {\n        ActiveValue::NotSet\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::prelude::TimeDateTime;\n\n    #[test]\n    fn test_default_value() {\n        let v = (&ActiveValue::<i32>::NotSet).default_value();\n        assert_eq!(v, ActiveValue::Set(0));\n\n        let v = (&ActiveValue::<Option<i32>>::NotSet).default_value();\n        assert_eq!(v, ActiveValue::Set(None));\n\n        let v = (&ActiveValue::<String>::NotSet).default_value();\n        assert_eq!(v, ActiveValue::Set(\"\".to_owned()));\n\n        let v = (&ActiveValue::<Option<String>>::NotSet).default_value();\n        assert_eq!(v, ActiveValue::Set(None));\n\n        let v = (&ActiveValue::<TimeDateTime>::NotSet).default_value();\n        assert!(matches!(v, ActiveValue::Set(_)));\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/active_enum_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse active_enum::Entity as ActiveEnumEntity;\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\n#[cfg(feature = \"sqlx-postgres\")]\nuse sea_orm::QueryTrait;\nuse sea_orm::{\n    ActiveEnum as ActiveEnumTrait, DatabaseConnection, DbErr, FromQueryResult, QueryFilter,\n    QuerySelect,\n    entity::*,\n    sea_query::{BinOper, Expr, ExprTrait},\n};\n\n#[sea_orm_macros::test]\nfn active_enum_tests() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"active_enum_tests\");\n    create_tea_enum(&ctx.db)?;\n    create_active_enum_table(&ctx.db)?;\n    create_active_enum_child_table(&ctx.db)?;\n    #[cfg(feature = \"sqlx-postgres\")]\n    create_categories_table(&ctx.db)?;\n\n    insert_active_enum(&ctx.db)?;\n    insert_active_enum_child(&ctx.db)?;\n\n    #[cfg(feature = \"sqlx-postgres\")]\n    insert_active_enum_vec(&ctx.db)?;\n\n    find_related_active_enum(&ctx.db)?;\n    find_linked_active_enum(&ctx.db)?;\n\n    delete_active_enum(&ctx.db)?;\n\n    ctx.delete();\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn active_enum_schema_sync_test() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"active_enum_schema_sync_test\");\n    let db = &ctx.db;\n\n    let mut schema_builder = db.get_schema_builder().register(active_enum::Entity);\n\n    #[cfg(feature = \"sqlx-postgres\")]\n    {\n        schema_builder = schema_builder\n            .register(active_enum_child::Entity)\n            .register(categories::Entity);\n    }\n\n    #[cfg(not(feature = \"schema-sync\"))]\n    schema_builder.apply(db)?;\n\n    #[cfg(feature = \"schema-sync\")]\n    schema_builder.sync(db)?;\n\n    insert_active_enum(&ctx.db)?;\n    #[cfg(feature = \"sqlx-postgres\")]\n    insert_active_enum_vec(&ctx.db)?;\n\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn insert_active_enum(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use active_enum::*;\n\n    let model = Model {\n        id: 1,\n        category: None,\n        color: None,\n        tea: None,\n    };\n\n    assert_eq!(\n        model,\n        ActiveModel {\n            category: Set(None),\n            color: Set(None),\n            tea: Set(None),\n            ..Default::default()\n        }\n        .insert(db)?\n    );\n    assert_eq!(model, Entity::find().one(db)?.unwrap());\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.is_not_null())\n            .filter(Column::Category.is_null())\n            .filter(Column::Color.is_null())\n            .filter(Column::Tea.is_null())\n            .one(db)?\n            .unwrap()\n    );\n\n    let _ = ActiveModel {\n        category: Set(Some(Category::Big)),\n        color: Set(Some(Color::Black)),\n        tea: Set(Some(Tea::EverydayTea)),\n        ..model.into_active_model()\n    }\n    .save(db)?;\n\n    let model = Entity::find().one(db)?.unwrap();\n    assert_eq!(\n        model,\n        Model {\n            id: 1,\n            category: Some(Category::Big),\n            color: Some(Color::Black),\n            tea: Some(Tea::EverydayTea),\n        }\n    );\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.eq(1))\n            .filter(Column::Category.eq(Category::Big))\n            .filter(Column::Color.eq(Color::Black))\n            .filter(Column::Tea.eq(Tea::EverydayTea))\n            .one(db)?\n            .unwrap()\n    );\n\n    #[derive(Debug, FromQueryResult, PartialEq)]\n    struct SelectResult {\n        tea_alias: Option<Tea>,\n    }\n\n    assert_eq!(\n        SelectResult {\n            tea_alias: Some(Tea::EverydayTea),\n        },\n        Entity::find()\n            .select_only()\n            .column_as(Column::Tea, \"tea_alias\")\n            .into_model()\n            .one(db)?\n            .unwrap()\n    );\n\n    assert_eq!(\n        serde_json::json!({\n            \"id\": 1,\n            \"category\": \"B\",\n            \"color\": 0,\n            \"tea\": \"EverydayTea\",\n        }),\n        Entity::find().into_json().one(db)?.unwrap()\n    );\n\n    assert_eq!(\n        serde_json::json!({\n            \"tea_alias\": \"EverydayTea\",\n        }),\n        Entity::find()\n            .select_only()\n            .column_as(Column::Tea, \"tea_alias\")\n            .into_json()\n            .one(db)?\n            .unwrap()\n    );\n\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Expr::col(Column::Tea).binary(\n                BinOper::In,\n                Expr::tuple([ActiveEnumTrait::as_enum(&Tea::EverydayTea)])\n            ))\n            .one(db)?\n            .unwrap()\n    );\n    // Equivalent to the above.\n    let select_with_tea_in =\n        Entity::find().filter(Column::Tea.is_in([Tea::EverydayTea, Tea::BreakfastTea]));\n    #[cfg(feature = \"sqlx-postgres\")]\n    assert_eq!(\n        select_with_tea_in\n            .build(sea_orm::DatabaseBackend::Postgres)\n            .to_string(),\n        [\n            r#\"SELECT \"active_enum\".\"id\",\"#,\n            r#\"\"active_enum\".\"category\",\"#,\n            r#\"\"active_enum\".\"color\",\"#,\n            r#\"CAST(\"active_enum\".\"tea\" AS \"text\")\"#,\n            r#\"FROM \"public\".\"active_enum\"\"#,\n            r#\"WHERE \"active_enum\".\"tea\" IN (CAST('EverydayTea' AS \"tea\"), CAST('BreakfastTea' AS \"tea\"))\"#,\n        ]\n        .join(\" \")\n    );\n    assert_eq!(model, select_with_tea_in.one(db)?.unwrap());\n\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Tea.is_not_null())\n            .filter(Expr::col(Column::Tea).binary(\n                BinOper::NotIn,\n                Expr::tuple([ActiveEnumTrait::as_enum(&Tea::BreakfastTea)])\n            ))\n            .one(db)?\n            .unwrap()\n    );\n    // Equivalent to the above.\n    let select_with_tea_not_in = Entity::find()\n        .filter(Column::Tea.is_not_null())\n        .filter(Column::Tea.is_not_in([Tea::BreakfastTea]));\n\n    #[cfg(feature = \"sqlx-postgres\")]\n    assert_eq!(\n        select_with_tea_not_in\n            .build(sea_orm::DatabaseBackend::Postgres)\n            .to_string(),\n        [\n            r#\"SELECT \"active_enum\".\"id\",\"#,\n            r#\"\"active_enum\".\"category\",\"#,\n            r#\"\"active_enum\".\"color\",\"#,\n            r#\"CAST(\"active_enum\".\"tea\" AS \"text\")\"#,\n            r#\"FROM \"public\".\"active_enum\"\"#,\n            r#\"WHERE \"active_enum\".\"tea\" IS NOT NULL\"#,\n            r#\"AND \"active_enum\".\"tea\" NOT IN (CAST('BreakfastTea' AS \"tea\"))\"#,\n        ]\n        .join(\" \")\n    );\n\n    assert_eq!(model, select_with_tea_not_in.one(db)?.unwrap());\n\n    // String enums should be compared alphabetically in all supported DBs.\n    // 'B' < 'S', so Big is considered \"smaller\" than Small.\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Category.lt(Category::Small))\n            .one(db)?\n            .unwrap()\n    );\n\n    // Integer enums should be compared by value in all supported DBs.\n    // 0 <= 1, so Black is considered \"smaller or equal to\" White.\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Color.lte(Color::White))\n            .one(db)?\n            .unwrap()\n    );\n\n    // Native enum comparisons are not portable.\n    //\n    // Postgres enums are compared by their definition order\n    // (see https://www.postgresql.org/docs/current/datatype-enum.html#DATATYPE-ENUM-ORDERING).\n    // Tea was defined as ('EverydayTea', 'BreakfastTea'), so EverydayTea is considered \"smaller\" than BreakfastTea.\n    //\n    // SQLite doesn't support enum types and SeaORM works around this limitation by storing them as strings.\n    // When treated as strings, EverydayTea is not \"smaller\" than BreakfastTea!\n    //\n    // MySQL should be the same as Postgres (see https://dev.mysql.com/doc/refman/8.0/en/enum.html#enum-sorting),\n    // but in practice this test case behaves like SQLite. I'm not sure why.\n    #[cfg(feature = \"sqlx-postgres\")]\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Tea.lt(Tea::BreakfastTea))\n            .one(db)?\n            .unwrap()\n    );\n    #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n    assert_eq!(\n        None,\n        Entity::find()\n            .filter(Column::Tea.lt(Tea::BreakfastTea))\n            .one(db)?\n    );\n\n    let res = model.delete(db)?;\n\n    assert_eq!(res.rows_affected, 1);\n    assert_eq!(Entity::find().one(db)?, None);\n\n    Ok(())\n}\n\npub fn insert_active_enum_child(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use active_enum_child::*;\n\n    active_enum::ActiveModel {\n        category: Set(Some(Category::Small)),\n        color: Set(Some(Color::White)),\n        tea: Set(Some(Tea::BreakfastTea)),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    let am = ActiveModel {\n        parent_id: Set(2),\n        category: Set(None),\n        color: Set(None),\n        tea: Set(None),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    let model = Entity::find().one(db)?.unwrap();\n    assert_eq!(\n        model,\n        Model {\n            id: 1,\n            parent_id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        }\n    );\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.is_not_null())\n            .filter(Column::Category.is_null())\n            .filter(Column::Color.is_null())\n            .filter(Column::Tea.is_null())\n            .one(db)?\n            .unwrap()\n    );\n\n    ActiveModel {\n        category: Set(Some(Category::Big)),\n        color: Set(Some(Color::Black)),\n        tea: Set(Some(Tea::EverydayTea)),\n        ..am.into_active_model()\n    }\n    .save(db)?;\n\n    let model = Entity::find().one(db)?.unwrap();\n    assert_eq!(\n        model,\n        Model {\n            id: 1,\n            parent_id: 2,\n            category: Some(Category::Big),\n            color: Some(Color::Black),\n            tea: Some(Tea::EverydayTea),\n        }\n    );\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.eq(1))\n            .filter(Column::Category.eq(Category::Big))\n            .filter(Column::Color.eq(Color::Black))\n            .filter(Column::Tea.eq(Tea::EverydayTea))\n            .one(db)?\n            .unwrap()\n    );\n\n    Ok(())\n}\n\npub fn insert_active_enum_vec(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use categories::*;\n\n    let model = Model {\n        id: 1,\n        categories: None,\n    };\n\n    assert_eq!(\n        model,\n        ActiveModel {\n            id: Set(1),\n            categories: Set(None),\n            ..Default::default()\n        }\n        .insert(db)?\n    );\n    assert_eq!(model, Entity::find().one(db)?.unwrap());\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.is_not_null())\n            .filter(Column::Categories.is_null())\n            .one(db)?\n            .unwrap()\n    );\n\n    let _ = ActiveModel {\n        id: Set(1),\n        categories: Set(Some(vec![Category::Big, Category::Small])),\n        ..model.into_active_model()\n    }\n    .save(db)?;\n\n    let model = Entity::find().one(db)?.unwrap();\n    assert_eq!(\n        model,\n        Model {\n            id: 1,\n            categories: Some(vec![Category::Big, Category::Small]),\n        }\n    );\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.eq(1))\n            .filter(Expr::cust_with_values(\n                r#\"$1 = ANY(\"categories\")\"#,\n                vec![Category::Big]\n            ))\n            .one(db)?\n            .unwrap()\n    );\n\n    let res = model.delete(db)?;\n\n    assert_eq!(res.rows_affected, 1);\n    assert_eq!(Entity::find().one(db)?, None);\n\n    Ok(())\n}\n\npub fn find_related_active_enum(db: &DatabaseConnection) -> Result<(), DbErr> {\n    assert_eq!(\n        active_enum::Model {\n            id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        }\n        .find_related(ActiveEnumChild)\n        .all(db)?,\n        [active_enum_child::Model {\n            id: 1,\n            parent_id: 2,\n            category: Some(Category::Big),\n            color: Some(Color::Black),\n            tea: Some(Tea::EverydayTea),\n        }]\n    );\n    assert_eq!(\n        ActiveEnumEntity::find()\n            .find_with_related(ActiveEnumChild)\n            .all(db)?,\n        [(\n            active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            },\n            vec![active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            }]\n        )]\n    );\n    assert_eq!(\n        ActiveEnumEntity::find()\n            .find_also_related(ActiveEnumChild)\n            .all(db)?,\n        [(\n            active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            },\n            Some(active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            })\n        )]\n    );\n\n    assert_eq!(\n        active_enum_child::Model {\n            id: 1,\n            parent_id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        }\n        .find_related(ActiveEnum)\n        .all(db)?,\n        [active_enum::Model {\n            id: 2,\n            category: Some(Category::Small),\n            color: Some(Color::White),\n            tea: Some(Tea::BreakfastTea),\n        }]\n    );\n    assert_eq!(\n        ActiveEnumChild::find()\n            .find_with_related(ActiveEnum)\n            .all(db)?,\n        [(\n            active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            },\n            vec![active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            }]\n        )]\n    );\n    assert_eq!(\n        ActiveEnumChild::find()\n            .find_also_related(ActiveEnum)\n            .all(db)?,\n        [(\n            active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            },\n            Some(active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            })\n        )]\n    );\n\n    Ok(())\n}\n\npub fn find_linked_active_enum(db: &DatabaseConnection) -> Result<(), DbErr> {\n    assert_eq!(\n        active_enum::Model {\n            id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        }\n        .find_linked(active_enum::ActiveEnumChildLink)\n        .all(db)?,\n        [active_enum_child::Model {\n            id: 1,\n            parent_id: 2,\n            category: Some(Category::Big),\n            color: Some(Color::Black),\n            tea: Some(Tea::EverydayTea),\n        }]\n    );\n    assert_eq!(\n        ActiveEnumEntity::find()\n            .find_also_linked(active_enum::ActiveEnumChildLink)\n            .all(db)?,\n        [(\n            active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            },\n            Some(active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            })\n        )]\n    );\n    assert_eq!(\n        ActiveEnumEntity::find()\n            .find_with_linked(active_enum::ActiveEnumChildLink)\n            .all(db)?,\n        [(\n            active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            },\n            vec![active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            }]\n        )]\n    );\n\n    assert_eq!(\n        active_enum_child::Model {\n            id: 1,\n            parent_id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        }\n        .find_linked(active_enum_child::ActiveEnumLink)\n        .all(db)?,\n        [active_enum::Model {\n            id: 2,\n            category: Some(Category::Small),\n            color: Some(Color::White),\n            tea: Some(Tea::BreakfastTea),\n        }]\n    );\n    assert_eq!(\n        ActiveEnumChild::find()\n            .find_also_linked(active_enum_child::ActiveEnumLink)\n            .all(db)?,\n        [(\n            active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            },\n            Some(active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            })\n        )]\n    );\n    assert_eq!(\n        ActiveEnumChild::find()\n            .find_with_linked(active_enum_child::ActiveEnumLink)\n            .all(db)?,\n        [(\n            active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            },\n            vec![active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            }]\n        )]\n    );\n\n    Ok(())\n}\n\nfn delete_active_enum(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use active_enum_child::*;\n\n    if db.get_database_backend().support_returning() {\n        let model = Entity::find().one(db)?.unwrap();\n\n        assert_eq!(model.id, 1);\n\n        assert_eq!(\n            model,\n            Entity::delete(model.clone().into_active_model())\n                .exec_with_returning(db)?\n                .unwrap()\n        );\n    }\n\n    Ok(())\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    pub use pretty_assertions::assert_eq;\n    pub use sea_orm::{DbBackend, QueryTrait};\n\n    #[test]\n    fn active_enum_find_related() {\n        let active_enum_model = active_enum::Model {\n            id: 1,\n            category: None,\n            color: None,\n            tea: None,\n        };\n        let _select = active_enum_model.find_related(ActiveEnumChild);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select.build(DbBackend::Sqlite).to_string(),\n                [\n                    r#\"SELECT \"active_enum_child\".\"id\", \"active_enum_child\".\"parent_id\", \"active_enum_child\".\"category\", \"active_enum_child\".\"color\", \"active_enum_child\".\"tea\"\"#,\n                    r#\"FROM \"active_enum_child\"\"#,\n                    r#\"INNER JOIN \"active_enum\" ON \"active_enum\".\"id\" = \"active_enum_child\".\"parent_id\"\"#,\n                    r#\"WHERE \"active_enum\".\"id\" = 1\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select.build(DbBackend::MySql).to_string(),\n                [\n                    \"SELECT `active_enum_child`.`id`, `active_enum_child`.`parent_id`, `active_enum_child`.`category`, `active_enum_child`.`color`, `active_enum_child`.`tea`\",\n                    \"FROM `active_enum_child`\",\n                    \"INNER JOIN `active_enum` ON `active_enum`.`id` = `active_enum_child`.`parent_id`\",\n                    \"WHERE `active_enum`.`id` = 1\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select.build(DbBackend::Postgres).to_string(),\n            [\n                r#\"SELECT \"active_enum_child\".\"id\", \"active_enum_child\".\"parent_id\", \"active_enum_child\".\"category\", \"active_enum_child\".\"color\", CAST(\"active_enum_child\".\"tea\" AS \"text\")\"#,\n                r#\"FROM \"public\".\"active_enum_child\"\"#,\n                r#\"INNER JOIN \"public\".\"active_enum\" ON \"active_enum\".\"id\" = \"active_enum_child\".\"parent_id\"\"#,\n                r#\"WHERE \"active_enum\".\"id\" = 1\"#,\n            ]\n            .join(\" \")\n        );\n\n        let _select = ActiveEnumEntity::find().find_also_related(ActiveEnumChild);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select\n                    .build(DbBackend::Sqlite)\n                    .to_string(),\n                [\n                    r#\"SELECT \"active_enum\".\"id\" AS \"A_id\", \"active_enum\".\"category\" AS \"A_category\", \"active_enum\".\"color\" AS \"A_color\", \"active_enum\".\"tea\" AS \"A_tea\",\"#,\n                    r#\"\"active_enum_child\".\"id\" AS \"B_id\", \"active_enum_child\".\"parent_id\" AS \"B_parent_id\", \"active_enum_child\".\"category\" AS \"B_category\", \"active_enum_child\".\"color\" AS \"B_color\", \"active_enum_child\".\"tea\" AS \"B_tea\"\"#,\n                    r#\"FROM \"active_enum\"\"#,\n                    r#\"LEFT JOIN \"active_enum_child\" ON \"active_enum\".\"id\" = \"active_enum_child\".\"parent_id\"\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select\n                    .build(DbBackend::MySql)\n                    .to_string(),\n                [\n                    \"SELECT `active_enum`.`id` AS `A_id`, `active_enum`.`category` AS `A_category`, `active_enum`.`color` AS `A_color`, `active_enum`.`tea` AS `A_tea`,\",\n                    \"`active_enum_child`.`id` AS `B_id`, `active_enum_child`.`parent_id` AS `B_parent_id`, `active_enum_child`.`category` AS `B_category`, `active_enum_child`.`color` AS `B_color`, `active_enum_child`.`tea` AS `B_tea`\",\n                    \"FROM `active_enum`\",\n                    \"LEFT JOIN `active_enum_child` ON `active_enum`.`id` = `active_enum_child`.`parent_id`\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select\n                .build(DbBackend::Postgres)\n                .to_string(),\n            [\n                r#\"SELECT \"active_enum\".\"id\" AS \"A_id\", \"active_enum\".\"category\" AS \"A_category\", \"active_enum\".\"color\" AS \"A_color\", CAST(\"active_enum\".\"tea\" AS \"text\") AS \"A_tea\",\"#,\n                r#\"\"active_enum_child\".\"id\" AS \"B_id\", \"active_enum_child\".\"parent_id\" AS \"B_parent_id\", \"active_enum_child\".\"category\" AS \"B_category\", \"active_enum_child\".\"color\" AS \"B_color\", CAST(\"active_enum_child\".\"tea\" AS \"text\") AS \"B_tea\"\"#,\n                r#\"FROM \"public\".\"active_enum\"\"#,\n                r#\"LEFT JOIN \"public\".\"active_enum_child\" ON \"active_enum\".\"id\" = \"active_enum_child\".\"parent_id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn active_enum_find_linked() {\n        let active_enum_model = active_enum::Model {\n            id: 1,\n            category: None,\n            color: None,\n            tea: None,\n        };\n        let _select = active_enum_model.find_linked(active_enum::ActiveEnumChildLink);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select.build(DbBackend::Sqlite).to_string(),\n                [\n                    r#\"SELECT \"active_enum_child\".\"id\", \"active_enum_child\".\"parent_id\", \"active_enum_child\".\"category\", \"active_enum_child\".\"color\", \"active_enum_child\".\"tea\"\"#,\n                    r#\"FROM \"active_enum_child\"\"#,\n                    r#\"INNER JOIN \"active_enum\" AS \"r0\" ON \"r0\".\"id\" = \"active_enum_child\".\"parent_id\"\"#,\n                    r#\"WHERE \"r0\".\"id\" = 1\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select.build(DbBackend::MySql).to_string(),\n                [\n                    \"SELECT `active_enum_child`.`id`, `active_enum_child`.`parent_id`, `active_enum_child`.`category`, `active_enum_child`.`color`, `active_enum_child`.`tea`\",\n                    \"FROM `active_enum_child`\",\n                    \"INNER JOIN `active_enum` AS `r0` ON `r0`.`id` = `active_enum_child`.`parent_id`\",\n                    \"WHERE `r0`.`id` = 1\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select.build(DbBackend::Postgres).to_string(),\n            [\n                r#\"SELECT \"active_enum_child\".\"id\", \"active_enum_child\".\"parent_id\", \"active_enum_child\".\"category\", \"active_enum_child\".\"color\", CAST(\"active_enum_child\".\"tea\" AS \"text\")\"#,\n                r#\"FROM \"public\".\"active_enum_child\"\"#,\n                r#\"INNER JOIN \"public\".\"active_enum\" AS \"r0\" ON \"r0\".\"id\" = \"active_enum_child\".\"parent_id\"\"#,\n                r#\"WHERE \"r0\".\"id\" = 1\"#,\n            ]\n            .join(\" \")\n        );\n\n        let _select = ActiveEnumEntity::find().find_also_linked(active_enum::ActiveEnumChildLink);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select\n                    .build(DbBackend::Sqlite)\n                    .to_string(),\n                [\n                    r#\"SELECT \"active_enum\".\"id\" AS \"A_id\", \"active_enum\".\"category\" AS \"A_category\", \"active_enum\".\"color\" AS \"A_color\", \"active_enum\".\"tea\" AS \"A_tea\",\"#,\n                    r#\"\"r0\".\"id\" AS \"B_id\", \"r0\".\"parent_id\" AS \"B_parent_id\", \"r0\".\"category\" AS \"B_category\", \"r0\".\"color\" AS \"B_color\", \"r0\".\"tea\" AS \"B_tea\"\"#,\n                    r#\"FROM \"active_enum\"\"#,\n                    r#\"LEFT JOIN \"active_enum_child\" AS \"r0\" ON \"active_enum\".\"id\" = \"r0\".\"parent_id\"\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select\n                    .build(DbBackend::MySql)\n                    .to_string(),\n                [\n                    \"SELECT `active_enum`.`id` AS `A_id`, `active_enum`.`category` AS `A_category`, `active_enum`.`color` AS `A_color`, `active_enum`.`tea` AS `A_tea`,\",\n                    \"`r0`.`id` AS `B_id`, `r0`.`parent_id` AS `B_parent_id`, `r0`.`category` AS `B_category`, `r0`.`color` AS `B_color`, `r0`.`tea` AS `B_tea`\",\n                    \"FROM `active_enum`\",\n                    \"LEFT JOIN `active_enum_child` AS `r0` ON `active_enum`.`id` = `r0`.`parent_id`\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select\n                .build(DbBackend::Postgres)\n                .to_string(),\n            [\n                r#\"SELECT \"active_enum\".\"id\" AS \"A_id\", \"active_enum\".\"category\" AS \"A_category\", \"active_enum\".\"color\" AS \"A_color\", CAST(\"active_enum\".\"tea\" AS \"text\") AS \"A_tea\",\"#,\n                r#\"\"r0\".\"id\" AS \"B_id\", \"r0\".\"parent_id\" AS \"B_parent_id\", \"r0\".\"category\" AS \"B_category\", \"r0\".\"color\" AS \"B_color\", CAST(\"r0\".\"tea\" AS \"text\") AS \"B_tea\"\"#,\n                r#\"FROM \"public\".\"active_enum\"\"#,\n                r#\"LEFT JOIN \"public\".\"active_enum_child\" AS \"r0\" ON \"active_enum\".\"id\" = \"r0\".\"parent_id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn active_enum_child_find_related() {\n        let active_enum_child_model = active_enum_child::Model {\n            id: 1,\n            parent_id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        };\n        let _select = active_enum_child_model.find_related(ActiveEnum);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select.build(DbBackend::Sqlite).to_string(),\n                [\n                    r#\"SELECT \"active_enum\".\"id\", \"active_enum\".\"category\", \"active_enum\".\"color\", \"active_enum\".\"tea\"\"#,\n                    r#\"FROM \"active_enum\"\"#,\n                    r#\"INNER JOIN \"active_enum_child\" ON \"active_enum_child\".\"parent_id\" = \"active_enum\".\"id\"\"#,\n                    r#\"WHERE \"active_enum_child\".\"id\" = 1\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select.build(DbBackend::MySql).to_string(),\n                [\n                    \"SELECT `active_enum`.`id`, `active_enum`.`category`, `active_enum`.`color`, `active_enum`.`tea`\",\n                    \"FROM `active_enum`\",\n                    \"INNER JOIN `active_enum_child` ON `active_enum_child`.`parent_id` = `active_enum`.`id`\",\n                    \"WHERE `active_enum_child`.`id` = 1\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select.build(DbBackend::Postgres).to_string(),\n            [\n                r#\"SELECT \"active_enum\".\"id\", \"active_enum\".\"category\", \"active_enum\".\"color\", CAST(\"active_enum\".\"tea\" AS \"text\")\"#,\n                r#\"FROM \"public\".\"active_enum\"\"#,\n                r#\"INNER JOIN \"public\".\"active_enum_child\" ON \"active_enum_child\".\"parent_id\" = \"active_enum\".\"id\"\"#,\n                r#\"WHERE \"active_enum_child\".\"id\" = 1\"#,\n            ]\n            .join(\" \")\n        );\n\n        let _select = ActiveEnumChild::find().find_also_related(ActiveEnum);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select\n                    .build(DbBackend::Sqlite)\n                    .to_string(),\n                [\n                    r#\"SELECT \"active_enum_child\".\"id\" AS \"A_id\", \"active_enum_child\".\"parent_id\" AS \"A_parent_id\", \"active_enum_child\".\"category\" AS \"A_category\", \"active_enum_child\".\"color\" AS \"A_color\", \"active_enum_child\".\"tea\" AS \"A_tea\",\"#,\n                    r#\"\"active_enum\".\"id\" AS \"B_id\", \"active_enum\".\"category\" AS \"B_category\", \"active_enum\".\"color\" AS \"B_color\", \"active_enum\".\"tea\" AS \"B_tea\"\"#,\n                    r#\"FROM \"active_enum_child\"\"#,\n                    r#\"LEFT JOIN \"active_enum\" ON \"active_enum_child\".\"parent_id\" = \"active_enum\".\"id\"\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select\n                    .build(DbBackend::MySql)\n                    .to_string(),\n                [\n                    \"SELECT `active_enum_child`.`id` AS `A_id`, `active_enum_child`.`parent_id` AS `A_parent_id`, `active_enum_child`.`category` AS `A_category`, `active_enum_child`.`color` AS `A_color`, `active_enum_child`.`tea` AS `A_tea`,\",\n                    \"`active_enum`.`id` AS `B_id`, `active_enum`.`category` AS `B_category`, `active_enum`.`color` AS `B_color`, `active_enum`.`tea` AS `B_tea`\",\n                    \"FROM `active_enum_child`\",\n                    \"LEFT JOIN `active_enum` ON `active_enum_child`.`parent_id` = `active_enum`.`id`\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select\n                .build(DbBackend::Postgres)\n                .to_string(),\n            [\n                r#\"SELECT \"active_enum_child\".\"id\" AS \"A_id\", \"active_enum_child\".\"parent_id\" AS \"A_parent_id\", \"active_enum_child\".\"category\" AS \"A_category\", \"active_enum_child\".\"color\" AS \"A_color\", CAST(\"active_enum_child\".\"tea\" AS \"text\") AS \"A_tea\",\"#,\n                r#\"\"active_enum\".\"id\" AS \"B_id\", \"active_enum\".\"category\" AS \"B_category\", \"active_enum\".\"color\" AS \"B_color\", CAST(\"active_enum\".\"tea\" AS \"text\") AS \"B_tea\"\"#,\n                r#\"FROM \"public\".\"active_enum_child\"\"#,\n                r#\"LEFT JOIN \"public\".\"active_enum\" ON \"active_enum_child\".\"parent_id\" = \"active_enum\".\"id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn active_enum_child_find_linked() {\n        let active_enum_child_model = active_enum_child::Model {\n            id: 1,\n            parent_id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        };\n        let _select = active_enum_child_model.find_linked(active_enum_child::ActiveEnumLink);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select.build(DbBackend::Sqlite).to_string(),\n                [\n                    r#\"SELECT \"active_enum\".\"id\", \"active_enum\".\"category\", \"active_enum\".\"color\", \"active_enum\".\"tea\"\"#,\n                    r#\"FROM \"active_enum\"\"#,\n                    r#\"INNER JOIN \"active_enum_child\" AS \"r0\" ON \"r0\".\"parent_id\" = \"active_enum\".\"id\"\"#,\n                    r#\"WHERE \"r0\".\"id\" = 1\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select.build(DbBackend::MySql).to_string(),\n                [\n                    \"SELECT `active_enum`.`id`, `active_enum`.`category`, `active_enum`.`color`, `active_enum`.`tea`\",\n                    \"FROM `active_enum`\",\n                    \"INNER JOIN `active_enum_child` AS `r0` ON `r0`.`parent_id` = `active_enum`.`id`\",\n                    \"WHERE `r0`.`id` = 1\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select.build(DbBackend::Postgres).to_string(),\n            [\n                r#\"SELECT \"active_enum\".\"id\", \"active_enum\".\"category\", \"active_enum\".\"color\", CAST(\"active_enum\".\"tea\" AS \"text\")\"#,\n                r#\"FROM \"public\".\"active_enum\"\"#,\n                r#\"INNER JOIN \"public\".\"active_enum_child\" AS \"r0\" ON \"r0\".\"parent_id\" = \"active_enum\".\"id\"\"#,\n                r#\"WHERE \"r0\".\"id\" = 1\"#,\n            ]\n            .join(\" \")\n        );\n\n        let _select = ActiveEnumChild::find().find_also_linked(active_enum_child::ActiveEnumLink);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select\n                    .build(DbBackend::Sqlite)\n                    .to_string(),\n                [\n                    r#\"SELECT \"active_enum_child\".\"id\" AS \"A_id\", \"active_enum_child\".\"parent_id\" AS \"A_parent_id\", \"active_enum_child\".\"category\" AS \"A_category\", \"active_enum_child\".\"color\" AS \"A_color\", \"active_enum_child\".\"tea\" AS \"A_tea\",\"#,\n                    r#\"\"r0\".\"id\" AS \"B_id\", \"r0\".\"category\" AS \"B_category\", \"r0\".\"color\" AS \"B_color\", \"r0\".\"tea\" AS \"B_tea\"\"#,\n                    r#\"FROM \"active_enum_child\"\"#,\n                    r#\"LEFT JOIN \"active_enum\" AS \"r0\" ON \"active_enum_child\".\"parent_id\" = \"r0\".\"id\"\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select\n                    .build(DbBackend::MySql)\n                    .to_string(),\n                [\n                    \"SELECT `active_enum_child`.`id` AS `A_id`, `active_enum_child`.`parent_id` AS `A_parent_id`, `active_enum_child`.`category` AS `A_category`, `active_enum_child`.`color` AS `A_color`, `active_enum_child`.`tea` AS `A_tea`,\",\n                    \"`r0`.`id` AS `B_id`, `r0`.`category` AS `B_category`, `r0`.`color` AS `B_color`, `r0`.`tea` AS `B_tea`\",\n                    \"FROM `active_enum_child`\",\n                    \"LEFT JOIN `active_enum` AS `r0` ON `active_enum_child`.`parent_id` = `r0`.`id`\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select\n                .build(DbBackend::Postgres)\n                .to_string(),\n            [\n                r#\"SELECT \"active_enum_child\".\"id\" AS \"A_id\", \"active_enum_child\".\"parent_id\" AS \"A_parent_id\", \"active_enum_child\".\"category\" AS \"A_category\", \"active_enum_child\".\"color\" AS \"A_color\", CAST(\"active_enum_child\".\"tea\" AS \"text\") AS \"A_tea\",\"#,\n                r#\"\"r0\".\"id\" AS \"B_id\", \"r0\".\"category\" AS \"B_category\", \"r0\".\"color\" AS \"B_color\", CAST(\"r0\".\"tea\" AS \"text\") AS \"B_tea\"\"#,\n                r#\"FROM \"public\".\"active_enum_child\"\"#,\n                r#\"LEFT JOIN \"public\".\"active_enum\" AS \"r0\" ON \"active_enum_child\".\"parent_id\" = \"r0\".\"id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn create_enum_from() {\n        use sea_orm::{Schema, Statement};\n\n        let db_postgres = DbBackend::Postgres;\n        let schema = Schema::new(db_postgres);\n\n        assert_eq!(\n            schema\n                .create_enum_from_entity(active_enum::Entity)\n                .iter()\n                .map(|stmt| db_postgres.build(stmt))\n                .collect::<Vec<_>>(),\n            [Statement::from_string(\n                db_postgres,\n                r#\"CREATE TYPE \"tea\" AS ENUM ('EverydayTea', 'BreakfastTea', 'AfternoonTea')\"#\n                    .to_owned()\n            ),]\n        );\n\n        assert_eq!(\n            db_postgres.build(&schema.create_enum_from_active_enum::<Tea>().unwrap()),\n            Statement::from_string(\n                db_postgres,\n                r#\"CREATE TYPE \"tea\" AS ENUM ('EverydayTea', 'BreakfastTea', 'AfternoonTea')\"#\n                    .to_owned()\n            )\n        );\n    }\n\n    #[test]\n    fn display_test() {\n        assert_eq!(format!(\"{}\", Tea::BreakfastTea), \"BreakfastTea\");\n        assert_eq!(format!(\"{}\", DisplayTea::BreakfastTea), \"Breakfast\");\n        assert_eq!(format!(\"{}\", Tea::EverydayTea), \"EverydayTea\");\n        assert_eq!(format!(\"{}\", DisplayTea::EverydayTea), \"Everyday\");\n    }\n\n    #[cfg(feature = \"sqlx-postgres\")]\n    #[test]\n    fn derive_partial_model_active_enum_casts_to_text() {\n        use sea_orm::*;\n        use sea_query::PostgresQueryBuilder;\n\n        #[derive(Debug, DerivePartialModel)]\n        #[sea_orm(entity = \"active_enum::Entity\")]\n        struct PartialWithEnum {\n            tea: Option<Tea>,\n        }\n\n        let sql = active_enum::Entity::find()\n            .into_partial_model::<PartialWithEnum>()\n            .into_statement(DbBackend::Postgres)\n            .sql;\n\n        assert_eq!(\n            sql,\n            r#\"SELECT CAST(\"active_enum\".\"tea\" AS \"text\") AS \"tea\" FROM \"public\".\"active_enum\"\"#,\n        );\n\n        #[derive(Debug, DerivePartialModel)]\n        #[sea_orm(entity = \"active_enum::Entity\", from_query_result, alias = \"zzz\")]\n        struct PartialWithEnumAndAlias {\n            #[sea_orm(from_col = \"tea\")]\n            foo: Option<Tea>,\n        }\n\n        let sql = active_enum::Entity::find()\n            .into_partial_model::<PartialWithEnumAndAlias>()\n            .into_statement(DbBackend::Postgres)\n            .sql;\n\n        assert_eq!(\n            sql,\n            r#\"SELECT CAST(\"zzz\".\"tea\" AS \"text\") AS \"foo\" FROM \"public\".\"active_enum\"\"#,\n        );\n\n        #[derive(Debug, DerivePartialModel)]\n        #[sea_orm(entity = \"active_enum::Entity\", from_query_result)]\n        struct PartialWithEnumNested {\n            tea: Option<Tea>,\n            #[sea_orm(nested, alias = \"foo\")]\n            nested: Option<PartialWithEnum>,\n        }\n\n        let sql = active_enum::Entity::find()\n            .into_partial_model::<PartialWithEnumNested>()\n            .into_statement(DbBackend::Postgres)\n            .sql;\n\n        assert_eq!(\n            sql,\n            r#\"SELECT CAST(\"active_enum\".\"tea\" AS \"text\") AS \"tea\", CAST(\"foo\".\"tea\" AS \"text\") AS \"nested_tea\" FROM \"public\".\"active_enum\"\"#,\n        );\n\n        #[derive(Debug, DerivePartialModel)]\n        #[sea_orm(entity = \"active_enum::Entity\", from_query_result, alias = \"aaa\")]\n        struct PartialWithEnumNestedWithAlias {\n            tea: Option<Tea>,\n            #[sea_orm(nested, alias = \"foo\")]\n            nested: Option<PartialWithEnum>,\n        }\n\n        let sql = active_enum::Entity::find()\n            .into_partial_model::<PartialWithEnumNestedWithAlias>()\n            .into_statement(DbBackend::Postgres)\n            .sql;\n\n        assert_eq!(\n            sql,\n            r#\"SELECT CAST(\"aaa\".\"tea\" AS \"text\") AS \"tea\", CAST(\"foo\".\"tea\" AS \"text\") AS \"nested_tea\" FROM \"public\".\"active_enum\"\"#,\n        );\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/active_model_ex_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\nmod common;\n\nuse crate::common::TestContext;\nuse sea_orm::{Database, DbConn, DbErr, entity::*, prelude::*, query::*};\nuse tracing::info;\n\n#[sea_orm_macros::test]\nfn test_active_model_ex_blog() -> Result<(), DbErr> {\n    use common::blogger::*;\n\n    let ctx = TestContext::new(\"test_active_model_ex_blog\");\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(user::Entity)\n        .register(user_follower::Entity)\n        .register(profile::Entity)\n        .register(post::Entity)\n        .register(post_tag::Entity)\n        .register(tag::Entity)\n        .register(attachment::Entity)\n        .register(comment::Entity)\n        .apply(db)?;\n\n    info!(\"save a new user\");\n    let user = user::ActiveModel::builder()\n        .set_name(\"Alice\")\n        .set_email(\"@1\")\n        .save(db)?;\n\n    assert_eq!(user.id, Unchanged(1));\n\n    info!(\"save a post with an existing user\");\n    let post = post::ActiveModel::builder()\n        .set_title(\"post 1\")\n        .set_author(user)\n        .save(db)?;\n\n    assert_eq!(\n        post,\n        post::ActiveModelEx {\n            id: Unchanged(1),\n            user_id: Unchanged(1),\n            title: Unchanged(\"post 1\".into()),\n            author: HasOneModel::set(user::ActiveModelEx {\n                id: Unchanged(1),\n                name: Unchanged(\"Alice\".into()),\n                email: Unchanged(\"@1\".into()),\n                profile: HasOneModel::NotSet,\n                posts: HasManyModel::NotSet,\n                followers: HasManyModel::NotSet,\n                following: HasManyModel::NotSet,\n            }),\n            comments: HasManyModel::NotSet,\n            attachments: HasManyModel::NotSet,\n            tags: HasManyModel::NotSet,\n        }\n    );\n\n    info!(\"save a post with a new user\");\n    let post = post::ActiveModel::builder()\n        .set_title(\"post 2\")\n        .set_author(user::ActiveModel::builder().set_name(\"Bob\").set_email(\"@2\"))\n        .save(db)?;\n\n    if false {\n        post::ActiveModelEx {\n            title: Set(\"post 2\".into()),\n            author: HasOneModel::set(user::ActiveModelEx {\n                name: Set(\"Bob\".into()),\n                email: Set(\"@2\".into()),\n                ..Default::default()\n            }),\n            ..Default::default()\n        };\n    }\n\n    assert_eq!(\n        post,\n        post::ActiveModelEx {\n            id: Unchanged(2),\n            user_id: Unchanged(2),\n            title: Unchanged(\"post 2\".into()),\n            author: HasOneModel::set(user::ActiveModelEx {\n                id: Unchanged(2),\n                name: Unchanged(\"Bob\".into()),\n                email: Unchanged(\"@2\".into()),\n                ..Default::default()\n            }),\n            ..Default::default()\n        }\n    );\n\n    info!(\"save a new user with a new profile\");\n    let user = user::ActiveModel::builder()\n        .set_name(\"Sam\")\n        .set_email(\"@3\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Sam.jpg\"))\n        .save(db)?;\n\n    if false {\n        user::ActiveModelEx {\n            name: Set(\"Sam\".into()),\n            email: Set(\"@3\".into()),\n            profile: HasOneModel::set(profile::ActiveModelEx {\n                picture: Set(\"Sam.jpg\".into()),\n                ..Default::default()\n            }),\n            ..Default::default()\n        };\n    }\n\n    assert_eq!(\n        user,\n        user::ActiveModelEx {\n            id: Unchanged(3),\n            name: Unchanged(\"Sam\".into()),\n            email: Unchanged(\"@3\".into()),\n            profile: HasOneModel::set(profile::ActiveModelEx {\n                id: Unchanged(1),\n                picture: Unchanged(\"Sam.jpg\".into()),\n                user_id: Unchanged(3),\n                user: HasOneModel::NotSet,\n            }),\n            ..Default::default()\n        }\n    );\n\n    info!(\"save a new user with a new profile and 2 posts\");\n    let mut user = user::ActiveModel::builder()\n        .set_name(\"Alan\")\n        .set_email(\"@4\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Alan.jpg\"))\n        .add_post(post::ActiveModel::builder().set_title(\"post 3\"))\n        .add_post(post::ActiveModel::builder().set_title(\"post 4\"))\n        .save(db)?;\n\n    assert_eq!(\n        user,\n        user::ActiveModelEx {\n            id: Unchanged(4),\n            name: Unchanged(\"Alan\".into()),\n            email: Unchanged(\"@4\".into()),\n            profile: HasOneModel::set(profile::ActiveModelEx {\n                id: Unchanged(2),\n                picture: Unchanged(\"Alan.jpg\".into()),\n                user_id: Unchanged(4),\n                user: HasOneModel::NotSet,\n            }),\n            posts: HasManyModel::Append(vec![\n                post::ActiveModelEx {\n                    id: Unchanged(3),\n                    user_id: Unchanged(4),\n                    title: Unchanged(\"post 3\".into()),\n                    ..Default::default()\n                },\n                post::ActiveModelEx {\n                    id: Unchanged(4),\n                    user_id: Unchanged(4),\n                    title: Unchanged(\"post 4\".into()),\n                    ..Default::default()\n                },\n            ]),\n            followers: HasManyModel::NotSet,\n            following: HasManyModel::NotSet,\n        }\n    );\n\n    let posts = user.find_related(post::Entity).all(db)?;\n    assert_eq!(posts.len(), 2);\n    assert_eq!(posts[0].id, 3);\n    assert_eq!(posts[1].id, 4);\n\n    info!(\"replace posts of user: delete 3,4; insert 5 with attachment\");\n    user.posts = HasManyModel::Replace(vec![post::ActiveModelEx {\n        title: Set(\"post 5\".into()),\n        attachments: HasManyModel::Append(vec![attachment::ActiveModelEx {\n            file: Set(\"for post 5\".into()),\n            ..Default::default()\n        }]),\n        ..Default::default()\n    }]);\n\n    let mut user = user.save(db)?;\n\n    let posts = user.find_related(post::Entity).all(db)?;\n    assert_eq!(posts.len(), 1);\n    assert_eq!(posts[0].id, 5);\n    let attachments = posts[0].find_related(attachment::Entity).all(db)?;\n    assert_eq!(attachments.len(), 1);\n    assert_eq!(attachments[0].id, 1);\n    assert_eq!(attachments[0].file, \"for post 5\");\n\n    info!(\"insert attachment for later use\");\n    let attachment_6 = attachment::ActiveModel::builder()\n        .set_file(\"for post 6\")\n        .save(db)?;\n\n    info!(\"add new post to user: insert 6 and attach existing attachment\");\n    user.posts = HasManyModel::Append(vec![post::ActiveModelEx {\n        title: Set(\"post 6\".into()),\n        attachments: HasManyModel::Append(vec![attachment_6]),\n        ..Default::default()\n    }]);\n\n    let mut user = user.save(db)?;\n\n    let posts = user.find_related(post::Entity).all(db)?;\n    assert_eq!(posts.len(), 2);\n    assert_eq!(posts[0].id, 5);\n    assert_eq!(posts[1].id, 6);\n    let attachments = posts[1].find_related(attachment::Entity).all(db)?;\n    assert_eq!(attachments.len(), 1);\n    assert_eq!(attachments[0].file, \"for post 6\");\n\n    info!(\"update post 6 through user\");\n    user.posts[0].title = Set(\"post 6!\".into());\n\n    let mut user = user.save(db)?;\n\n    let posts = user.find_related(post::Entity).all(db)?;\n    assert_eq!(posts.len(), 2);\n    assert_eq!(posts[0].id, 5);\n    assert_eq!(posts[0].title, \"post 5\");\n    assert_eq!(posts[1].id, 6);\n    assert_eq!(posts[1].title, \"post 6!\");\n\n    info!(\"update user profile and delete all posts\");\n    user.profile.as_mut().unwrap().picture = Set(\"Alan2.jpg\".into());\n    // user.posts = HasManyModel::Replace(vec![]);\n    user.posts.replace_all([]);\n    user.save(db)?;\n\n    info!(\"check that user has 0 posts\");\n    let user = user::Entity::load()\n        .filter_by_id(4)\n        .with(profile::Entity)\n        .with(post::Entity)\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(\n        user,\n        user::ModelEx {\n            id: 4,\n            name: \"Alan\".into(),\n            email: \"@4\".into(),\n            profile: HasOne::loaded(profile::Model {\n                id: 2,\n                picture: \"Alan2.jpg\".into(),\n                user_id: 4,\n            }),\n            posts: HasMany::Loaded(vec![]),\n            followers: HasMany::Unloaded,\n            following: HasMany::Unloaded,\n        }\n    );\n\n    info!(\"check that attachment still exists\");\n    let attachment_1 = attachment::Entity::find_by_id(1).one(db)?.unwrap();\n    assert_eq!(attachment_1.file, \"for post 5\");\n    assert!(attachment_1.post_id.is_none());\n\n    info!(\"insert one tag for later use\");\n    let day = tag::ActiveModel {\n        tag: Set(\"day\".into()),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    info!(\"insert new post and set 2 tags\");\n    let post_ = post::ActiveModelEx {\n        id: NotSet,\n        user_id: NotSet,\n        title: Set(\"post 7\".into()),\n        author: HasOneModel::set(user.clone().into_active_model()),\n        comments: HasManyModel::NotSet,\n        attachments: HasManyModel::NotSet,\n        tags: HasManyModel::Append(vec![\n            day.clone().into_active_model().into(),\n            tag::ActiveModel {\n                id: NotSet,\n                tag: Set(\"pet\".into()),\n            }\n            .into(),\n        ]),\n    };\n\n    let post = post::ActiveModel::builder()\n        .set_title(\"post 7\")\n        .set_author(user.into_active_model())\n        .add_tag(day.into_active_model())\n        .add_tag(tag::ActiveModel::builder().set_tag(\"pet\"));\n\n    assert_eq!(post, post_);\n\n    let post = post.save(db)?;\n\n    assert_eq!(\n        post,\n        post::ActiveModelEx {\n            id: Unchanged(7),\n            user_id: Unchanged(4),\n            title: Unchanged(\"post 7\".into()),\n            author: HasOneModel::set(user::ActiveModelEx {\n                id: Unchanged(4),\n                name: Unchanged(\"Alan\".into()),\n                email: Unchanged(\"@4\".into()),\n                profile: HasOneModel::set(profile::ActiveModelEx {\n                    id: Unchanged(2),\n                    picture: Unchanged(\"Alan2.jpg\".into()),\n                    user_id: Unchanged(4),\n                    user: HasOneModel::NotSet,\n                }),\n                posts: HasManyModel::Append(vec![]),\n                followers: HasManyModel::NotSet,\n                following: HasManyModel::NotSet,\n            }),\n            comments: HasManyModel::NotSet,\n            attachments: HasManyModel::NotSet,\n            tags: HasManyModel::Append(vec![\n                tag::ActiveModel {\n                    id: Unchanged(1),\n                    tag: Unchanged(\"day\".into()),\n                }\n                .into(),\n                tag::ActiveModel {\n                    id: Unchanged(2),\n                    tag: Unchanged(\"pet\".into()),\n                }\n                .into(),\n            ]),\n        }\n    );\n\n    info!(\"replace should be idempotent\");\n    let mut post = post.save(db)?;\n\n    info!(\"append should be idempotent\");\n    post.tags.convert_to_append();\n    let mut post = post.save(db)?;\n\n    info!(\"get back the post and tags\");\n    let post_7 = post::Entity::load()\n        .filter_by_id(7)\n        .with(tag::Entity)\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(post_7.id, 7);\n    assert_eq!(post_7.tags.len(), 2);\n    assert_eq!(post_7.tags[0].tag, \"day\");\n    assert_eq!(post_7.tags[1].tag, \"pet\");\n\n    info!(\"add attachment to post\");\n    let mut post_7 = post_7.into_active_model();\n    post_7.attachments.push(attachment::ActiveModel {\n        file: Set(\"for post 7\".into()),\n        ..Default::default()\n    });\n    post_7.insert(db)?;\n\n    info!(\"get back the post and attachment\");\n    let post_7 = post::Entity::load()\n        .filter_by_id(7)\n        .with(attachment::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(post_7.attachments.len(), 1);\n    assert_eq!(post_7.attachments[0].file, \"for post 7\");\n\n    info!(\"update user profile through post\");\n    post.author\n        .as_mut()\n        .unwrap()\n        .profile\n        .as_mut()\n        .unwrap()\n        .picture = Set(\"Alan3.jpg\".into());\n    let mut post = post.save(db)?;\n    assert_eq!(\n        profile::Entity::find_by_id(2).one(db)?.unwrap().picture,\n        \"Alan3.jpg\"\n    );\n\n    info!(\"replace post tags: remove tag 1 add tag 3\");\n    post.tags = HasManyModel::Replace(vec![\n        tag::ActiveModel {\n            id: NotSet, // new tag\n            tag: Set(\"food\".into()),\n        }\n        .into(),\n        tag::ActiveModel {\n            id: Unchanged(2), // retain\n            tag: Unchanged(\"pet\".into()),\n        }\n        .into(),\n    ]);\n    let mut post = post.save(db)?;\n\n    info!(\"get back the post and tags\");\n    let post_7 = post::Entity::load()\n        .filter_by_id(7)\n        .with(tag::Entity)\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(post_7.id, 7);\n    assert_eq!(post_7.tags.len(), 2);\n    assert_eq!(post_7.tags[0].tag, \"pet\");\n    assert_eq!(post_7.tags[1].tag, \"food\");\n\n    info!(\"update post title and add new tag\");\n    post.title = Set(\"post 7!\".into());\n    post.tags = HasManyModel::Append(vec![\n        tag::ActiveModel {\n            id: NotSet, // new tag\n            tag: Set(\"sunny\".into()),\n        }\n        .into(),\n    ]);\n    post.save(db)?;\n\n    info!(\"get back the post and tags\");\n    let post_7 = post::Entity::load()\n        .filter_by_id(7)\n        .with(tag::Entity)\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(post_7.id, 7);\n    assert_eq!(post_7.title, \"post 7!\");\n    assert_eq!(post_7.tags.len(), 3);\n    assert_eq!(post_7.tags[0].tag, \"pet\");\n    assert_eq!(post_7.tags[1].tag, \"food\");\n    assert_eq!(post_7.tags[2].tag, \"sunny\");\n\n    let user_1 = user::Entity::find_by_email(\"@1\").one(db)?.unwrap();\n    info!(\"can't delete as there are posts belonging to user\");\n    assert!(user_1.clone().delete(db).is_err());\n    info!(\"cascade delete user 1\");\n    assert_eq!(user_1.cascade_delete(db)?.rows_affected, 2); // user + post\n    assert!(user::Entity::find_by_email(\"@1\").one(db)?.is_none());\n\n    info!(\"cascade delete user 2\");\n    let user_2 = user::Entity::find_by_email(\"@2\").one(db)?.unwrap();\n    assert_eq!(user_2.cascade_delete(db)?.rows_affected, 2); // user + post\n    assert!(user::Entity::find_by_email(\"@2\").one(db)?.is_none());\n\n    info!(\"cascade delete user 4\");\n    let user_4 = user::Entity::find_by_id(4).one(db)?.unwrap();\n    assert_eq!(user_4.cascade_delete(db)?.rows_affected, 1 + 1 + 3 + 1); // user + profile + post_tag + post\n    assert!(user::Entity::find_by_id(4).one(db)?.is_none());\n\n    info!(\"insert a new user with a new profile and new post with tag\");\n    let user = user::ActiveModel::builder()\n        .set_name(\"Bob\")\n        .set_email(\"bob@sea-ql.org\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"image.jpg\"))\n        .add_post(\n            post::ActiveModel::builder()\n                .set_title(\"Nice weather\")\n                .add_tag(tag::ActiveModel::builder().set_tag(\"sunny\")),\n        )\n        .insert(db)?;\n\n    info!(\"get back the user with profile, posts and tags\");\n    assert_eq!(\n        user::Entity::load()\n            .filter_by_id(user.id)\n            .with(profile::Entity)\n            .with((post::Entity, tag::Entity))\n            .one(db)?\n            .unwrap(),\n        user::ModelEx {\n            id: 5,\n            name: \"Bob\".into(),\n            email: \"bob@sea-ql.org\".into(),\n            profile: HasOne::loaded(profile::Model {\n                id: 3,\n                picture: \"image.jpg\".into(),\n                user_id: 5,\n            }),\n            posts: HasMany::Loaded(vec![post::ModelEx {\n                id: 8,\n                user_id: 5,\n                title: \"Nice weather\".into(),\n                author: HasOne::Unloaded,\n                attachments: HasMany::Unloaded,\n                comments: HasMany::Unloaded,\n                tags: HasMany::Loaded(vec![tag::ModelEx {\n                    id: 5,\n                    tag: \"sunny\".into(),\n                    posts: HasMany::Unloaded,\n                }]),\n            }]),\n            followers: HasMany::Unloaded,\n            following: HasMany::Unloaded,\n        }\n    );\n\n    info!(\"should be no-op\");\n    assert_eq!(user, user.clone().into_active_model().update(db)?);\n\n    // test self_ref via\n\n    info!(\"save a new user Alice\");\n    let alice = user::ActiveModel::builder()\n        .set_name(\"Alice\")\n        .set_email(\"@alice\")\n        .save(db)?;\n\n    let bob = user::Entity::find()\n        .filter(user::COLUMN.name.eq(\"Bob\"))\n        .one(db)?\n        .unwrap()\n        .into_active_model()\n        .into_ex();\n\n    let sam = user::Entity::find()\n        .filter(user::COLUMN.name.eq(\"Sam\"))\n        .one(db)?\n        .unwrap()\n        .into_active_model();\n\n    info!(\"Add follower to Alice\");\n    let alice = alice.add_follower(bob.clone()).save(db)?;\n\n    info!(\"Sam starts following Alice\");\n    sam.clone().into_ex().add_following(alice).save(db)?;\n\n    info!(\"Add follower to Bob\");\n    bob.add_follower(sam).save(db)?;\n\n    let users = user::Entity::load()\n        .with(user_follower::Entity)\n        .with(user_follower::Entity::REVERSE)\n        .order_by_asc(user::COLUMN.name)\n        .all(db)?;\n\n    assert_eq!(users[0].name, \"Alice\");\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0].name, \"Sam\");\n    assert_eq!(users[0].followers[1].name, \"Bob\");\n    assert!(users[0].following.is_empty());\n\n    assert_eq!(users[1].name, \"Bob\");\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0].name, \"Sam\");\n    assert_eq!(users[1].following.len(), 1);\n    assert_eq!(users[1].following[0].name, \"Alice\");\n\n    assert_eq!(users[2].name, \"Sam\");\n    assert!(users[2].followers.is_empty());\n    assert_eq!(users[2].following.len(), 2);\n    assert_eq!(users[2].following[0].name, \"Bob\");\n    assert_eq!(users[2].following[1].name, \"Alice\");\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn test_active_model_ex_film_store() -> Result<(), DbErr> {\n    use common::film_store::*;\n\n    let ctx = TestContext::new(\"test_active_model_ex_film_store\");\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(film::Entity)\n        .register(actor::Entity)\n        .register(film_actor::Entity)\n        .register(staff::Entity)\n        .apply(db)?;\n\n    info!(\"save film Mission, no actors\");\n    let mut film = film::ActiveModel {\n        title: Set(\"Mission\".into()),\n        ..Default::default()\n    }\n    .save(db)?\n    .into_ex();\n\n    info!(\"create two actors and add to film Mission\");\n    film.actors.push(actor::ActiveModel {\n        name: Set(\"Tom\".into()),\n        ..Default::default()\n    });\n    film.actors.push(actor::ActiveModel {\n        name: Set(\"Ben\".into()),\n        ..Default::default()\n    });\n    film.save(db)?;\n\n    info!(\"check that film has two actors\");\n    let film = film::Entity::load().with(actor::Entity).one(db)?.unwrap();\n    assert_eq!(film.title, \"Mission\");\n    assert_eq!(film.actors.len(), 2);\n    assert_eq!(film.actors[0].name, \"Tom\");\n    assert_eq!(film.actors[1].name, \"Ben\");\n\n    info!(\"save new actor Sam, no films\");\n    let tom = film.actors.into_iter().next().unwrap();\n    let sam = actor::ActiveModel {\n        // new actor\n        name: Set(\"Sam\".into()),\n        ..Default::default()\n    }\n    .save(db)?;\n\n    info!(\"save new films Galaxy with Tom and Sam as actors\");\n    film::ActiveModelEx {\n        title: Set(\"Galaxy\".into()),\n        actors: HasManyModel::Replace(vec![tom.into_active_model(), sam.into_ex()]),\n        ..Default::default()\n    }\n    .save(db)?;\n\n    info!(\"film Galaxy has two actors\");\n    let film = film::Entity::load()\n        .filter_by_id(2)\n        .with(actor::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(film.title, \"Galaxy\");\n    assert_eq!(film.actors.len(), 2);\n    assert_eq!(film.actors[0].name, \"Tom\");\n    assert_eq!(film.actors[1].name, \"Sam\");\n\n    info!(\"actor Tom has two films\");\n    let tom = actor::Entity::load()\n        .filter_by_name(\"Tom\")\n        .with(film::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(tom.name, \"Tom\");\n    assert_eq!(tom.films.len(), 2);\n    assert_eq!(tom.films[0].title, \"Mission\");\n    assert_eq!(tom.films[1].title, \"Galaxy\");\n\n    info!(\"cascade delete film Galaxy\");\n    assert_eq!(film.delete(db)?.rows_affected, 3); // film + 2 film_actor\n\n    info!(\"tom has 1 film left\");\n    let tom = actor::Entity::load()\n        .filter_by_name(\"Tom\")\n        .with(film::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(tom.name, \"Tom\");\n    assert_eq!(tom.films.len(), 1);\n    assert_eq!(tom.films[0].title, \"Mission\");\n\n    info!(\"sam still exists, but no films\");\n    let sam = actor::Entity::load()\n        .filter_by_name(\"Sam\")\n        .with(film::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(sam.name, \"Sam\");\n    assert_eq!(sam.films.len(), 0);\n\n    info!(\"should be idempotent\");\n    let mut film = film::Entity::find_by_id(1)\n        .one(db)?\n        .unwrap()\n        .into_active_model()\n        .into_ex();\n    film.actors.push(tom.into_active_model());\n    film.save(db)?;\n\n    // test self_ref\n\n    info!(\"insert new staff: alan\");\n\n    let alan = staff::ActiveModel::builder().set_name(\"Alan\").insert(db)?;\n\n    info!(\"insert new staff: Ben reports to Alan\");\n    staff::ActiveModel::builder()\n        .set_name(\"Ben\")\n        .set_reports_to(alan.clone())\n        .insert(db)?;\n\n    info!(\"insert new staff: Alice\");\n    let alice = staff::ActiveModel::builder().set_name(\"Alice\").insert(db)?;\n\n    info!(\"assign Alice to report to Alan\");\n    let alan = alan\n        .into_active_model()\n        .add_manage(alice.clone())\n        .save(db)?;\n\n    info!(\"insert new staff: Elle\");\n    staff::ActiveModel::builder().set_name(\"Elle\").insert(db)?;\n\n    info!(\"load all staff\");\n    let staff = staff::Entity::load()\n        .with(staff::Relation::ReportsTo)\n        .with(staff::Relation::Manages)\n        .all(db)?;\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(staff[0].reports_to, None);\n    assert_eq!(staff[0].manages[0].name, \"Ben\");\n    assert_eq!(staff[0].manages[1].name, \"Alice\");\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n    assert!(staff[1].manages.is_empty());\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n    assert!(staff[2].manages.is_empty());\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(staff[3].reports_to, None);\n    assert!(staff[3].manages.is_empty());\n\n    info!(\"delete alan, reports_to should be cleared\");\n    alan.delete(db)?;\n\n    info!(\"verify Alice still exists\");\n    assert!(\n        staff::Entity::find_by_id(alice.id)\n            .one(db)?\n            .unwrap()\n            .reports_to_id\n            .is_none()\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/arrow_schema_tests.rs",
    "content": "#![cfg(feature = \"with-arrow\")]\n//! Tests for the DeriveArrowSchema macro.\n//!\n//! cargo t --test arrow_schema_tests --features=with-arrow\n\nuse sea_orm::ArrowSchema;\nuse sea_orm_arrow::arrow::datatypes::{DataType, Field, Schema, TimeUnit};\n\n// ---------------------------------------------------------------------------\n// Entities using #[sea_orm::model] (2.0 format, arrow_schema flag)\n// ---------------------------------------------------------------------------\n\nmod basic_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"basic\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_name = \"user_name\")]\n        pub name: String,\n        pub flag: bool,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod split_attrs_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"split_attrs\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        #[sea_orm(auto_increment = false)]\n        pub id: i32,\n        pub name: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod float_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"floats\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub float_val: f32,\n        pub double_val: f64,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod nullable_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"nullable\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub required_name: String,\n        pub optional_name: Option<String>,\n        pub optional_int: Option<i32>,\n        #[sea_orm(nullable)]\n        pub nullable_via_attr: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod string_variants_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"string_variants\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub plain: String,\n        #[sea_orm(column_type = \"Text\")]\n        pub text_field: String,\n        #[sea_orm(column_type = \"Char(Some(10))\")]\n        pub char_field: String,\n        #[sea_orm(column_type = \"String(StringLen::N(100))\")]\n        pub short_string: String,\n        #[sea_orm(column_type = \"String(StringLen::N(50000))\")]\n        pub long_string: String,\n        #[sea_orm(column_type = \"String(StringLen::Max)\")]\n        pub max_string: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod comment_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"comment_test\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(arrow_comment = \"The user's display name\")]\n        pub name: String,\n        #[sea_orm(nullable, arrow_comment = \"Optional email address\")]\n        pub email: Option<String>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod timestamp_override_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"timestamp_override\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_type = \"DateTime\", arrow_timestamp_unit = \"Nanosecond\")]\n        pub nano_ts: String,\n        #[sea_orm(column_type = \"DateTime\", arrow_timestamp_unit = \"Second\")]\n        pub second_ts: String,\n        #[sea_orm(column_type = \"DateTime\", arrow_timestamp_unit = \"Millisecond\")]\n        pub milli_ts: String,\n        #[sea_orm(\n            column_type = \"DateTime\",\n            arrow_timestamp_unit = \"Nanosecond\",\n            arrow_timezone = \"America/New_York\"\n        )]\n        pub nano_with_tz: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod decimal_override_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"decimal_override\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(\n            column_type = \"Decimal(Some((10, 2)))\",\n            arrow_precision = 20,\n            arrow_scale = 4\n        )]\n        pub overridden: String,\n        #[sea_orm(column_type = \"Decimal(Some((10, 2)))\", arrow_precision = 50)]\n        pub large_precision: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// ---------------------------------------------------------------------------\n// Entities using old format (manual Relation enum + DeriveArrowSchema)\n// ---------------------------------------------------------------------------\n\nmod all_integers_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, DeriveArrowSchema)]\n    #[sea_orm(table_name = \"all_integers\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub tiny: i8,\n        pub small: i16,\n        pub big: i64,\n        pub tiny_u: u8,\n        pub small_u: u16,\n        pub uint: u32,\n        pub big_u: u64,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod column_type_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel, DeriveArrowSchema)]\n    #[sea_orm(table_name = \"column_types\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_type = \"Text\")]\n        pub description: String,\n        #[sea_orm(column_type = \"Boolean\")]\n        pub active: bool,\n        #[sea_orm(column_type = \"TinyInteger\")]\n        pub tiny: i8,\n        #[sea_orm(column_type = \"SmallInteger\")]\n        pub small: i16,\n        #[sea_orm(column_type = \"BigInteger\")]\n        pub big: i64,\n        #[sea_orm(column_type = \"TinyUnsigned\")]\n        pub tiny_u: u8,\n        #[sea_orm(column_type = \"SmallUnsigned\")]\n        pub small_u: u16,\n        #[sea_orm(column_type = \"Unsigned\")]\n        pub uint: u32,\n        #[sea_orm(column_type = \"BigUnsigned\")]\n        pub big_u: u64,\n        #[sea_orm(column_type = \"Float\")]\n        pub fval: f32,\n        #[sea_orm(column_type = \"Double\")]\n        pub dval: f64,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod skip_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, DeriveArrowSchema)]\n    #[sea_orm(table_name = \"skip_test\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_name = \"db_visible\", arrow_field = \"arrowVisible\")]\n        pub visible: String,\n        #[sea_orm(arrow_skip)]\n        pub internal: String,\n        #[sea_orm(column_name = \"db_also_visible\")]\n        pub also_visible: bool,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod special_types_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, DeriveArrowSchema)]\n    #[sea_orm(table_name = \"special_types\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_type = \"Json\")]\n        pub json_data: String,\n        #[sea_orm(column_type = \"JsonBinary\")]\n        pub jsonb_data: String,\n        #[sea_orm(column_type = \"Uuid\")]\n        pub uuid_val: String,\n        #[sea_orm(column_type = \"Binary(16)\")]\n        pub bin_val: Vec<u8>,\n        #[sea_orm(column_type = \"VarBinary(StringLen::N(256))\")]\n        pub varbin_val: Vec<u8>,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod date_time_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, DeriveArrowSchema)]\n    #[sea_orm(table_name = \"date_time_test\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub date_val: Date,\n        pub time_val: Time,\n        pub datetime_val: DateTime,\n        #[sea_orm(column_type = \"Timestamp\")]\n        pub timestamp_val: String,\n        pub timestamptz_val: DateTimeWithTimeZone,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod decimal_column_type_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, DeriveArrowSchema)]\n    #[sea_orm(table_name = \"decimal_column_type\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_type = \"Decimal(Some((10, 2)))\")]\n        pub price: String,\n        #[sea_orm(column_type = \"Decimal(Some((20, 4)))\")]\n        pub amount: String,\n        #[sea_orm(column_type = \"Decimal(None)\")]\n        pub default_decimal: String,\n        #[sea_orm(column_type = \"Money(None)\")]\n        pub money_val: String,\n        #[sea_orm(column_type = \"Money(Some((12, 3)))\")]\n        pub money_custom: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// ---------------------------------------------------------------------------\n// Tests\n// ---------------------------------------------------------------------------\n\n#[test]\nfn test_basic_schema() {\n    let schema = basic_entity::Entity::arrow_schema();\n    let expected = Schema::new(vec![\n        Field::new(\"id\", DataType::Int32, true),\n        // column_name = \"user_name\" should be used instead of \"name\"\n        Field::new(\"user_name\", DataType::Utf8, true),\n        Field::new(\"flag\", DataType::Boolean, true),\n    ]);\n    assert_eq!(schema, expected);\n}\n\n#[test]\nfn test_all_integer_types() {\n    let schema = all_integers_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n    assert_eq!(fields.len(), 8);\n    assert_eq!(fields[0].as_ref(), &Field::new(\"id\", DataType::Int32, true));\n    assert_eq!(\n        fields[1].as_ref(),\n        &Field::new(\"tiny\", DataType::Int8, true)\n    );\n    assert_eq!(\n        fields[2].as_ref(),\n        &Field::new(\"small\", DataType::Int16, true)\n    );\n    assert_eq!(\n        fields[3].as_ref(),\n        &Field::new(\"big\", DataType::Int64, true)\n    );\n    assert_eq!(\n        fields[4].as_ref(),\n        &Field::new(\"tiny_u\", DataType::UInt8, true)\n    );\n    assert_eq!(\n        fields[5].as_ref(),\n        &Field::new(\"small_u\", DataType::UInt16, true)\n    );\n    assert_eq!(\n        fields[6].as_ref(),\n        &Field::new(\"uint\", DataType::UInt32, true)\n    );\n    assert_eq!(\n        fields[7].as_ref(),\n        &Field::new(\"big_u\", DataType::UInt64, true)\n    );\n}\n\n#[test]\nfn test_float_types() {\n    let schema = float_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n    assert_eq!(\n        fields[1].as_ref(),\n        &Field::new(\"float_val\", DataType::Float32, true)\n    );\n    assert_eq!(\n        fields[2].as_ref(),\n        &Field::new(\"double_val\", DataType::Float64, true)\n    );\n}\n\n#[test]\nfn test_nullable_fields() {\n    let schema = nullable_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // required_name: not nullable\n    assert_eq!(fields[1].name(), \"required_name\");\n    assert!(fields[1].is_nullable());\n\n    // optional_name: Option<String> -> nullable\n    assert_eq!(fields[2].name(), \"optional_name\");\n    assert!(fields[2].is_nullable());\n\n    // optional_int: Option<i32> -> nullable\n    assert_eq!(fields[3].name(), \"optional_int\");\n    assert!(fields[3].is_nullable());\n\n    // nullable_via_attr: #[sea_orm(nullable)] -> nullable\n    assert_eq!(fields[4].name(), \"nullable_via_attr\");\n    assert!(fields[4].is_nullable());\n}\n\n#[test]\nfn test_column_type_overrides() {\n    let schema = column_type_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    assert_eq!(fields[0].data_type(), &DataType::Int32); // id\n    assert_eq!(fields[1].data_type(), &DataType::LargeUtf8); // Text\n    assert_eq!(fields[2].data_type(), &DataType::Boolean); // Boolean\n    assert_eq!(fields[3].data_type(), &DataType::Int8); // TinyInteger\n    assert_eq!(fields[4].data_type(), &DataType::Int16); // SmallInteger\n    assert_eq!(fields[5].data_type(), &DataType::Int64); // BigInteger\n    assert_eq!(fields[6].data_type(), &DataType::UInt8); // TinyUnsigned\n    assert_eq!(fields[7].data_type(), &DataType::UInt16); // SmallUnsigned\n    assert_eq!(fields[8].data_type(), &DataType::UInt32); // Unsigned\n    assert_eq!(fields[9].data_type(), &DataType::UInt64); // BigUnsigned\n    assert_eq!(fields[10].data_type(), &DataType::Float32); // Float\n    assert_eq!(fields[11].data_type(), &DataType::Float64); // Double\n}\n\n#[test]\nfn test_string_variants() {\n    let schema = string_variants_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // plain String -> Utf8\n    assert_eq!(fields[1].data_type(), &DataType::Utf8);\n    // Text -> LargeUtf8\n    assert_eq!(fields[2].data_type(), &DataType::LargeUtf8);\n    // Char -> Utf8\n    assert_eq!(fields[3].data_type(), &DataType::Utf8);\n    // String(N(100)) where 100 <= 32767 -> Utf8\n    assert_eq!(fields[4].data_type(), &DataType::Utf8);\n    // String(N(50000)) where 50000 > 32767 -> LargeUtf8\n    assert_eq!(fields[5].data_type(), &DataType::LargeUtf8);\n    // String(Max) -> LargeUtf8\n    assert_eq!(fields[6].data_type(), &DataType::LargeUtf8);\n}\n\n#[test]\nfn test_arrow_skip() {\n    let schema = skip_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // Should have 3 fields: id, visible, also_visible (internal is skipped)\n    assert_eq!(fields.len(), 3);\n    assert_eq!(fields[0].name(), \"id\");\n    // arrow_field = \"arrowVisible\" takes priority over column_name = \"db_visible\"\n    assert_eq!(fields[1].name(), \"arrowVisible\");\n    // column_name = \"db_also_visible\" is used when no arrow_field is set\n    assert_eq!(fields[2].name(), \"db_also_visible\");\n}\n\n#[test]\nfn test_arrow_comment_metadata() {\n    let schema = comment_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // name field has comment metadata\n    let name_field = fields[1].as_ref();\n    assert_eq!(name_field.name(), \"name\");\n    let metadata = name_field.metadata();\n    assert_eq!(\n        metadata.get(\"comment\"),\n        Some(&\"The user's display name\".to_string())\n    );\n\n    // email field has comment metadata and is nullable\n    let email_field = fields[2].as_ref();\n    assert_eq!(email_field.name(), \"email\");\n    assert!(email_field.is_nullable());\n    let metadata = email_field.metadata();\n    assert_eq!(\n        metadata.get(\"comment\"),\n        Some(&\"Optional email address\".to_string())\n    );\n}\n\n#[test]\nfn test_special_types() {\n    let schema = special_types_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // Json -> Utf8\n    assert_eq!(fields[1].data_type(), &DataType::Utf8);\n    // JsonBinary -> Utf8\n    assert_eq!(fields[2].data_type(), &DataType::Utf8);\n    // Uuid -> Binary\n    assert_eq!(fields[3].data_type(), &DataType::Binary);\n    // Binary(16) -> Binary\n    assert_eq!(fields[4].data_type(), &DataType::Binary);\n    // VarBinary -> Binary\n    assert_eq!(fields[5].data_type(), &DataType::Binary);\n}\n\n#[test]\nfn test_date_time_column_types() {\n    let schema = date_time_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // Date -> Date32\n    assert_eq!(fields[1].data_type(), &DataType::Date32);\n    // Time -> Time64(Microsecond)\n    assert_eq!(\n        fields[2].data_type(),\n        &DataType::Time64(TimeUnit::Microsecond)\n    );\n    // DateTime -> Timestamp(Microsecond, None)\n    assert_eq!(\n        fields[3].data_type(),\n        &DataType::Timestamp(TimeUnit::Microsecond, None)\n    );\n    // Timestamp -> Timestamp(Microsecond, None)\n    assert_eq!(\n        fields[4].data_type(),\n        &DataType::Timestamp(TimeUnit::Microsecond, None)\n    );\n    // TimestampWithTimeZone -> Timestamp(Microsecond, Some(\"UTC\"))\n    assert_eq!(\n        fields[5].data_type(),\n        &DataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into()))\n    );\n}\n\n#[test]\nfn test_timestamp_unit_overrides() {\n    let schema = timestamp_override_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // Nanosecond override\n    assert_eq!(\n        fields[1].data_type(),\n        &DataType::Timestamp(TimeUnit::Nanosecond, None)\n    );\n    // Second override\n    assert_eq!(\n        fields[2].data_type(),\n        &DataType::Timestamp(TimeUnit::Second, None)\n    );\n    // Millisecond override\n    assert_eq!(\n        fields[3].data_type(),\n        &DataType::Timestamp(TimeUnit::Millisecond, None)\n    );\n    // Nanosecond + timezone override\n    assert_eq!(\n        fields[4].data_type(),\n        &DataType::Timestamp(TimeUnit::Nanosecond, Some(\"America/New_York\".into()))\n    );\n}\n\n#[test]\nfn test_decimal_column_types() {\n    let schema = decimal_column_type_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // Decimal(Some((10, 2))) -> Decimal64(10, 2) (precision ≤ 18)\n    assert_eq!(fields[1].data_type(), &DataType::Decimal64(10, 2));\n    // Decimal(Some((20, 4))) -> Decimal128(20, 4) (precision > 18)\n    assert_eq!(fields[2].data_type(), &DataType::Decimal128(20, 4));\n    // Decimal(None) -> Decimal128(38, 10)\n    assert_eq!(fields[3].data_type(), &DataType::Decimal128(38, 10));\n    // Money(None) -> Decimal128(19, 4) (precision 19 > 18)\n    assert_eq!(fields[4].data_type(), &DataType::Decimal128(19, 4));\n    // Money(Some((12, 3))) -> Decimal128 (defaults to precision 19)\n    assert!(matches!(fields[5].data_type(), DataType::Decimal128(..)));\n}\n\n#[test]\nfn test_decimal_arrow_precision_override() {\n    let schema = decimal_override_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // arrow_precision=20, arrow_scale=4 overrides column_type's (10, 2)\n    assert_eq!(fields[1].data_type(), &DataType::Decimal128(20, 4));\n\n    // arrow_precision=50 (>38) -> Decimal256, scale falls back to column_type's 2\n    assert_eq!(fields[2].data_type(), &DataType::Decimal256(50, 2));\n}\n\n#[test]\nfn test_field_count_matches() {\n    assert_eq!(basic_entity::Entity::arrow_schema().fields().len(), 3);\n    assert_eq!(\n        all_integers_entity::Entity::arrow_schema().fields().len(),\n        8\n    );\n    assert_eq!(float_entity::Entity::arrow_schema().fields().len(), 3);\n    assert_eq!(nullable_entity::Entity::arrow_schema().fields().len(), 5);\n    assert_eq!(skip_entity::Entity::arrow_schema().fields().len(), 3); // 1 skipped\n    assert_eq!(comment_entity::Entity::arrow_schema().fields().len(), 3);\n}\n\n#[test]\nfn test_field_names_preserve_snake_case() {\n    let schema = all_integers_entity::Entity::arrow_schema();\n    let names: Vec<&str> = schema.fields().iter().map(|f| f.name().as_str()).collect();\n    assert_eq!(\n        names,\n        vec![\n            \"id\", \"tiny\", \"small\", \"big\", \"tiny_u\", \"small_u\", \"uint\", \"big_u\"\n        ]\n    );\n}\n\n// ---------------------------------------------------------------------------\n// Chrono type tests (feature-gated)\n// ---------------------------------------------------------------------------\n\n#[cfg(feature = \"with-chrono\")]\nmod chrono_schema_tests {\n    use super::*;\n\n    // 2.0 format\n    mod chrono_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[sea_orm::model]\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"chrono_schema\", arrow_schema)]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            pub date_val: ChronoDate,\n            pub time_val: ChronoTime,\n            pub datetime_val: ChronoDateTime,\n            pub datetime_utc: ChronoDateTimeUtc,\n            pub optional_date: Option<ChronoDate>,\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    // Old format\n    mod chrono_override_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel, DeriveArrowSchema)]\n        #[sea_orm(table_name = \"chrono_override\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(arrow_timestamp_unit = \"Nanosecond\")]\n            pub nano_dt: ChronoDateTime,\n            #[sea_orm(arrow_timestamp_unit = \"Nanosecond\", arrow_timezone = \"UTC\")]\n            pub nano_utc: ChronoDateTimeUtc,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn test_chrono_date() {\n        let schema = chrono_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        assert_eq!(fields[1].name(), \"date_val\");\n        assert_eq!(fields[1].data_type(), &DataType::Date32);\n        assert!(fields[1].is_nullable());\n    }\n\n    #[test]\n    fn test_chrono_time() {\n        let schema = chrono_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        assert_eq!(fields[2].name(), \"time_val\");\n        assert_eq!(\n            fields[2].data_type(),\n            &DataType::Time64(TimeUnit::Microsecond)\n        );\n    }\n\n    #[test]\n    fn test_chrono_datetime_naive() {\n        let schema = chrono_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        assert_eq!(fields[3].name(), \"datetime_val\");\n        assert_eq!(\n            fields[3].data_type(),\n            &DataType::Timestamp(TimeUnit::Microsecond, None)\n        );\n    }\n\n    #[test]\n    fn test_chrono_datetime_utc() {\n        let schema = chrono_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        assert_eq!(fields[4].name(), \"datetime_utc\");\n        assert_eq!(\n            fields[4].data_type(),\n            &DataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into()))\n        );\n    }\n\n    #[test]\n    fn test_chrono_optional_nullable() {\n        let schema = chrono_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        assert_eq!(fields[5].name(), \"optional_date\");\n        assert!(fields[5].is_nullable());\n        assert_eq!(fields[5].data_type(), &DataType::Date32);\n    }\n\n    #[test]\n    fn test_chrono_timestamp_unit_override() {\n        let schema = chrono_override_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        // ChronoDateTime with Nanosecond override, no timezone\n        assert_eq!(\n            fields[1].data_type(),\n            &DataType::Timestamp(TimeUnit::Nanosecond, None)\n        );\n\n        // ChronoDateTimeUtc with Nanosecond + explicit UTC\n        assert_eq!(\n            fields[2].data_type(),\n            &DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into()))\n        );\n    }\n}\n\n// ---------------------------------------------------------------------------\n// Decimal type tests with rust_decimal (feature-gated)\n// ---------------------------------------------------------------------------\n\n#[cfg(feature = \"with-rust_decimal\")]\nmod rust_decimal_schema_tests {\n    use super::*;\n\n    // Old format\n    mod decimal_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel, DeriveArrowSchema)]\n        #[sea_orm(table_name = \"decimal_schema\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(column_type = \"Decimal(Some((10, 2)))\")]\n            pub price: Decimal,\n            pub inferred_decimal: Decimal,\n            pub optional_decimal: Option<Decimal>,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn test_decimal_with_column_type() {\n        let schema = decimal_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        // precision 10 ≤ 18 → Decimal64\n        assert_eq!(fields[1].data_type(), &DataType::Decimal64(10, 2));\n        assert!(fields[1].is_nullable());\n    }\n\n    #[test]\n    fn test_decimal_inferred_type() {\n        let schema = decimal_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        // Inferred from Rust type Decimal -> Decimal128(38, 10) defaults\n        assert_eq!(fields[2].data_type(), &DataType::Decimal128(38, 10));\n    }\n\n    #[test]\n    fn test_decimal_optional_nullable() {\n        let schema = decimal_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        assert!(fields[3].is_nullable());\n        assert_eq!(fields[3].data_type(), &DataType::Decimal128(38, 10));\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/arrow_tests.rs",
    "content": "#![cfg(feature = \"with-arrow\")]\n//! cargo t --test arrow_tests --features=with-arrow\n//! cargo t --test arrow_tests --features=with-arrow,with-bigdecimal\nuse sea_orm::entity::prelude::*;\nuse sea_orm::{ActiveValue::NotSet, ArrowSchema, Set, arrow};\nuse sea_orm_arrow::arrow::array::*;\nuse sea_orm_arrow::arrow::datatypes::{DataType, Field, Schema, TimeUnit};\nuse std::sync::Arc;\n\n/// Test entity with all supported primitive types\nmod primitive_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"test_arrow\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub tiny: i8,\n        pub small: i16,\n        pub big: i64,\n        pub tiny_u: u8,\n        pub small_u: u16,\n        pub uint: u32,\n        pub big_u: u64,\n        pub float_val: f32,\n        pub double_val: f64,\n        pub name: String,\n        pub flag: bool,\n        pub nullable_int: Option<i32>,\n        pub nullable_name: Option<String>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n/// Test entity with column_name overrides\nmod column_name_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"test_col_names\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_name = \"user_name\")]\n        pub name: String,\n        #[sea_orm(column_name = \"is_active\")]\n        pub active: bool,\n        #[sea_orm(column_name = \"score_value\")]\n        pub score: Option<f64>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nfn make_batch() -> RecordBatch {\n    let schema = Arc::new(Schema::new(vec![\n        Field::new(\"id\", DataType::Int32, false),\n        Field::new(\"tiny\", DataType::Int8, false),\n        Field::new(\"small\", DataType::Int16, false),\n        Field::new(\"big\", DataType::Int64, false),\n        Field::new(\"tiny_u\", DataType::UInt8, false),\n        Field::new(\"small_u\", DataType::UInt16, false),\n        Field::new(\"uint\", DataType::UInt32, false),\n        Field::new(\"big_u\", DataType::UInt64, false),\n        Field::new(\"float_val\", DataType::Float32, false),\n        Field::new(\"double_val\", DataType::Float64, false),\n        Field::new(\"name\", DataType::Utf8, false),\n        Field::new(\"flag\", DataType::Boolean, false),\n        Field::new(\"nullable_int\", DataType::Int32, true),\n        Field::new(\"nullable_name\", DataType::Utf8, true),\n    ]));\n\n    RecordBatch::try_new(\n        schema,\n        vec![\n            Arc::new(Int32Array::from(vec![1, 2])),\n            Arc::new(Int8Array::from(vec![10i8, 20])),\n            Arc::new(Int16Array::from(vec![100i16, 200])),\n            Arc::new(Int64Array::from(vec![1000i64, 2000])),\n            Arc::new(UInt8Array::from(vec![5u8, 6])),\n            Arc::new(UInt16Array::from(vec![50u16, 60])),\n            Arc::new(UInt32Array::from(vec![500u32, 600])),\n            Arc::new(UInt64Array::from(vec![5000u64, 6000])),\n            Arc::new(Float32Array::from(vec![1.5f32, 2.5])),\n            Arc::new(Float64Array::from(vec![10.5f64, 20.5])),\n            Arc::new(StringArray::from(vec![\"Alice\", \"Bob\"])),\n            Arc::new(BooleanArray::from(vec![true, false])),\n            Arc::new(Int32Array::from(vec![Some(42), None])),\n            Arc::new(StringArray::from(vec![Some(\"hello\"), None])),\n        ],\n    )\n    .expect(\"Failed to create RecordBatch\")\n}\n\n#[test]\nfn test_from_arrow_basic() {\n    let batch = make_batch();\n    let active_models =\n        primitive_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n\n    assert_eq!(active_models.len(), 2);\n\n    let am = &active_models[0];\n    assert_eq!(am.id, Set(1));\n    assert_eq!(am.tiny, Set(10));\n    assert_eq!(am.small, Set(100));\n    assert_eq!(am.big, Set(1000));\n    assert_eq!(am.tiny_u, Set(5));\n    assert_eq!(am.small_u, Set(50));\n    assert_eq!(am.uint, Set(500));\n    assert_eq!(am.big_u, Set(5000));\n    assert_eq!(am.float_val, Set(1.5));\n    assert_eq!(am.double_val, Set(10.5));\n    assert_eq!(am.name, Set(\"Alice\".to_owned()));\n    assert_eq!(am.flag, Set(true));\n    assert_eq!(am.nullable_int, Set(Some(42)));\n    assert_eq!(am.nullable_name, Set(Some(\"hello\".to_owned())));\n\n    let am = &active_models[1];\n    assert_eq!(am.id, Set(2));\n    assert_eq!(am.tiny, Set(20));\n    assert_eq!(am.name, Set(\"Bob\".to_owned()));\n    assert_eq!(am.flag, Set(false));\n    assert_eq!(am.nullable_int, Set(None));\n    assert_eq!(am.nullable_name, Set(None));\n}\n\n#[test]\nfn test_from_arrow_missing_columns() {\n    let schema = Arc::new(Schema::new(vec![\n        Field::new(\"id\", DataType::Int32, false),\n        Field::new(\"name\", DataType::Utf8, false),\n    ]));\n\n    let batch = RecordBatch::try_new(\n        schema,\n        vec![\n            Arc::new(Int32Array::from(vec![42])),\n            Arc::new(StringArray::from(vec![\"partial\"])),\n        ],\n    )\n    .expect(\"Failed to create RecordBatch\");\n\n    let active_models =\n        primitive_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n    assert_eq!(active_models.len(), 1);\n\n    let am = &active_models[0];\n    assert_eq!(am.id, Set(42));\n    assert_eq!(am.name, Set(\"partial\".to_owned()));\n    assert_eq!(am.tiny, NotSet);\n    assert_eq!(am.small, NotSet);\n    assert_eq!(am.big, NotSet);\n    assert_eq!(am.float_val, NotSet);\n    assert_eq!(am.double_val, NotSet);\n    assert_eq!(am.flag, NotSet);\n    assert_eq!(am.nullable_int, NotSet);\n    assert_eq!(am.nullable_name, NotSet);\n}\n\n#[test]\nfn test_from_arrow_empty_batch() {\n    let schema = Arc::new(Schema::new(vec![\n        Field::new(\"id\", DataType::Int32, false),\n        Field::new(\"name\", DataType::Utf8, false),\n    ]));\n\n    let batch = RecordBatch::new_empty(schema);\n    let active_models =\n        primitive_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n    assert!(active_models.is_empty());\n}\n\n#[test]\nfn test_from_arrow_type_mismatch() {\n    let schema = Arc::new(Schema::new(vec![Field::new(\"id\", DataType::Int64, false)]));\n\n    let batch = RecordBatch::try_new(schema, vec![Arc::new(Int64Array::from(vec![1i64]))])\n        .expect(\"Failed to create RecordBatch\");\n\n    let result = primitive_entity::ActiveModel::from_arrow(&batch);\n    assert!(result.is_err());\n    assert!(matches!(result.unwrap_err(), DbErr::Type(_)));\n}\n\n// ===========================================================================\n// to_arrow tests\n// ===========================================================================\n\n#[test]\nfn test_to_arrow_basic_primitives() {\n    use sea_orm::ArrowSchema;\n\n    let schema = primitive_entity::Entity::arrow_schema();\n\n    let models = vec![\n        primitive_entity::ActiveModel {\n            id: Set(1),\n            tiny: Set(10),\n            small: Set(100),\n            big: Set(1000),\n            tiny_u: Set(5),\n            small_u: Set(50),\n            uint: Set(500),\n            big_u: Set(5000),\n            float_val: Set(1.5),\n            double_val: Set(10.5),\n            name: Set(\"Alice\".to_owned()),\n            flag: Set(true),\n            nullable_int: Set(Some(42)),\n            nullable_name: Set(Some(\"hello\".to_owned())),\n        },\n        primitive_entity::ActiveModel {\n            id: Set(2),\n            tiny: Set(20),\n            small: Set(200),\n            big: Set(2000),\n            tiny_u: Set(6),\n            small_u: Set(60),\n            uint: Set(600),\n            big_u: Set(6000),\n            float_val: Set(2.5),\n            double_val: Set(20.5),\n            name: Set(\"Bob\".to_owned()),\n            flag: Set(false),\n            nullable_int: Set(None),\n            nullable_name: Set(None),\n        },\n    ];\n\n    let batch = primitive_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n\n    assert_eq!(batch.num_rows(), 2);\n    assert_eq!(batch.num_columns(), 14);\n\n    // Verify integer columns\n    let id_arr = batch\n        .column_by_name(\"id\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Int32Array>()\n        .unwrap();\n    assert_eq!(id_arr.value(0), 1);\n    assert_eq!(id_arr.value(1), 2);\n\n    let tiny_arr = batch\n        .column_by_name(\"tiny\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Int8Array>()\n        .unwrap();\n    assert_eq!(tiny_arr.value(0), 10);\n    assert_eq!(tiny_arr.value(1), 20);\n\n    // Verify unsigned\n    let tiny_u_arr = batch\n        .column_by_name(\"tiny_u\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<UInt8Array>()\n        .unwrap();\n    assert_eq!(tiny_u_arr.value(0), 5);\n\n    // Verify floats\n    let float_arr = batch\n        .column_by_name(\"float_val\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Float32Array>()\n        .unwrap();\n    assert_eq!(float_arr.value(0), 1.5);\n\n    let double_arr = batch\n        .column_by_name(\"double_val\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Float64Array>()\n        .unwrap();\n    assert_eq!(double_arr.value(0), 10.5);\n\n    // Verify strings\n    let name_arr = batch\n        .column_by_name(\"name\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<StringArray>()\n        .unwrap();\n    assert_eq!(name_arr.value(0), \"Alice\");\n    assert_eq!(name_arr.value(1), \"Bob\");\n\n    // Verify boolean\n    let flag_arr = batch\n        .column_by_name(\"flag\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<BooleanArray>()\n        .unwrap();\n    assert!(flag_arr.value(0));\n    assert!(!flag_arr.value(1));\n\n    // Verify nullable: row 0 has values, row 1 has nulls\n    let ni_arr = batch\n        .column_by_name(\"nullable_int\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Int32Array>()\n        .unwrap();\n    assert!(!ni_arr.is_null(0));\n    assert_eq!(ni_arr.value(0), 42);\n    assert!(ni_arr.is_null(1));\n\n    let nn_arr = batch\n        .column_by_name(\"nullable_name\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<StringArray>()\n        .unwrap();\n    assert!(!nn_arr.is_null(0));\n    assert_eq!(nn_arr.value(0), \"hello\");\n    assert!(nn_arr.is_null(1));\n}\n\n#[test]\nfn test_to_arrow_not_set_becomes_null() {\n    // Use an all-nullable schema so that NotSet → null is accepted by Arrow\n    let base = primitive_entity::Entity::arrow_schema();\n    let nullable_fields: Vec<Field> = base\n        .fields()\n        .iter()\n        .map(|f| Field::new(f.name(), f.data_type().clone(), true))\n        .collect();\n    let schema = Schema::new(nullable_fields);\n\n    // ActiveModel with only id and name set; everything else is NotSet\n    let models = vec![primitive_entity::ActiveModel {\n        id: Set(99),\n        name: Set(\"partial\".to_owned()),\n        ..Default::default()\n    }];\n\n    let batch = primitive_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n    assert_eq!(batch.num_rows(), 1);\n\n    // id and name should be present\n    let id_arr = batch\n        .column_by_name(\"id\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Int32Array>()\n        .unwrap();\n    assert_eq!(id_arr.value(0), 99);\n\n    // NotSet fields should be null\n    let tiny_arr = batch\n        .column_by_name(\"tiny\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Int8Array>()\n        .unwrap();\n    assert!(tiny_arr.is_null(0));\n\n    let flag_arr = batch\n        .column_by_name(\"flag\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<BooleanArray>()\n        .unwrap();\n    assert!(flag_arr.is_null(0));\n}\n\n#[test]\nfn test_to_arrow_empty_slice() {\n    let schema = primitive_entity::Entity::arrow_schema();\n    let batch = primitive_entity::ActiveModel::to_arrow(&[], &schema).expect(\"to_arrow failed\");\n    assert_eq!(batch.num_rows(), 0);\n    assert_eq!(batch.num_columns(), 14);\n}\n\n// ===========================================================================\n// column_name attribute tests\n// ===========================================================================\n\n#[test]\nfn test_column_name_schema_uses_db_names() {\n    // DeriveArrowSchema should use the column_name attribute values, not the Rust field names\n    let schema = column_name_entity::Entity::arrow_schema();\n    let field_names: Vec<&str> = schema.fields().iter().map(|f| f.name().as_str()).collect();\n\n    assert_eq!(\n        field_names,\n        vec![\"id\", \"user_name\", \"is_active\", \"score_value\"]\n    );\n}\n\n#[test]\nfn test_column_name_to_arrow_uses_db_names() {\n    let schema = column_name_entity::Entity::arrow_schema();\n\n    let models = vec![column_name_entity::ActiveModel {\n        id: Set(1),\n        name: Set(\"Alice\".to_owned()),\n        active: Set(true),\n        score: Set(Some(95.5)),\n    }];\n\n    let batch =\n        column_name_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n\n    // Columns should be accessible by their column_name (db name), not the Rust field name\n    assert!(batch.column_by_name(\"user_name\").is_some());\n    assert!(batch.column_by_name(\"is_active\").is_some());\n    assert!(batch.column_by_name(\"score_value\").is_some());\n\n    // Rust field names should NOT appear in the batch\n    assert!(batch.column_by_name(\"name\").is_none());\n    assert!(batch.column_by_name(\"active\").is_none());\n    assert!(batch.column_by_name(\"score\").is_none());\n\n    // Verify values\n    let name_arr = batch\n        .column_by_name(\"user_name\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<StringArray>()\n        .unwrap();\n    assert_eq!(name_arr.value(0), \"Alice\");\n\n    let active_arr = batch\n        .column_by_name(\"is_active\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<BooleanArray>()\n        .unwrap();\n    assert!(active_arr.value(0));\n\n    let score_arr = batch\n        .column_by_name(\"score_value\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Float64Array>()\n        .unwrap();\n    assert_eq!(score_arr.value(0), 95.5);\n}\n\n#[test]\nfn test_column_name_from_arrow_uses_db_names() {\n    // Build a RecordBatch with column_name (db) names\n    let schema = Arc::new(column_name_entity::Entity::arrow_schema());\n\n    let batch = RecordBatch::try_new(\n        schema,\n        vec![\n            Arc::new(Int32Array::from(vec![1])),\n            Arc::new(StringArray::from(vec![\"Bob\"])),\n            Arc::new(BooleanArray::from(vec![false])),\n            Arc::new(Float64Array::from(vec![Some(88.0)])),\n        ],\n    )\n    .expect(\"Failed to create RecordBatch\");\n\n    let ams = column_name_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n    assert_eq!(ams.len(), 1);\n\n    // Values should be set on the Rust fields correctly\n    assert_eq!(ams[0].id, Set(1));\n    assert_eq!(ams[0].name, Set(\"Bob\".to_owned()));\n    assert_eq!(ams[0].active, Set(false));\n    assert_eq!(ams[0].score, Set(Some(88.0)));\n}\n\n#[test]\nfn test_column_name_roundtrip() {\n    let schema = column_name_entity::Entity::arrow_schema();\n\n    let original = vec![\n        column_name_entity::ActiveModel {\n            id: Set(1),\n            name: Set(\"Alice\".to_owned()),\n            active: Set(true),\n            score: Set(Some(95.5)),\n        },\n        column_name_entity::ActiveModel {\n            id: Set(2),\n            name: Set(\"Bob\".to_owned()),\n            active: Set(false),\n            score: Set(None),\n        },\n    ];\n\n    let batch =\n        column_name_entity::ActiveModel::to_arrow(&original, &schema).expect(\"to_arrow failed\");\n    let roundtripped =\n        column_name_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n\n    assert_eq!(roundtripped, original);\n}\n\n#[test]\nfn test_column_name_from_arrow_ignores_rust_field_names() {\n    // Build a RecordBatch using the Rust field names instead of column_name values.\n    // from_arrow should NOT find these columns (they don't match col.as_str()).\n    let schema = Arc::new(Schema::new(vec![\n        Field::new(\"id\", DataType::Int32, false),\n        Field::new(\"name\", DataType::Utf8, false), // Rust field name, not \"user_name\"\n        Field::new(\"active\", DataType::Boolean, false), // Rust field name, not \"is_active\"\n        Field::new(\"score\", DataType::Float64, true), // Rust field name, not \"score_value\"\n    ]));\n\n    let batch = RecordBatch::try_new(\n        schema,\n        vec![\n            Arc::new(Int32Array::from(vec![1])),\n            Arc::new(StringArray::from(vec![\"Alice\"])),\n            Arc::new(BooleanArray::from(vec![true])),\n            Arc::new(Float64Array::from(vec![Some(95.5)])),\n        ],\n    )\n    .expect(\"Failed to create RecordBatch\");\n\n    let ams = column_name_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n    assert_eq!(ams.len(), 1);\n\n    // id should be found (same name in both)\n    assert_eq!(ams[0].id, Set(1));\n\n    // The other fields should be NotSet because \"name\"/\"active\"/\"score\"\n    // don't match \"user_name\"/\"is_active\"/\"score_value\"\n    assert_eq!(ams[0].name, NotSet);\n    assert_eq!(ams[0].active, NotSet);\n    assert_eq!(ams[0].score, NotSet);\n}\n\n#[test]\nfn test_to_arrow_roundtrip_primitives() {\n    let schema = primitive_entity::Entity::arrow_schema();\n\n    let original = vec![\n        primitive_entity::ActiveModel {\n            id: Set(1),\n            tiny: Set(10),\n            small: Set(100),\n            big: Set(1000),\n            tiny_u: Set(5),\n            small_u: Set(50),\n            uint: Set(500),\n            big_u: Set(5000),\n            float_val: Set(1.5),\n            double_val: Set(10.5),\n            name: Set(\"Alice\".to_owned()),\n            flag: Set(true),\n            nullable_int: Set(Some(42)),\n            nullable_name: Set(Some(\"hello\".to_owned())),\n        },\n        primitive_entity::ActiveModel {\n            id: Set(2),\n            tiny: Set(20),\n            small: Set(200),\n            big: Set(2000),\n            tiny_u: Set(6),\n            small_u: Set(60),\n            uint: Set(600),\n            big_u: Set(6000),\n            float_val: Set(2.5),\n            double_val: Set(20.5),\n            name: Set(\"Bob\".to_owned()),\n            flag: Set(false),\n            nullable_int: Set(None),\n            nullable_name: Set(None),\n        },\n    ];\n\n    // to_arrow -> from_arrow roundtrip\n    let batch =\n        primitive_entity::ActiveModel::to_arrow(&original, &schema).expect(\"to_arrow failed\");\n    let roundtripped =\n        primitive_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n\n    assert_eq!(roundtripped.len(), 2);\n\n    // First row\n    assert_eq!(roundtripped, original);\n}\n\n/// Chrono datetime tests\n#[cfg(feature = \"with-chrono\")]\nmod chrono_tests {\n    use super::*;\n\n    mod chrono_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[sea_orm::model]\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"test_chrono\", arrow_schema)]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            pub created_date: ChronoDate,\n            pub created_time: ChronoTime,\n            pub created_at: ChronoDateTime,\n            pub updated_at: ChronoDateTimeUtc,\n            pub nullable_ts: Option<ChronoDateTimeUtc>,\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn test_to_arrow_chrono_roundtrip() {\n        use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};\n        use sea_orm::ArrowSchema;\n\n        let schema = chrono_entity::Entity::arrow_schema();\n\n        let date = NaiveDate::from_ymd_opt(2024, 6, 15).unwrap();\n        let time = NaiveTime::from_hms_opt(10, 30, 0).unwrap();\n        let naive_dt = NaiveDateTime::new(date, time);\n        let utc_dt: DateTime<Utc> = DateTime::from_timestamp_micros(1_718_447_400_000_000).unwrap();\n\n        let models = vec![\n            chrono_entity::ActiveModel {\n                id: Set(1),\n                created_date: Set(date),\n                created_time: Set(time),\n                created_at: Set(naive_dt),\n                updated_at: Set(utc_dt),\n                nullable_ts: Set(Some(utc_dt)),\n            },\n            chrono_entity::ActiveModel {\n                id: Set(2),\n                created_date: Set(date),\n                created_time: Set(time),\n                created_at: Set(naive_dt),\n                updated_at: Set(utc_dt),\n                nullable_ts: NotSet,\n            },\n        ];\n\n        let batch =\n            chrono_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n        assert_eq!(batch.num_rows(), 2);\n\n        // Verify Date32\n        let date_arr = batch\n            .column_by_name(\"created_date\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Date32Array>()\n            .unwrap();\n        assert_eq!(date_arr.value(0), 19889); // 2024-06-15\n\n        // Verify Time64\n        let time_arr = batch\n            .column_by_name(\"created_time\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Time64MicrosecondArray>()\n            .unwrap();\n        let expected_time_us: i64 = 10 * 3_600_000_000 + 30 * 60_000_000;\n        assert_eq!(time_arr.value(0), expected_time_us);\n\n        // Verify Timestamp (naive)\n        let ts_arr = batch\n            .column_by_name(\"created_at\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<TimestampMicrosecondArray>()\n            .unwrap();\n        assert_eq!(ts_arr.value(0), 1_718_447_400_000_000);\n\n        // Verify Timestamp with timezone\n        let ts_utc_arr = batch\n            .column_by_name(\"updated_at\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<TimestampMicrosecondArray>()\n            .unwrap();\n        assert_eq!(ts_utc_arr.value(0), 1_718_447_400_000_000);\n\n        // Verify nullable timestamp: row 0 present, row 1 null\n        let nullable_arr = batch\n            .column_by_name(\"nullable_ts\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<TimestampMicrosecondArray>()\n            .unwrap();\n        assert!(!nullable_arr.is_null(0));\n        assert!(nullable_arr.is_null(1));\n\n        // Full roundtrip\n        let roundtripped =\n            chrono_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(roundtripped.len(), 2);\n        assert_eq!(roundtripped[0].id, Set(1));\n        assert_eq!(roundtripped[0].created_date, Set(date));\n        assert_eq!(roundtripped[0].created_time, Set(time));\n        assert_eq!(roundtripped[0].created_at, Set(naive_dt));\n        assert_eq!(roundtripped[0].updated_at, Set(utc_dt));\n        assert_eq!(roundtripped[0].nullable_ts, Set(Some(utc_dt)));\n        assert_eq!(roundtripped[1].nullable_ts, Set(None));\n    }\n\n    #[test]\n    fn test_to_arrow_chrono_nanosecond_schema() {\n        use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};\n\n        let date = NaiveDate::from_ymd_opt(2024, 6, 15).unwrap();\n        let time = NaiveTime::from_hms_nano_opt(10, 30, 0, 123_456_789).unwrap();\n        let naive_dt = NaiveDateTime::new(date, time);\n        let utc_dt: DateTime<Utc> = DateTime::from_timestamp_nanos(1_718_447_400_123_456_789);\n\n        let models = vec![chrono_entity::ActiveModel {\n            id: Set(1),\n            created_date: Set(date),\n            created_time: Set(time),\n            created_at: Set(naive_dt),\n            updated_at: Set(utc_dt),\n            nullable_ts: Set(Some(utc_dt)),\n        }];\n\n        // Use a nanosecond schema\n        let schema = Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"created_date\", DataType::Date32, false),\n            Field::new(\n                \"created_time\",\n                DataType::Time64(TimeUnit::Nanosecond),\n                false,\n            ),\n            Field::new(\n                \"created_at\",\n                DataType::Timestamp(TimeUnit::Nanosecond, None),\n                false,\n            ),\n            Field::new(\n                \"updated_at\",\n                DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into())),\n                false,\n            ),\n            Field::new(\n                \"nullable_ts\",\n                DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into())),\n                true,\n            ),\n        ]);\n\n        let batch =\n            chrono_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n\n        let time_arr = batch\n            .column_by_name(\"created_time\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Time64NanosecondArray>()\n            .unwrap();\n        let expected_time_ns: i64 = 10 * 3_600_000_000_000 + 30 * 60_000_000_000 + 123_456_789;\n        assert_eq!(time_arr.value(0), expected_time_ns);\n\n        let ts_arr = batch\n            .column_by_name(\"created_at\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<TimestampNanosecondArray>()\n            .unwrap();\n        assert_eq!(ts_arr.value(0), 1_718_447_400_123_456_789);\n    }\n\n    #[test]\n    fn test_from_arrow_chrono_timestamp_micros() {\n        use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};\n\n        // 2024-06-15 10:30:00 UTC\n        let epoch_us: i64 = 1_718_447_400_000_000;\n        // Date: days since 1970-01-01 for 2024-06-15\n        let epoch_days: i32 = 19889;\n        // Time: 10:30:00 as microseconds since midnight\n        let time_us: i64 = 10 * 3_600_000_000 + 30 * 60_000_000;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"created_date\", DataType::Date32, false),\n            Field::new(\n                \"created_time\",\n                DataType::Time64(TimeUnit::Microsecond),\n                false,\n            ),\n            Field::new(\n                \"created_at\",\n                DataType::Timestamp(TimeUnit::Microsecond, None),\n                false,\n            ),\n            Field::new(\n                \"updated_at\",\n                DataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into())),\n                false,\n            ),\n            Field::new(\n                \"nullable_ts\",\n                DataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into())),\n                true,\n            ),\n        ]));\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1, 2])),\n                Arc::new(Date32Array::from(vec![epoch_days, epoch_days])),\n                Arc::new(Time64MicrosecondArray::from(vec![time_us, time_us])),\n                Arc::new(TimestampMicrosecondArray::from(vec![epoch_us, epoch_us])),\n                Arc::new(\n                    TimestampMicrosecondArray::from(vec![epoch_us, epoch_us]).with_timezone(\"UTC\"),\n                ),\n                Arc::new(\n                    TimestampMicrosecondArray::from(vec![Some(epoch_us), None])\n                        .with_timezone(\"UTC\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = chrono_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 2);\n\n        let am = &ams[0];\n        assert_eq!(am.id, Set(1));\n        assert_eq!(\n            am.created_date,\n            Set(NaiveDate::from_ymd_opt(2024, 6, 15).expect(\"valid\"))\n        );\n        assert_eq!(\n            am.created_time,\n            Set(NaiveTime::from_hms_opt(10, 30, 0).expect(\"valid\"))\n        );\n        let expected_naive = NaiveDateTime::new(\n            NaiveDate::from_ymd_opt(2024, 6, 15).expect(\"valid\"),\n            NaiveTime::from_hms_opt(10, 30, 0).expect(\"valid\"),\n        );\n        assert_eq!(am.created_at, Set(expected_naive));\n        let expected_utc: DateTime<Utc> = DateTime::from_timestamp_micros(epoch_us).expect(\"valid\");\n        assert_eq!(am.updated_at, Set(expected_utc));\n        assert_eq!(am.nullable_ts, Set(Some(expected_utc)));\n\n        // Second row: nullable_ts should be None\n        let am = &ams[1];\n        assert_eq!(am.nullable_ts, Set(None));\n    }\n\n    #[test]\n    fn test_from_arrow_chrono_timestamp_seconds() {\n        use chrono::{DateTime, Utc};\n\n        // 2024-06-15 10:30:00 UTC as seconds\n        let epoch_s: i64 = 1_718_447_400;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"created_date\", DataType::Date32, false),\n            Field::new(\"created_time\", DataType::Time32(TimeUnit::Second), false),\n            Field::new(\n                \"created_at\",\n                DataType::Timestamp(TimeUnit::Second, None),\n                false,\n            ),\n            Field::new(\n                \"updated_at\",\n                DataType::Timestamp(TimeUnit::Second, None),\n                false,\n            ),\n            Field::new(\n                \"nullable_ts\",\n                DataType::Timestamp(TimeUnit::Second, None),\n                true,\n            ),\n        ]));\n\n        let time_secs: i32 = 10 * 3600 + 30 * 60; // 10:30:00\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1])),\n                Arc::new(Date32Array::from(vec![19889])),\n                Arc::new(Time32SecondArray::from(vec![time_secs])),\n                Arc::new(TimestampSecondArray::from(vec![epoch_s])),\n                Arc::new(TimestampSecondArray::from(vec![epoch_s])),\n                Arc::new(TimestampSecondArray::from(vec![Some(epoch_s)])),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = chrono_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 1);\n\n        let expected_utc: DateTime<Utc> = DateTime::from_timestamp(epoch_s, 0).expect(\"valid\");\n        assert_eq!(ams[0].updated_at, Set(expected_utc));\n    }\n\n    #[test]\n    fn test_from_arrow_chrono_timestamp_nanos() {\n        use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};\n\n        // 2024-06-15 10:30:00.123456789 UTC as nanoseconds\n        let epoch_ns: i64 = 1_718_447_400_123_456_789;\n        // Date: days since 1970-01-01 for 2024-06-15\n        let epoch_days: i32 = 19889;\n        // Time: 10:30:00.123456789 as nanoseconds since midnight\n        let time_ns: i64 = 10 * 3_600_000_000_000 + 30 * 60_000_000_000 + 123_456_789;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"created_date\", DataType::Date32, false),\n            Field::new(\n                \"created_time\",\n                DataType::Time64(TimeUnit::Nanosecond),\n                false,\n            ),\n            Field::new(\n                \"created_at\",\n                DataType::Timestamp(TimeUnit::Nanosecond, None),\n                false,\n            ),\n            Field::new(\n                \"updated_at\",\n                DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into())),\n                false,\n            ),\n            Field::new(\n                \"nullable_ts\",\n                DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into())),\n                true,\n            ),\n        ]));\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1, 2])),\n                Arc::new(Date32Array::from(vec![epoch_days, epoch_days])),\n                Arc::new(Time64NanosecondArray::from(vec![time_ns, time_ns])),\n                Arc::new(TimestampNanosecondArray::from(vec![epoch_ns, epoch_ns])),\n                Arc::new(\n                    TimestampNanosecondArray::from(vec![epoch_ns, epoch_ns]).with_timezone(\"UTC\"),\n                ),\n                Arc::new(\n                    TimestampNanosecondArray::from(vec![Some(epoch_ns), None]).with_timezone(\"UTC\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = chrono_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 2);\n\n        let am = &ams[0];\n        assert_eq!(am.id, Set(1));\n        assert_eq!(\n            am.created_date,\n            Set(NaiveDate::from_ymd_opt(2024, 6, 15).expect(\"valid\"))\n        );\n        assert_eq!(\n            am.created_time,\n            Set(NaiveTime::from_hms_nano_opt(10, 30, 0, 123_456_789).expect(\"valid\"))\n        );\n        let expected_naive = NaiveDateTime::new(\n            NaiveDate::from_ymd_opt(2024, 6, 15).expect(\"valid\"),\n            NaiveTime::from_hms_nano_opt(10, 30, 0, 123_456_789).expect(\"valid\"),\n        );\n        assert_eq!(am.created_at, Set(expected_naive));\n        let expected_utc: DateTime<Utc> = DateTime::from_timestamp_nanos(epoch_ns);\n        assert_eq!(am.updated_at, Set(expected_utc));\n        assert_eq!(am.nullable_ts, Set(Some(expected_utc)));\n\n        // Second row: nullable_ts should be None\n        let am = &ams[1];\n        assert_eq!(am.nullable_ts, Set(None));\n    }\n}\n\n/// time crate datetime tests\n#[cfg(feature = \"with-time\")]\nmod time_tests {\n    use super::*;\n\n    mod time_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[sea_orm::model]\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"test_time\", arrow_schema)]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            pub created_date: TimeDate,\n            pub created_time: TimeTime,\n            pub created_at: TimeDateTime,\n            pub updated_at: TimeDateTimeWithTimeZone,\n            pub nullable_ts: Option<TimeDateTimeWithTimeZone>,\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn test_from_arrow_time_crate() {\n        // 2024-06-15 10:30:00 UTC\n        let epoch_us: i64 = 1_718_447_400_000_000;\n        let epoch_days: i32 = 19889;\n        let time_us: i64 = 10 * 3_600_000_000 + 30 * 60_000_000;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"created_date\", DataType::Date32, false),\n            Field::new(\n                \"created_time\",\n                DataType::Time64(TimeUnit::Microsecond),\n                false,\n            ),\n            Field::new(\n                \"created_at\",\n                DataType::Timestamp(TimeUnit::Microsecond, None),\n                false,\n            ),\n            Field::new(\n                \"updated_at\",\n                DataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into())),\n                false,\n            ),\n            Field::new(\n                \"nullable_ts\",\n                DataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into())),\n                true,\n            ),\n        ]));\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1])),\n                Arc::new(Date32Array::from(vec![epoch_days])),\n                Arc::new(Time64MicrosecondArray::from(vec![time_us])),\n                Arc::new(TimestampMicrosecondArray::from(vec![epoch_us])),\n                Arc::new(TimestampMicrosecondArray::from(vec![epoch_us]).with_timezone(\"UTC\")),\n                Arc::new(\n                    TimestampMicrosecondArray::from(vec![Some(epoch_us)]).with_timezone(\"UTC\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = time_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 1);\n\n        let am = &ams[0];\n\n        let expected_date =\n            time::Date::from_calendar_date(2024, time::Month::June, 15).expect(\"valid\");\n        assert_eq!(am.created_date, Set(expected_date));\n\n        let expected_time = time::Time::from_hms(10, 30, 0).expect(\"valid\");\n        assert_eq!(am.created_time, Set(expected_time));\n\n        let expected_pdt = time::PrimitiveDateTime::new(expected_date, expected_time);\n        assert_eq!(am.created_at, Set(expected_pdt));\n\n        let expected_odt =\n            time::OffsetDateTime::from_unix_timestamp_nanos(epoch_us as i128 * 1_000)\n                .expect(\"valid\");\n        assert_eq!(am.updated_at, Set(expected_odt));\n        assert_eq!(am.nullable_ts, Set(Some(expected_odt)));\n    }\n\n    #[test]\n    fn test_from_arrow_time_crate_nanos() {\n        // 2024-06-15 10:30:00.123456789 UTC\n        let epoch_ns: i64 = 1_718_447_400_123_456_789;\n        let epoch_days: i32 = 19889;\n        let time_ns: i64 = 10 * 3_600_000_000_000 + 30 * 60_000_000_000 + 123_456_789;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"created_date\", DataType::Date32, false),\n            Field::new(\n                \"created_time\",\n                DataType::Time64(TimeUnit::Nanosecond),\n                false,\n            ),\n            Field::new(\n                \"created_at\",\n                DataType::Timestamp(TimeUnit::Nanosecond, None),\n                false,\n            ),\n            Field::new(\n                \"updated_at\",\n                DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into())),\n                false,\n            ),\n            Field::new(\n                \"nullable_ts\",\n                DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into())),\n                true,\n            ),\n        ]));\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1, 2])),\n                Arc::new(Date32Array::from(vec![epoch_days, epoch_days])),\n                Arc::new(Time64NanosecondArray::from(vec![time_ns, time_ns])),\n                Arc::new(TimestampNanosecondArray::from(vec![epoch_ns, epoch_ns])),\n                Arc::new(\n                    TimestampNanosecondArray::from(vec![epoch_ns, epoch_ns]).with_timezone(\"UTC\"),\n                ),\n                Arc::new(\n                    TimestampNanosecondArray::from(vec![Some(epoch_ns), None]).with_timezone(\"UTC\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = time_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 2);\n\n        let am = &ams[0];\n\n        let expected_date =\n            time::Date::from_calendar_date(2024, time::Month::June, 15).expect(\"valid\");\n        assert_eq!(am.created_date, Set(expected_date));\n\n        let expected_time = time::Time::from_hms_nano(10, 30, 0, 123_456_789).expect(\"valid\");\n        assert_eq!(am.created_time, Set(expected_time));\n\n        let expected_pdt = time::PrimitiveDateTime::new(expected_date, expected_time);\n        assert_eq!(am.created_at, Set(expected_pdt));\n\n        let expected_odt =\n            time::OffsetDateTime::from_unix_timestamp_nanos(epoch_ns as i128).expect(\"valid\");\n        assert_eq!(am.updated_at, Set(expected_odt));\n        assert_eq!(am.nullable_ts, Set(Some(expected_odt)));\n\n        // Second row: nullable_ts should be None\n        let am = &ams[1];\n        assert_eq!(am.nullable_ts, Set(None));\n    }\n\n    #[test]\n    fn test_to_arrow_time_crate_roundtrip() {\n        use sea_orm::ArrowSchema;\n\n        let schema = time_entity::Entity::arrow_schema();\n\n        let date = time::Date::from_calendar_date(2024, time::Month::June, 15).expect(\"valid\");\n        let time_val = time::Time::from_hms(10, 30, 0).expect(\"valid\");\n        let pdt = time::PrimitiveDateTime::new(date, time_val);\n        let odt = time::OffsetDateTime::from_unix_timestamp_nanos(1_718_447_400_000_000_000)\n            .expect(\"valid\");\n\n        let models = vec![\n            time_entity::ActiveModel {\n                id: Set(1),\n                created_date: Set(date),\n                created_time: Set(time_val),\n                created_at: Set(pdt),\n                updated_at: Set(odt),\n                nullable_ts: Set(Some(odt)),\n            },\n            time_entity::ActiveModel {\n                id: Set(2),\n                created_date: Set(date),\n                created_time: Set(time_val),\n                created_at: Set(pdt),\n                updated_at: Set(odt),\n                nullable_ts: NotSet,\n            },\n        ];\n\n        let batch = time_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n        assert_eq!(batch.num_rows(), 2);\n\n        // Verify Date32\n        let date_arr = batch\n            .column_by_name(\"created_date\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Date32Array>()\n            .unwrap();\n        assert_eq!(date_arr.value(0), 19889); // 2024-06-15\n\n        // Verify Time64\n        let time_arr = batch\n            .column_by_name(\"created_time\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Time64MicrosecondArray>()\n            .unwrap();\n        let expected_time_us: i64 = 10 * 3_600_000_000 + 30 * 60_000_000;\n        assert_eq!(time_arr.value(0), expected_time_us);\n\n        // Verify nullable: row 0 present, row 1 null\n        let nullable_arr = batch\n            .column_by_name(\"nullable_ts\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<TimestampMicrosecondArray>()\n            .unwrap();\n        assert!(!nullable_arr.is_null(0));\n        assert!(nullable_arr.is_null(1));\n\n        // Full roundtrip\n        let roundtripped = time_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(roundtripped.len(), 2);\n        assert_eq!(roundtripped[0].id, Set(1));\n        assert_eq!(roundtripped[0].created_date, Set(date));\n        assert_eq!(roundtripped[0].created_time, Set(time_val));\n        assert_eq!(roundtripped[0].created_at, Set(pdt));\n        assert_eq!(roundtripped[0].updated_at, Set(odt));\n        assert_eq!(roundtripped[0].nullable_ts, Set(Some(odt)));\n        assert_eq!(roundtripped[1].nullable_ts, Set(None));\n    }\n}\n\n/// rust_decimal type tests\n#[cfg(feature = \"with-rust_decimal\")]\nmod rust_decimal_tests {\n    use super::*;\n\n    mod decimal_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[sea_orm::model]\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"test_rust_decimal\", arrow_schema)]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(column_type = \"Decimal(Some((10, 2)))\")]\n            pub price: Decimal,\n            #[sea_orm(column_type = \"Decimal(Some((20, 4)))\")]\n            pub amount: Decimal,\n            #[sea_orm(column_type = \"Decimal(Some((10, 2)))\")]\n            pub nullable_decimal: Option<Decimal>,\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn test_from_arrow_decimal128_rust_decimal() {\n        use rust_decimal::Decimal;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"price\", DataType::Decimal128(10, 2), false),\n            Field::new(\"amount\", DataType::Decimal128(20, 4), false),\n            Field::new(\"nullable_decimal\", DataType::Decimal128(10, 2), true),\n        ]));\n\n        // Create test data: price=12345.67, amount=9876543.2109\n        let price_scaled = 1234567i128; // 12345.67 with scale 2\n        let amount_scaled = 98765432109i128; // 9876543.2109 with scale 4\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1, 2])),\n                Arc::new(\n                    Decimal128Array::from(vec![price_scaled, price_scaled])\n                        .with_precision_and_scale(10, 2)\n                        .expect(\"valid precision/scale\"),\n                ),\n                Arc::new(\n                    Decimal128Array::from(vec![amount_scaled, amount_scaled])\n                        .with_precision_and_scale(20, 4)\n                        .expect(\"valid precision/scale\"),\n                ),\n                Arc::new(\n                    Decimal128Array::from(vec![Some(price_scaled), None])\n                        .with_precision_and_scale(10, 2)\n                        .expect(\"valid precision/scale\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = decimal_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 2);\n\n        let am = &ams[0];\n        assert_eq!(am.id, Set(1));\n        assert_eq!(\n            am.price,\n            Set(Decimal::from_i128_with_scale(price_scaled, 2))\n        );\n        assert_eq!(\n            am.amount,\n            Set(Decimal::from_i128_with_scale(amount_scaled, 4))\n        );\n        assert_eq!(\n            am.nullable_decimal,\n            Set(Some(Decimal::from_i128_with_scale(price_scaled, 2)))\n        );\n\n        // Second row: nullable_decimal should be None\n        let am = &ams[1];\n        assert_eq!(am.nullable_decimal, Set(None));\n    }\n\n    #[test]\n    fn test_from_arrow_decimal128_edge_cases() {\n        use rust_decimal::Decimal;\n\n        // Test zero, negative, and large values\n        let zero = Decimal::from_i128_with_scale(0, 2);\n        let negative = Decimal::from_i128_with_scale(-123456, 2);\n        let large = Decimal::from_i128_with_scale(123456789012345678i128, 10);\n\n        assert_eq!(zero.to_string(), \"0.00\");\n        assert_eq!(negative.to_string(), \"-1234.56\");\n        assert!(large.to_string().contains(\"12345678.9012345678\"));\n    }\n\n    #[test]\n    fn test_to_arrow_rust_decimal_roundtrip() {\n        use rust_decimal::Decimal;\n        use sea_orm::ArrowSchema;\n\n        let schema = decimal_entity::Entity::arrow_schema();\n\n        let price = Decimal::new(1234567, 2); // 12345.67\n        let amount = Decimal::new(98765432109, 4); // 9876543.2109\n\n        let models = vec![\n            decimal_entity::ActiveModel {\n                id: Set(1),\n                price: Set(price),\n                amount: Set(amount),\n                nullable_decimal: Set(Some(price)),\n            },\n            decimal_entity::ActiveModel {\n                id: Set(2),\n                price: Set(price),\n                amount: Set(amount),\n                nullable_decimal: Set(None),\n            },\n        ];\n\n        let batch =\n            decimal_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n        assert_eq!(batch.num_rows(), 2);\n\n        // price has precision 10 (≤18), so it becomes Decimal64\n        let price_arr = batch\n            .column_by_name(\"price\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal64Array>()\n            .unwrap();\n        assert_eq!(price_arr.value(0), 1234567);\n        assert_eq!(price_arr.precision(), 10);\n        assert_eq!(price_arr.scale(), 2);\n\n        // nullable_decimal also has precision 10 → Decimal64\n        let nullable_arr = batch\n            .column_by_name(\"nullable_decimal\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal64Array>()\n            .unwrap();\n        assert!(!nullable_arr.is_null(0));\n        assert!(nullable_arr.is_null(1));\n\n        // Full roundtrip\n        let roundtripped =\n            decimal_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(roundtripped, models);\n    }\n\n    #[test]\n    fn test_to_arrow_rust_decimal_decimal128_roundtrip() {\n        use rust_decimal::Decimal;\n\n        let schema = Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, true),\n            Field::new(\"price\", DataType::Decimal128(10, 2), true),\n            Field::new(\"amount\", DataType::Decimal128(20, 4), true),\n            Field::new(\"nullable_decimal\", DataType::Decimal128(10, 2), true),\n        ]);\n\n        let price = Decimal::new(1234567, 2);\n        let amount = Decimal::new(98765432109, 4);\n\n        let models = vec![\n            decimal_entity::ActiveModel {\n                id: Set(1),\n                price: Set(price),\n                amount: Set(amount),\n                nullable_decimal: Set(Some(price)),\n            },\n            decimal_entity::ActiveModel {\n                id: Set(2),\n                price: Set(price),\n                amount: Set(amount),\n                nullable_decimal: Set(None),\n            },\n        ];\n\n        let batch =\n            decimal_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n        assert_eq!(batch.num_rows(), 2);\n\n        let price_arr = batch\n            .column_by_name(\"price\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal128Array>()\n            .unwrap();\n        assert_eq!(price_arr.value(0), 1234567);\n        assert_eq!(price_arr.precision(), 10);\n        assert_eq!(price_arr.scale(), 2);\n\n        let amount_arr = batch\n            .column_by_name(\"amount\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal128Array>()\n            .unwrap();\n        assert_eq!(amount_arr.value(0), 98765432109);\n        assert_eq!(amount_arr.precision(), 20);\n        assert_eq!(amount_arr.scale(), 4);\n\n        let nullable_arr = batch\n            .column_by_name(\"nullable_decimal\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal128Array>()\n            .unwrap();\n        assert!(!nullable_arr.is_null(0));\n        assert_eq!(nullable_arr.value(0), 1234567);\n        assert!(nullable_arr.is_null(1));\n\n        // Roundtrip through Decimal128\n        let roundtripped =\n            decimal_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(roundtripped, models);\n    }\n}\n\n/// bigdecimal type tests\n#[cfg(feature = \"with-bigdecimal\")]\nmod bigdecimal_tests {\n    use super::*;\n\n    mod decimal_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[sea_orm::model]\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"test_bigdecimal\", arrow_schema)]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(column_type = \"Decimal(Some((10, 2)))\")]\n            pub price: BigDecimal,\n            #[sea_orm(column_type = \"Decimal(Some((20, 4)))\")]\n            pub amount: BigDecimal,\n            #[sea_orm(column_type = \"Decimal(Some((10, 2)))\")]\n            pub nullable_decimal: Option<BigDecimal>,\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    #[cfg(not(feature = \"with-rust_decimal\"))]\n    fn test_from_arrow_decimal128_bigdecimal() {\n        use bigdecimal::{BigDecimal, num_bigint::BigInt};\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"price\", DataType::Decimal128(10, 2), false),\n            Field::new(\"amount\", DataType::Decimal128(20, 4), false),\n            Field::new(\"nullable_decimal\", DataType::Decimal128(10, 2), true),\n        ]));\n\n        // Create test data: price=12345.67, amount=9876543.2109\n        let price_scaled = 1234567i128; // 12345.67 with scale 2\n        let amount_scaled = 98765432109i128; // 9876543.2109 with scale 4\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1, 2])),\n                Arc::new(\n                    Decimal128Array::from(vec![price_scaled, price_scaled])\n                        .with_precision_and_scale(10, 2)\n                        .expect(\"valid precision/scale\"),\n                ),\n                Arc::new(\n                    Decimal128Array::from(vec![amount_scaled, amount_scaled])\n                        .with_precision_and_scale(20, 4)\n                        .expect(\"valid precision/scale\"),\n                ),\n                Arc::new(\n                    Decimal128Array::from(vec![Some(price_scaled), None])\n                        .with_precision_and_scale(10, 2)\n                        .expect(\"valid precision/scale\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = decimal_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 2);\n\n        let am = &ams[0];\n        assert_eq!(am.id, Set(1));\n        assert_eq!(\n            am.price,\n            Set(BigDecimal::new(BigInt::from(price_scaled), 2))\n        );\n        assert_eq!(\n            am.amount,\n            Set(BigDecimal::new(BigInt::from(amount_scaled), 4))\n        );\n        assert_eq!(\n            am.nullable_decimal,\n            Set(Some(BigDecimal::new(BigInt::from(price_scaled), 2)))\n        );\n\n        // Second row: nullable_decimal should be None\n        let am = &ams[1];\n        assert_eq!(am.nullable_decimal, Set(None));\n    }\n\n    #[test]\n    fn test_from_arrow_decimal256_bigdecimal() {\n        use sea_orm_arrow::arrow::datatypes::i256;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"large_value\", DataType::Decimal256(76, 20), false),\n            Field::new(\"nullable_large\", DataType::Decimal256(76, 20), true),\n        ]));\n\n        // Create a large i256 value\n        let large_val = i256::from_i128(123456789012345678i128);\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1, 2])),\n                Arc::new(\n                    Decimal256Array::from(vec![large_val, large_val])\n                        .with_precision_and_scale(76, 20)\n                        .expect(\"valid precision/scale\"),\n                ),\n                Arc::new(\n                    Decimal256Array::from(vec![Some(large_val), None])\n                        .with_precision_and_scale(76, 20)\n                        .expect(\"valid precision/scale\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        // Test the batch was created correctly\n        assert_eq!(batch.num_rows(), 2);\n        assert_eq!(batch.num_columns(), 3);\n\n        // Test that we can read the decimal values\n        let arr = batch\n            .column(1)\n            .as_any()\n            .downcast_ref::<Decimal256Array>()\n            .expect(\"Expected Decimal256Array\");\n        assert_eq!(arr.value(0), large_val);\n        assert_eq!(arr.precision(), 76);\n        assert_eq!(arr.scale(), 20);\n    }\n\n    #[test]\n    #[cfg(not(feature = \"with-rust_decimal\"))]\n    fn test_to_arrow_bigdecimal_roundtrip() {\n        use bigdecimal::{BigDecimal, num_bigint::BigInt};\n        use sea_orm::ArrowSchema;\n\n        let schema = decimal_entity::Entity::arrow_schema();\n\n        let price = BigDecimal::new(BigInt::from(1234567i64), 2); // 12345.67\n        let amount = BigDecimal::new(BigInt::from(98765432109i64), 4); // 9876543.2109\n\n        let models = vec![\n            decimal_entity::ActiveModel {\n                id: Set(1),\n                price: Set(price.clone()),\n                amount: Set(amount.clone()),\n                nullable_decimal: Set(Some(price.clone())),\n            },\n            decimal_entity::ActiveModel {\n                id: Set(2),\n                price: Set(price.clone()),\n                amount: Set(amount.clone()),\n                nullable_decimal: Set(None),\n            },\n        ];\n\n        let batch =\n            decimal_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n        assert_eq!(batch.num_rows(), 2);\n\n        // price has precision 10 (≤18), so it becomes Decimal64\n        let price_arr = batch\n            .column_by_name(\"price\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal64Array>()\n            .unwrap();\n        assert_eq!(price_arr.value(0), 1234567);\n        assert_eq!(price_arr.precision(), 10);\n        assert_eq!(price_arr.scale(), 2);\n\n        // nullable_decimal also has precision 10 → Decimal64\n        let nullable_arr = batch\n            .column_by_name(\"nullable_decimal\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal64Array>()\n            .unwrap();\n        assert!(!nullable_arr.is_null(0));\n        assert!(nullable_arr.is_null(1));\n\n        // Full roundtrip\n        let roundtripped =\n            decimal_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(roundtripped, models);\n    }\n\n    #[test]\n    #[cfg(not(feature = \"with-rust_decimal\"))]\n    fn test_to_arrow_bigdecimal_decimal128_roundtrip() {\n        use bigdecimal::{BigDecimal, num_bigint::BigInt};\n\n        let schema = Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, true),\n            Field::new(\"price\", DataType::Decimal128(10, 2), true),\n            Field::new(\"amount\", DataType::Decimal128(20, 4), true),\n            Field::new(\"nullable_decimal\", DataType::Decimal128(10, 2), true),\n        ]);\n\n        let price = BigDecimal::new(BigInt::from(1234567i64), 2);\n        let amount = BigDecimal::new(BigInt::from(98765432109i64), 4);\n\n        let models = vec![\n            decimal_entity::ActiveModel {\n                id: Set(1),\n                price: Set(price.clone()),\n                amount: Set(amount.clone()),\n                nullable_decimal: Set(Some(price.clone())),\n            },\n            decimal_entity::ActiveModel {\n                id: Set(2),\n                price: Set(price.clone()),\n                amount: Set(amount.clone()),\n                nullable_decimal: Set(None),\n            },\n        ];\n\n        let batch =\n            decimal_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n        assert_eq!(batch.num_rows(), 2);\n\n        let price_arr = batch\n            .column_by_name(\"price\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal128Array>()\n            .unwrap();\n        assert_eq!(price_arr.value(0), 1234567);\n        assert_eq!(price_arr.precision(), 10);\n        assert_eq!(price_arr.scale(), 2);\n\n        let amount_arr = batch\n            .column_by_name(\"amount\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal128Array>()\n            .unwrap();\n        assert_eq!(amount_arr.value(0), 98765432109);\n        assert_eq!(amount_arr.precision(), 20);\n        assert_eq!(amount_arr.scale(), 4);\n\n        let nullable_arr = batch\n            .column_by_name(\"nullable_decimal\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal128Array>()\n            .unwrap();\n        assert!(!nullable_arr.is_null(0));\n        assert_eq!(nullable_arr.value(0), 1234567);\n        assert!(nullable_arr.is_null(1));\n\n        // Roundtrip through Decimal128\n        let roundtripped =\n            decimal_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(roundtripped, models);\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/basic.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use sea_orm::{Database, DbConn, entity::*, error::*, query::*, sea_query, tests_cfg::*};\n\n// DATABASE_URL=sqlite::memory: cargo test --features rusqlite --test basic\n// DATABASE_URL=sqlite::memory: cargo test --features sqlx-sqlite,runtime-tokio --test basic\n#[sea_orm_macros::test]\n#[cfg(feature = \"rusqlite\")]\nfn main() -> Result<(), DbErr> {\n    dotenv::from_filename(\".env.local\").ok();\n    dotenv::from_filename(\".env\").ok();\n\n    let base_url = std::env::var(\"DATABASE_URL\").unwrap_or_else(|_| \"sqlite::memory:\".to_owned());\n\n    let db: DbConn = Database::connect(&base_url)?;\n    setup_schema(&db)?;\n    crud_cake(&db)?;\n\n    Ok(())\n}\n\n#[cfg(feature = \"rusqlite\")]\nfn setup_schema(db: &DbConn) -> Result<(), DbErr> {\n    use sea_query::*;\n\n    let stmt = sea_query::Table::create()\n        .table(cake::Entity)\n        .col(\n            ColumnDef::new(cake::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(cake::Column::Name).string())\n        .to_owned();\n\n    let result = db.execute(&stmt)?;\n    println!(\"Create table cake: {result:?}\");\n\n    Ok(())\n}\n\n#[cfg(feature = \"rusqlite\")]\nfn crud_cake(db: &DbConn) -> Result<(), DbErr> {\n    let apple = cake::ActiveModel {\n        name: Set(\"Apple Pie\".to_owned()),\n        ..Default::default()\n    };\n\n    let mut apple = apple.save(db)?;\n\n    println!();\n    println!(\"Inserted: {apple:?}\");\n\n    assert_eq!(\n        apple,\n        cake::ActiveModel {\n            id: Unchanged(1),\n            name: Unchanged(\"Apple Pie\".to_owned()),\n        }\n    );\n\n    apple.name = Set(\"Lemon Tart\".to_owned());\n\n    let apple = apple.save(db)?;\n\n    println!();\n    println!(\"Updated: {apple:?}\");\n\n    let count = cake::Entity::find().count(db)?;\n\n    println!();\n    println!(\"Count: {count:?}\");\n    assert_eq!(count, 1);\n\n    let apple = cake::Entity::find_by_id(1).one(db)?;\n\n    assert_eq!(\n        Some(cake::Model {\n            id: 1,\n            name: \"Lemon Tart\".to_owned(),\n        }),\n        apple\n    );\n\n    let apple: cake::Model = apple.unwrap();\n\n    let result = apple.delete(db)?;\n\n    println!();\n    println!(\"Deleted: {result:?}\");\n\n    let apple = cake::Entity::find_by_id(1).one(db)?;\n\n    assert_eq!(None, apple);\n\n    let count = cake::Entity::find().count(db)?;\n\n    println!();\n    println!(\"Count: {count:?}\");\n    assert_eq!(count, 0);\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/bits_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse common::features::*;\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-postgres\")]\nfn main() -> Result<(), DbErr> {\n    let ctx = common::TestContext::new(\"bits_tests\");\n    create_bits_table(&ctx.db)?;\n    create_and_update(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn create_and_update(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let bits = bits::Model {\n        id: 1,\n        bit0: 0,\n        bit1: 1,\n        bit8: 8,\n        bit16: 16,\n        bit32: 32,\n        bit64: 64,\n    };\n\n    let res = bits.clone().into_active_model().insert(db)?;\n\n    let model = Bits::find().one(db)?;\n    assert_eq!(model, Some(res));\n    assert_eq!(model, Some(bits.clone()));\n\n    let res = bits::ActiveModel {\n        bit32: Set(320),\n        bit64: Set(640),\n        ..bits.clone().into_active_model()\n    }\n    .update(db)?;\n\n    let model = Bits::find().one(db)?;\n    assert_eq!(model, Some(res));\n    assert_eq!(\n        model,\n        Some(bits::Model {\n            id: 1,\n            bit0: 0,\n            bit1: 1,\n            bit8: 8,\n            bit16: 16,\n            bit32: 320,\n            bit64: 640,\n        })\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/byte_primary_key_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"byte_primary_key_tests\");\n    create_byte_primary_key_table(&ctx.db)?;\n    create_and_update(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn create_and_update(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use common::features::byte_primary_key::*;\n\n    let model = Model {\n        id: vec![1, 2, 3],\n        value: \"First Row\".to_owned(),\n    };\n\n    let res = Entity::insert(model.clone().into_active_model()).exec(db)?;\n\n    assert_eq!(Entity::find().one(db)?, Some(model.clone()));\n\n    assert_eq!(res.last_insert_id, model.id);\n\n    let updated_active_model = ActiveModel {\n        value: Set(\"First Row (Updated)\".to_owned()),\n        ..model.clone().into_active_model()\n    };\n\n    let update_res = Entity::update(updated_active_model.clone())\n        .validate()?\n        .filter(Column::Id.eq(vec![1_u8, 2_u8, 4_u8])) // annotate it as Vec<u8> explicitly\n        .exec(db);\n\n    assert_eq!(update_res, Err(DbErr::RecordNotUpdated));\n\n    let update_res = Entity::update(updated_active_model)\n        .validate()?\n        .filter(Column::Id.eq(vec![1_u8, 2_u8, 3_u8])) // annotate it as Vec<u8> explicitly\n        .exec(db)?;\n\n    assert_eq!(\n        update_res,\n        Model {\n            id: vec![1, 2, 3],\n            value: \"First Row (Updated)\".to_owned(),\n        }\n    );\n\n    assert_eq!(\n        Entity::find()\n            .filter(Column::Id.eq(vec![1_u8, 2_u8, 3_u8])) // annotate it as Vec<u8> explicitly\n            .one(db)?,\n        Some(Model {\n            id: vec![1, 2, 3],\n            value: \"First Row (Updated)\".to_owned(),\n        })\n    );\n\n    assert_eq!(\n        Entity::find()\n            .filter(Column::Id.eq(vec![1_u8, 2_u8, 3_u8])) // annotate it as Vec<u8> explicitly\n            .into_values::<_, Column>()\n            .one(db)?,\n        Some((vec![1_u8, 2_u8, 3_u8], \"First Row (Updated)\".to_owned(),))\n    );\n\n    assert_eq!(\n        Entity::find()\n            .filter(Column::Id.eq(vec![1_u8, 2_u8, 3_u8])) // annotate it as Vec<u8> explicitly\n            .into_tuple()\n            .one(db)?,\n        Some((vec![1_u8, 2_u8, 3_u8], \"First Row (Updated)\".to_owned(),))\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/collection_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, DerivePartialModel, QueryOrder, entity::prelude::*, entity::*};\nuse serde_json::json;\n\n#[sea_orm_macros::test]\n#[cfg(all(feature = \"sqlx-postgres\", feature = \"postgres-array\"))]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"collection_tests\");\n    create_tea_enum(&ctx.db)?;\n    create_collection_table(&ctx.db)?;\n    insert_collection(&ctx.db)?;\n    update_collection(&ctx.db)?;\n    select_collection(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use collection::*;\n\n    let uuid = Uuid::new_v4();\n\n    assert_eq!(\n        Model {\n            id: 1,\n            name: \"Collection 1\".into(),\n            integers: vec![1, 2, 3],\n            integers_opt: Some(vec![1, 2, 3]),\n            teas: vec![Tea::BreakfastTea],\n            teas_opt: Some(vec![Tea::BreakfastTea]),\n            colors: vec![Color::Black],\n            colors_opt: Some(vec![Color::Black]),\n            uuid: vec![uuid],\n            uuid_hyphenated: vec![uuid.hyphenated()],\n        }\n        .into_active_model()\n        .insert(db)?,\n        Model {\n            id: 1,\n            name: \"Collection 1\".into(),\n            integers: vec![1, 2, 3],\n            integers_opt: Some(vec![1, 2, 3]),\n            teas: vec![Tea::BreakfastTea],\n            teas_opt: Some(vec![Tea::BreakfastTea]),\n            colors: vec![Color::Black],\n            colors_opt: Some(vec![Color::Black]),\n            uuid: vec![uuid],\n            uuid_hyphenated: vec![uuid.hyphenated()],\n        }\n    );\n\n    assert_eq!(\n        Model {\n            id: 2,\n            name: \"Collection 2\".into(),\n            integers: vec![10, 9],\n            integers_opt: None,\n            teas: vec![Tea::BreakfastTea, Tea::AfternoonTea],\n            teas_opt: None,\n            colors: vec![Color::Black],\n            colors_opt: None,\n            uuid: vec![uuid],\n            uuid_hyphenated: vec![uuid.hyphenated()],\n        }\n        .into_active_model()\n        .insert(db)?,\n        Model {\n            id: 2,\n            name: \"Collection 2\".into(),\n            integers: vec![10, 9],\n            integers_opt: None,\n            teas: vec![Tea::BreakfastTea, Tea::AfternoonTea],\n            teas_opt: None,\n            colors: vec![Color::Black],\n            colors_opt: None,\n            uuid: vec![uuid],\n            uuid_hyphenated: vec![uuid.hyphenated()],\n        }\n    );\n\n    assert_eq!(\n        Model {\n            id: 3,\n            name: \"Collection 3\".into(),\n            integers: vec![],\n            integers_opt: Some(vec![]),\n            teas: vec![],\n            teas_opt: Some(vec![]),\n            colors: vec![],\n            colors_opt: Some(vec![]),\n            uuid: vec![uuid],\n            uuid_hyphenated: vec![uuid.hyphenated()],\n        }\n        .into_active_model()\n        .insert(db)?,\n        Model {\n            id: 3,\n            name: \"Collection 3\".into(),\n            integers: vec![],\n            integers_opt: Some(vec![]),\n            teas: vec![],\n            teas_opt: Some(vec![]),\n            colors: vec![],\n            colors_opt: Some(vec![]),\n            uuid: vec![uuid],\n            uuid_hyphenated: vec![uuid.hyphenated()],\n        }\n    );\n\n    assert_eq!(\n        Entity::find_by_id(1).into_json().one(db)?,\n        Some(json!({\n            \"id\": 1,\n            \"name\": \"Collection 1\",\n            \"integers\": [1, 2, 3],\n            \"integers_opt\": [1, 2, 3],\n            \"teas\": [\"BreakfastTea\"],\n            \"teas_opt\": [\"BreakfastTea\"],\n            \"colors\": [0],\n            \"colors_opt\": [0],\n            \"uuid\": [uuid],\n            \"uuid_hyphenated\": [uuid.hyphenated()],\n        }))\n    );\n\n    assert_eq!(\n        Entity::find_by_id(2).into_json().one(db)?,\n        Some(json!({\n            \"id\": 2,\n            \"name\": \"Collection 2\",\n            \"integers\": [10, 9],\n            \"integers_opt\": null,\n            \"teas\": [\"BreakfastTea\", \"AfternoonTea\"],\n            \"teas_opt\": null,\n            \"colors\": [0],\n            \"colors_opt\": null,\n            \"uuid\": [uuid],\n            \"uuid_hyphenated\": [uuid.hyphenated()],\n        }))\n    );\n\n    assert_eq!(\n        Entity::find_by_id(3).into_json().one(db)?,\n        Some(json!({\n            \"id\": 3,\n            \"name\": \"Collection 3\",\n            \"integers\": [],\n            \"integers_opt\": [],\n            \"teas\": [],\n            \"teas_opt\": [],\n            \"colors\": [],\n            \"colors_opt\": [],\n            \"uuid\": [uuid],\n            \"uuid_hyphenated\": [uuid.hyphenated()],\n        }))\n    );\n\n    let found = Entity::find()\n        .filter(Entity::COLUMN.teas.contains(vec![Tea::BreakfastTea]))\n        .order_by_asc(Entity::COLUMN.id)\n        .all(db)?;\n\n    assert_eq!(found.len(), 2);\n    assert_eq!(found[0].id, 1);\n    assert_eq!(found[1].id, 2);\n\n    let found = Entity::find()\n        .filter(Entity::COLUMN.teas.contains(vec![Tea::AfternoonTea]))\n        .order_by_asc(Entity::COLUMN.id)\n        .all(db)?;\n\n    assert_eq!(found.len(), 1);\n    assert_eq!(found[0].id, 2);\n\n    let found = Entity::find()\n        .filter(\n            Entity::COLUMN\n                .teas\n                .overlap(vec![Tea::BreakfastTea, Tea::AfternoonTea]),\n        )\n        .order_by_asc(Entity::COLUMN.id)\n        .all(db)?;\n\n    assert_eq!(found.len(), 2);\n    assert_eq!(found[0].id, 1);\n    assert_eq!(found[1].id, 2);\n\n    let found = Entity::find()\n        .filter(Entity::COLUMN.integers.contains(vec![10]))\n        .order_by_asc(Entity::COLUMN.id)\n        .all(db)?;\n\n    assert_eq!(found.len(), 1);\n    assert_eq!(found[0].id, 2);\n\n    Ok(())\n}\n\npub fn update_collection(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use collection::*;\n\n    let uuid = Uuid::new_v4();\n    let model = Entity::find_by_id(1).one(db)?.unwrap();\n\n    ActiveModel {\n        integers: Set(vec![4, 5, 6]),\n        integers_opt: Set(Some(vec![4, 5, 6])),\n        teas: Set(vec![Tea::EverydayTea]),\n        teas_opt: Set(Some(vec![Tea::EverydayTea])),\n        colors: Set(vec![Color::White]),\n        colors_opt: Set(Some(vec![Color::White])),\n        ..model.into_active_model()\n    }\n    .update(db)?;\n\n    ActiveModel {\n        id: Unchanged(3),\n        name: Set(\"Collection 3\".into()),\n        integers: Set(vec![3, 1, 4]),\n        integers_opt: Set(None),\n        teas: Set(vec![Tea::EverydayTea]),\n        teas_opt: Set(None),\n        colors: Set(vec![Color::White]),\n        colors_opt: Set(None),\n        uuid: Set(vec![uuid]),\n        uuid_hyphenated: Set(vec![uuid.hyphenated()]),\n    }\n    .update(db)?;\n\n    Ok(())\n}\n\npub fn select_collection(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use collection::*;\n\n    #[derive(DerivePartialModel, Debug, PartialEq)]\n    #[sea_orm(entity = \"Entity\")]\n    struct PartialSelectResult {\n        name: String,\n    }\n\n    let result = Entity::find_by_id(1)\n        .into_partial_model::<PartialSelectResult>()\n        .one(db)?;\n\n    assert_eq!(\n        result,\n        Some(PartialSelectResult {\n            name: \"Collection 1\".into(),\n        })\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_chain/Readme.md",
    "content": "# Schema for SeaORM test suite\n\n![Entity Relation Diagram](bakery_chain_erd.png)\n\nERD generated by DataGrip."
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_chain/baker.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"baker\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub contact_details: Json,\n    pub bakery_id: Option<i32>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::bakery::Entity\",\n        from = \"Column::BakeryId\",\n        to = \"super::bakery::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"SetNull\"\n    )]\n    Bakery,\n}\n\nimpl Related<super::bakery::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bakery.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cakes_bakers::Relation::Cake.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cakes_bakers::Relation::Baker.def().rev())\n    }\n}\n\npub struct BakedForCustomer;\n\nimpl Linked for BakedForCustomer {\n    type FromEntity = Entity;\n\n    type ToEntity = super::customer::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![\n            super::cakes_bakers::Relation::Baker.def().rev(),\n            super::cakes_bakers::Relation::Cake.def(),\n            super::lineitem::Relation::Cake.def().rev(),\n            super::lineitem::Relation::Order.def(),\n            super::order::Relation::Customer.def(),\n        ]\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_chain/bakery.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bakery\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub profit_margin: f64,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::baker::Entity\")]\n    Baker,\n    #[sea_orm(has_many = \"super::order::Entity\")]\n    Order,\n    #[sea_orm(has_many = \"super::cake::Entity\")]\n    Cake,\n}\n\nimpl Related<super::baker::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Baker.def()\n    }\n}\n\nimpl Related<super::order::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Order.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\npub struct ToBaker;\n\nimpl Linked for ToBaker {\n    type FromEntity = Entity;\n    type ToEntity = super::baker::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::Baker.def()]\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_chain/cake.rs",
    "content": "use sea_orm::{ConnectionTrait, entity::prelude::*};\n\n#[sea_orm::compact_model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub price: Decimal,\n    pub bakery_id: Option<i32>,\n    pub gluten_free: bool,\n    pub serial: Uuid,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::bakery::Entity\",\n        from = \"Column::BakeryId\",\n        to = \"super::bakery::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"SetNull\"\n    )]\n    Bakery,\n    #[sea_orm(has_many = \"super::lineitem::Entity\")]\n    Lineitem,\n}\n\nimpl Related<super::bakery::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bakery.def()\n    }\n}\n\nimpl Related<super::baker::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cakes_bakers::Relation::Baker.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cakes_bakers::Relation::Cake.def().rev())\n    }\n}\n\nimpl Related<super::lineitem::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Lineitem.def()\n    }\n}\n\npub struct ToBakery;\nimpl Linked for ToBakery {\n    type FromEntity = super::cake::Entity;\n    type ToEntity = super::bakery::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::Bakery.def()]\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {\n    fn new() -> Self {\n        use sea_orm::Set;\n        Self {\n            serial: Set(Uuid::new_v4()),\n            ..ActiveModelTrait::default()\n        }\n    }\n\n    fn before_save<C>(self, _db: &C, insert: bool) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.price.as_ref() == &Decimal::ZERO {\n            Err(DbErr::Custom(format!(\n                \"[before_save] Invalid Price, insert: {insert}\"\n            )))\n        } else {\n            Ok(self)\n        }\n    }\n\n    fn after_save<C>(model: Model, _db: &C, insert: bool) -> Result<Model, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if model.price < Decimal::ZERO {\n            Err(DbErr::Custom(format!(\n                \"[after_save] Invalid Price, insert: {insert}\"\n            )))\n        } else {\n            Ok(model)\n        }\n    }\n\n    fn before_delete<C>(self, _db: &C) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.name.as_ref().contains(\"(err_on_before_delete)\") {\n            Err(DbErr::Custom(\n                \"[before_delete] Cannot be deleted\".to_owned(),\n            ))\n        } else {\n            Ok(self)\n        }\n    }\n\n    fn after_delete<C>(self, _db: &C) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.name.as_ref().contains(\"(err_on_after_delete)\") {\n            Err(DbErr::Custom(\"[after_delete] Cannot be deleted\".to_owned()))\n        } else {\n            Ok(self)\n        }\n    }\n}\n\n#[test]\nfn column_type_test() {\n    let _id: sea_orm::NumericColumn<Entity> = COLUMN.id;\n    let _name: sea_orm::StringColumn<Entity> = COLUMN.name;\n    let _price: sea_orm::NumericColumn<Entity> = COLUMN.price;\n    let _bakery_id: sea_orm::NumericColumnNullable<Entity> = COLUMN.bakery_id;\n    let _gluten_free: sea_orm::BoolColumn<Entity> = COLUMN.gluten_free;\n    let _serial: sea_orm::UuidColumn<Entity> = COLUMN.serial;\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_chain/cakes_bakers.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cakes_bakers\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key)]\n    pub baker_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Cake,\n    #[sea_orm(\n        belongs_to = \"super::baker::Entity\",\n        from = \"Column::BakerId\",\n        to = \"super::baker::Column::Id\"\n    )]\n    Baker,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_chain/customer.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"customer\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub notes: Option<String>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::order::Entity\")]\n    Order,\n}\n\nimpl Related<super::order::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Order.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_chain/lineitem.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"lineitem\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub price: Decimal,\n    pub quantity: i32,\n    #[sea_orm(unique_key = \"lineitem\")]\n    pub order_id: i32,\n    #[sea_orm(unique_key = \"lineitem\")]\n    pub cake_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::order::Entity\",\n        from = \"Column::OrderId\",\n        to = \"super::order::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Order,\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\"\n    )]\n    Cake,\n}\n\nimpl Related<super::order::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Order.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_chain/mod.rs",
    "content": "pub mod baker;\npub mod bakery;\npub mod cake;\npub mod cakes_bakers;\npub mod customer;\npub mod lineitem;\npub mod order;\npub mod schema;\npub mod seed_data;\n\npub use baker::Entity as Baker;\npub use bakery::Entity as Bakery;\npub use cake::Entity as Cake;\npub use cakes_bakers::Entity as CakesBakers;\npub use customer::Entity as Customer;\npub use lineitem::Entity as Lineitem;\npub use order::Entity as Order;\npub use schema::*;\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_chain/order.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"order\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub total: Decimal,\n    pub bakery_id: i32,\n    pub customer_id: i32,\n    pub placed_at: DateTimeUtc,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::bakery::Entity\",\n        from = \"Column::BakeryId\",\n        to = \"super::bakery::Column::Id\"\n    )]\n    Bakery,\n    #[sea_orm(\n        belongs_to = \"super::customer::Entity\",\n        from = \"Column::CustomerId\",\n        to = \"super::customer::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Customer,\n    #[sea_orm(has_many = \"super::lineitem::Entity\")]\n    Lineitem,\n}\n\nimpl Related<super::bakery::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bakery.def()\n    }\n}\n\nimpl Related<super::customer::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Customer.def()\n    }\n}\n\nimpl Related<super::lineitem::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Lineitem.def()\n    }\n}\n\npub struct ToCustomer;\nimpl Linked for ToCustomer {\n    type FromEntity = Entity;\n    type ToEntity = super::customer::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::Customer.def()]\n    }\n}\n\npub struct ToLineitem;\nimpl Linked for ToLineitem {\n    type FromEntity = Entity;\n    type ToEntity = super::lineitem::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::Lineitem.def()]\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_chain/schema.rs",
    "content": "use super::*;\nuse crate::common::setup::{create_table, create_table_with_index};\nuse sea_orm::{\n    ConnectionTrait, DatabaseConnection, DbConn, ExecResult, Schema, error::*, sea_query,\n};\nuse sea_query::{ColumnDef, ForeignKey, ForeignKeyAction, Index, Table};\n\npub fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> {\n    create_bakery_table(db)?;\n    create_baker_table(db)?;\n    create_customer_table(db)?;\n    create_order_table(db)?;\n    create_cake_table(db)?;\n    create_cakes_bakers_table(db)?;\n    create_lineitem_table(db)?;\n    Ok(())\n}\n\npub fn create_bakery_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(bakery::Entity)\n        .col(\n            ColumnDef::new(bakery::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(bakery::Column::Name).string().not_null())\n        .col(\n            ColumnDef::new(bakery::Column::ProfitMargin)\n                .double()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, Bakery)\n}\n\npub fn create_baker_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(baker::Entity)\n        .col(\n            ColumnDef::new(baker::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(baker::Column::Name).string().not_null())\n        .col(\n            ColumnDef::new(baker::Column::ContactDetails)\n                .json()\n                .not_null(),\n        )\n        .col(ColumnDef::new(baker::Column::BakeryId).integer())\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-baker-bakery_id\")\n                .from(baker::Entity, baker::Column::BakeryId)\n                .to(bakery::Entity, bakery::Column::Id)\n                .on_delete(ForeignKeyAction::SetNull)\n                .on_update(ForeignKeyAction::Cascade),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, Baker)\n}\n\npub fn create_customer_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(customer::Entity)\n        .col(\n            ColumnDef::new(customer::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(customer::Column::Name).string().not_null())\n        .col(ColumnDef::new(customer::Column::Notes).text())\n        .to_owned();\n\n    create_table(db, &stmt, Customer)\n}\n\npub fn create_order_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(order::Entity)\n        .col(\n            ColumnDef::new(order::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(order::Column::Total)\n                .decimal_len(16, 4)\n                .not_null(),\n        )\n        .col(ColumnDef::new(order::Column::BakeryId).integer().not_null())\n        .col(\n            ColumnDef::new(order::Column::CustomerId)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(order::Column::PlacedAt)\n                .timestamp_with_time_zone()\n                .not_null(),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-order-bakery_id\")\n                .from(order::Entity, order::Column::BakeryId)\n                .to(bakery::Entity, bakery::Column::Id),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-order-customer_id\")\n                .from(order::Entity, order::Column::CustomerId)\n                .to(customer::Entity, customer::Column::Id)\n                .on_delete(ForeignKeyAction::Cascade)\n                .on_update(ForeignKeyAction::Cascade),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, Order)\n}\n\npub fn create_lineitem_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(lineitem::Entity)\n        .col(\n            ColumnDef::new(lineitem::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(lineitem::Column::Price)\n                .decimal_len(16, 4)\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(lineitem::Column::Quantity)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(lineitem::Column::OrderId)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(lineitem::Column::CakeId)\n                .integer()\n                .not_null(),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-lineitem-order_id\")\n                .from(lineitem::Entity, lineitem::Column::OrderId)\n                .to(order::Entity, order::Column::Id)\n                .on_delete(ForeignKeyAction::Cascade)\n                .on_update(ForeignKeyAction::Cascade),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-lineitem-cake_id\")\n                .from(lineitem::Entity, lineitem::Column::CakeId)\n                .to(cake::Entity, cake::Column::Id),\n        )\n        .to_owned();\n\n    let backend = db.get_database_backend();\n    let stmts = Schema::new(backend).create_index_from_entity(lineitem::Entity);\n    assert_eq!(stmts.len(), 1);\n    assert_eq!(\n        backend.build(&stmts[0]),\n        backend.build(\n            Index::create()\n                .name(\"idx-lineitem-lineitem\")\n                .table(lineitem::Entity)\n                .col(lineitem::Column::OrderId)\n                .col(lineitem::Column::CakeId)\n                .unique()\n        )\n    );\n\n    create_table_with_index(db, &stmt, Lineitem)\n}\n\npub fn create_cakes_bakers_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(cakes_bakers::Entity)\n        .col(\n            ColumnDef::new(cakes_bakers::Column::CakeId)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(cakes_bakers::Column::BakerId)\n                .integer()\n                .not_null(),\n        )\n        .primary_key(\n            Index::create()\n                .name(\"pk-cakes_bakers\")\n                .col(cakes_bakers::Column::CakeId)\n                .col(cakes_bakers::Column::BakerId),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-cakes_bakers-cake_id\")\n                .from(cakes_bakers::Entity, cakes_bakers::Column::CakeId)\n                .to(cake::Entity, cake::Column::Id)\n                .on_delete(ForeignKeyAction::Cascade)\n                .on_update(ForeignKeyAction::Cascade),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-cakes_bakers-baker_id\")\n                .from(cakes_bakers::Entity, cakes_bakers::Column::BakerId)\n                .to(baker::Entity, baker::Column::Id),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, CakesBakers)\n}\n\npub fn create_cake_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(cake::Entity)\n        .col(\n            ColumnDef::new(cake::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(cake::Column::Name).string().not_null())\n        .col(\n            ColumnDef::new(cake::Column::Price)\n                .decimal_len(16, 4)\n                .not_null(),\n        )\n        .col(ColumnDef::new(cake::Column::BakeryId).integer())\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-cake-bakery_id\")\n                .from(cake::Entity, cake::Column::BakeryId)\n                .to(bakery::Entity, bakery::Column::Id)\n                .on_delete(ForeignKeyAction::SetNull)\n                .on_update(ForeignKeyAction::Cascade),\n        )\n        .col(\n            ColumnDef::new(cake::Column::GlutenFree)\n                .boolean()\n                .not_null(),\n        )\n        .col(ColumnDef::new(cake::Column::Serial).uuid().not_null())\n        .to_owned();\n\n    create_table(db, &stmt, Cake)\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_chain/seed_data.rs",
    "content": "use super::*;\nuse crate::common::TestContext;\nuse sea_orm::{NotSet, Set, prelude::*};\n\npub fn init_1(ctx: &TestContext, link: bool) {\n    bakery::Entity::insert(bakery::ActiveModel {\n        id: Set(42),\n        name: Set(\"cool little bakery\".to_string()),\n        profit_margin: Set(4.1),\n    })\n    .exec(&ctx.db)\n    .expect(\"insert succeeds\");\n\n    cake::Entity::insert(cake::ActiveModel {\n        id: Set(13),\n        name: Set(\"Cheesecake\".to_owned()),\n        price: Set(2.into()),\n        bakery_id: Set(if link { Some(42) } else { None }),\n        gluten_free: Set(false),\n        ..Default::default()\n    })\n    .exec(&ctx.db)\n    .expect(\"insert succeeds\");\n\n    cake::Entity::insert(cake::ActiveModel {\n        id: Set(15),\n        name: Set(\"Chocolate\".to_owned()),\n        price: Set(3.into()),\n        bakery_id: Set(if link { Some(42) } else { None }),\n        gluten_free: Set(true),\n        ..Default::default()\n    })\n    .exec(&ctx.db)\n    .expect(\"insert succeeds\");\n\n    baker::Entity::insert(baker::ActiveModel {\n        id: Set(22),\n        name: Set(\"Master Baker\".to_owned()),\n        contact_details: Set(Json::Null),\n        bakery_id: Set(if link { Some(42) } else { None }),\n    })\n    .exec(&ctx.db)\n    .expect(\"insert succeeds\");\n\n    if link {\n        cakes_bakers::Entity::insert(cakes_bakers::ActiveModel {\n            cake_id: Set(13),\n            baker_id: Set(22),\n        })\n        .exec(&ctx.db)\n        .expect(\"insert succeeds\");\n\n        customer::Entity::insert(customer::ActiveModel {\n            id: Set(11),\n            name: Set(\"Bob\".to_owned()),\n            notes: Set(Some(\"Sweet tooth\".to_owned())),\n        })\n        .exec(&ctx.db)\n        .expect(\"insert succeeds\");\n\n        order::Entity::insert(order::ActiveModel {\n            id: Set(101),\n            total: Set(10.into()),\n            bakery_id: Set(42),\n            customer_id: Set(11),\n            placed_at: Set(\"2020-01-01T00:00:00Z\".parse().unwrap()),\n        })\n        .exec(&ctx.db)\n        .expect(\"insert succeeds\");\n\n        lineitem::Entity::insert(lineitem::ActiveModel {\n            id: NotSet,\n            price: Set(2.into()),\n            quantity: Set(2),\n            order_id: Set(101),\n            cake_id: Set(13),\n        })\n        .exec(&ctx.db)\n        .expect(\"insert succeeds\");\n\n        lineitem::Entity::insert(lineitem::ActiveModel {\n            id: NotSet,\n            price: Set(3.into()),\n            quantity: Set(2),\n            order_id: Set(101),\n            cake_id: Set(15),\n        })\n        .exec(&ctx.db)\n        .expect(\"insert succeeds\");\n    }\n}\n\npub fn init_2(ctx: &TestContext) -> Result<(), DbErr> {\n    let db = &ctx.db;\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let sea = Bakery::insert(bakery).exec(db)?.last_insert_id;\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"LakeSide Bakery\".to_owned()),\n        profit_margin: Set(5.8),\n        ..Default::default()\n    };\n    let lake = Bakery::insert(bakery).exec(db)?.last_insert_id;\n\n    let alice = baker::ActiveModel {\n        name: Set(\"Alice\".to_owned()),\n        contact_details: Set(\"+44 15273388\".into()),\n        bakery_id: Set(Some(sea)),\n        ..Default::default()\n    };\n    let alice = Baker::insert(alice).exec(db)?.last_insert_id;\n\n    let bob = baker::ActiveModel {\n        name: Set(\"Bob\".to_owned()),\n        contact_details: Set(\"+852 12345678\".into()),\n        bakery_id: Set(Some(lake)),\n        ..Default::default()\n    };\n    let bob = Baker::insert(bob).exec(db)?.last_insert_id;\n\n    let cake = cake::ActiveModel {\n        name: Set(\"Chocolate Cake\".to_owned()),\n        price: Set(\"10.25\".parse().unwrap()),\n        gluten_free: Set(false),\n        bakery_id: Set(Some(sea)),\n        ..Default::default()\n    };\n    let choco = Cake::insert(cake).exec(db)?.last_insert_id;\n\n    let cake = cake::ActiveModel {\n        name: Set(\"Double Chocolate\".to_owned()),\n        price: Set(\"12.5\".parse().unwrap()),\n        gluten_free: Set(false),\n        bakery_id: Set(Some(sea)),\n        ..Default::default()\n    };\n    let double_1 = Cake::insert(cake.clone()).exec(db)?.last_insert_id;\n\n    let mut cake = cake::ActiveModel {\n        name: Set(\"Lemon Cake\".to_owned()),\n        price: Set(\"8.8\".parse().unwrap()),\n        gluten_free: Set(true),\n        bakery_id: Set(Some(sea)),\n        ..Default::default()\n    };\n    let lemon_1 = Cake::insert(cake.clone()).exec(db)?.last_insert_id;\n    cake.bakery_id = Set(Some(lake));\n    let _lemon_2 = Cake::insert(cake).exec(db)?.last_insert_id;\n\n    let cake = cake::ActiveModel {\n        name: Set(\"Strawberry Cake\".to_owned()),\n        price: Set(\"9.9\".parse().unwrap()),\n        gluten_free: Set(false),\n        bakery_id: Set(Some(lake)),\n        ..Default::default()\n    };\n    let straw_2 = Cake::insert(cake).exec(db)?.last_insert_id;\n\n    let cake = cake::ActiveModel {\n        name: Set(\"Orange Cake\".to_owned()),\n        price: Set(\"6.5\".parse().unwrap()),\n        gluten_free: Set(true),\n        bakery_id: Set(Some(lake)),\n        ..Default::default()\n    };\n    let orange = Cake::insert(cake).exec(db)?.last_insert_id;\n\n    let mut cake = cake::ActiveModel {\n        name: Set(\"New York Cheese\".to_owned()),\n        price: Set(\"12.5\".parse().unwrap()),\n        gluten_free: Set(false),\n        bakery_id: Set(Some(sea)),\n        ..Default::default()\n    };\n    let cheese_1 = Cake::insert(cake.clone()).exec(db)?.last_insert_id;\n    cake.bakery_id = Set(Some(lake));\n    let cheese_2 = Cake::insert(cake).exec(db)?.last_insert_id;\n\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(choco),\n        baker_id: Set(alice),\n    };\n    CakesBakers::insert(rel).exec(db)?;\n\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(double_1),\n        baker_id: Set(alice),\n    };\n    CakesBakers::insert(rel).exec(db)?;\n\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(lemon_1),\n        baker_id: Set(alice),\n    };\n    CakesBakers::insert(rel).exec(db)?;\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(lemon_1),\n        baker_id: Set(bob),\n    };\n    CakesBakers::insert(rel).exec(db)?;\n\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(straw_2),\n        baker_id: Set(bob),\n    };\n    CakesBakers::insert(rel).exec(db)?;\n\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(orange),\n        baker_id: Set(bob),\n    };\n    CakesBakers::insert(rel).exec(db)?;\n\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(cheese_1),\n        baker_id: Set(alice),\n    };\n    CakesBakers::insert(rel).exec(db)?;\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(cheese_1),\n        baker_id: Set(bob),\n    };\n    CakesBakers::insert(rel).exec(db)?;\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(cheese_2),\n        baker_id: Set(alice),\n    };\n    CakesBakers::insert(rel).exec(db)?;\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(cheese_2),\n        baker_id: Set(bob),\n    };\n    CakesBakers::insert(rel).exec(db)?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_dense/NOTES.md",
    "content": "To regenerate entities, run at project root:\n```sh\nDATABASE_URL=\"postgres://sea:sea@localhost/bakery_chain_schema_crud_tests\" cargo run --manifest-path sea-orm-cli/Cargo.toml -- generate entity -o tests/common/bakery_dense --entity-format dense --er-diagram\n```"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_dense/baker.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"baker\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub contact_details: Json,\n    pub bakery_id: Option<i32>,\n    #[sea_orm(\n        belongs_to,\n        from = \"bakery_id\",\n        to = \"id\",\n        on_update = \"Cascade\",\n        on_delete = \"SetNull\"\n    )]\n    pub bakery: HasOne<super::bakery::Entity>,\n    #[sea_orm(has_many, via = \"cakes_bakers::Baker\")]\n    pub cakes: HasMany<super::cake::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_dense/bakery.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bakery\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(column_type = \"Double\")]\n    pub profit_margin: f64,\n    #[sea_orm(has_many)]\n    pub bakers: HasMany<super::baker::Entity>,\n    #[sea_orm(has_many)]\n    pub cakes: HasMany<super::cake::Entity>,\n    #[sea_orm(has_many)]\n    pub orders: HasMany<super::order::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_dense/cake.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(unique)]\n    pub name: String,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub price: Decimal,\n    pub bakery_id: Option<i32>,\n    pub gluten_free: bool,\n    pub serial: Uuid,\n    #[sea_orm(belongs_to, from = \"BakeryId\", to = \"Id\")]\n    pub bakery: HasOne<super::bakery::Entity>,\n    #[sea_orm(has_many)]\n    pub lineitems: HasMany<super::lineitem::Entity>,\n    #[sea_orm(has_many, via = \"cakes_bakers\")]\n    pub bakers: HasMany<super::baker::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {\n    fn new() -> Self {\n        use sea_orm::Set;\n        Self {\n            serial: Set(Uuid::new_v4()),\n            ..ActiveModelTrait::default()\n        }\n    }\n}\n\n/* // Following will be generated\n\npub struct EntityLoader {\n    select: sea_orm::Select<Entity>,\n    with: EntityLoaderWith,\n}\n\n#[derive(Debug, Default)]\nstruct EntityLoaderWith {\n    bakery: bool,\n    baker: bool,\n}\n\nimpl sea_orm::QueryFilter for EntityLoader {\n    type QueryStatement = <sea_orm::Select<Entity> as sea_orm::QueryFilter>::QueryStatement;\n\n    fn query(&mut self) -> &mut Self::QueryStatement {\n        sea_orm::QueryFilter::query(&mut self.select)\n    }\n}\n\nimpl sea_orm::QueryOrder for EntityLoader {\n    type QueryStatement = <sea_orm::Select<Entity> as sea_orm::QueryOrder>::QueryStatement;\n\n    fn query(&mut self) -> &mut Self::QueryStatement {\n        sea_orm::QueryOrder::query(&mut self.select)\n    }\n}\n\nimpl sea_orm::compound::EntityLoaderTrait<Entity> for EntityLoader {}\n\nimpl Entity {\n    pub fn load() -> EntityLoader {\n        EntityLoader {\n            select: Entity::find(),\n            with: Default::default(),\n        }\n    }\n}\n\nimpl EntityLoader {\n    pub fn one<C: sea_orm::ConnectionTrait>(\n        mut self,\n        db: &C,\n    ) -> Result<Option<Model>, DbErr> {\n        use sea_orm::QuerySelect;\n\n        self.select = self.select.limit(1);\n        Ok(self.all(db)?.into_iter().next())\n    }\n\n    pub fn with<R>(mut self, entity: R) -> Self\n    where\n        R: EntityTrait,\n        Entity: Related<R>,\n    {\n        if entity.table_ref() == super::bakery::Entity.table_ref() {\n            self.with.bakery = true;\n        }\n        if entity.table_ref() == super::baker::Entity.table_ref() {\n            self.with.baker = true;\n        }\n        self\n    }\n\n    pub fn load<C: sea_orm::ConnectionTrait>(Vec<Model>, with: &EntityLoaderWith, nest: &EntityLoaderNest, db: &C) -> Result<Vec<Model>, DbErr> {\n        if self.with.baker {\n            let bakers = cakes.load_many(super::baker::Entity, db)?;\n            super::baker::EntityLoader::load_nest_nest(bakers, &nest.baker)?;\n\n            for (cake, bakers) in cakes.iter_mut().zip(bakers) {\n                cake.bakers.set(bakers);\n            }\n        }\n    }\n\n    pub fn all<C: sea_orm::ConnectionTrait>(mut self, db: &C) -> Result<Vec<Model>, DbErr> {\n        let select = if self.with.bakery {\n            self.with.bakery = false;\n            self.select.find_also(Entity, super::bakery::Entity)\n        } else {\n            // select also but without join\n            self.select.select_also_fake(super::bakery::Entity)\n        };\n\n        let models = select.all(db)?;\n\n        let mut cakes = Vec::new();\n\n        for (mut cake, bakery) in models {\n            cake.bakery.set(bakery);\n            cakes.push(cake);\n        }\n\n        let cakes = Self::load(cakes, &self.with, db)?;\n\n        Ok(cakes)\n    }\n}\n\n*/\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_dense/cakes_bakers.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cakes_bakers\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub baker_id: i32,\n    #[sea_orm(belongs_to, from = \"baker_id\", to = \"id\")]\n    pub baker: Option<super::baker::Entity>,\n    #[sea_orm(belongs_to, from = \"cake_id\", to = \"id\")]\n    pub cake: Option<super::cake::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_dense/customer.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"customer\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub notes: Option<String>,\n    #[sea_orm(has_many)]\n    pub orders: HasMany<super::order::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_dense/entities.mermaid",
    "content": "erDiagram\n    baker {\n        int id PK\n        varchar name\n        json contact_details\n        int bakery_id FK\n    }\n    bakery {\n        int id PK\n        varchar name\n        double profit_margin\n    }\n    cake {\n        int id PK\n        varchar name\n        decimal price\n        int bakery_id FK\n        bool gluten_free\n        uuid serial\n    }\n    cakes_bakers {\n        int cake_id PK,FK\n        int baker_id PK,FK\n    }\n    customer {\n        int id PK\n        varchar name\n        text notes\n    }\n    lineitem {\n        int id PK\n        decimal price\n        int quantity\n        int order_id FK,UK\n        int cake_id FK,UK\n    }\n    order {\n        int id PK\n        decimal total\n        int bakery_id FK\n        int customer_id FK\n        timestamptz placed_at\n    }\n    baker }o--|| bakery : \"bakery_id\"\n    baker }o--o{ cake : \"[cakes_bakers]\"\n    cake }o--|| bakery : \"bakery_id\"\n    cakes_bakers }o--|| baker : \"baker_id\"\n    cakes_bakers }o--|| cake : \"cake_id\"\n    lineitem }o--|| cake : \"cake_id\"\n    lineitem }o--|| order : \"order_id\"\n    order }o--|| bakery : \"bakery_id\"\n    order }o--|| customer : \"customer_id\"\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_dense/lineitem.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::compact_model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"lineitem\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub price: Decimal,\n    pub quantity: i32,\n    pub order_id: i32,\n    pub cake_id: i32,\n    pub order: Option<super::order::Entity>,\n    pub cake: Option<super::cake::Entity>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::order::Entity\",\n        from = \"Column::OrderId\",\n        to = \"super::order::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Order,\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\"\n    )]\n    Cake,\n}\n\nimpl Related<super::order::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Order.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_dense/mod.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n// DATABASE_URL=sqlite://bakery.db cargo run --manifest-path sea-orm-cli/Cargo.toml -- generate entity --output-dir tests/common/bakery_dense --entity-format dense\n\npub mod prelude;\n\npub mod baker;\npub mod bakery;\npub mod cake;\npub mod cakes_bakers;\npub mod customer;\npub mod lineitem;\npub mod order;\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_dense/order.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"order\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub total: Decimal,\n    pub bakery_id: i32,\n    pub customer_id: i32,\n    pub placed_at: DateTimeWithTimeZone,\n    #[sea_orm(belongs_to, from = \"bakery_id\", to = \"id\")]\n    pub bakery: HasOne<super::bakery::Entity>,\n    #[sea_orm(belongs_to, from = \"customer_id\", to = \"id\")]\n    pub customer: HasOne<super::customer::Entity>,\n    #[sea_orm(has_many)]\n    pub lineitems: HasMany<super::lineitem::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/bakery_dense/prelude.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub use super::baker::Entity as Baker;\npub use super::bakery::Entity as Bakery;\npub use super::cake::Entity as Cake;\npub use super::cakes_bakers::Entity as CakesBakers;\npub use super::customer::Entity as Customer;\npub use super::lineitem::Entity as Lineitem;\npub use super::order::Entity as Order;\n"
  },
  {
    "path": "sea-orm-sync/tests/common/blogger/attachment.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"attachment\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub post_id: Option<i32>,\n    pub file: String,\n    #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n    pub post: HasOne<super::post::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/blogger/comment.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"comment\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub comment: String,\n    pub user_id: i32,\n    pub post_id: i32,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub user: HasOne<super::user::Entity>,\n    #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n    pub post: HasOne<super::post::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/blogger/mod.rs",
    "content": "pub mod attachment;\npub mod comment;\npub mod post;\npub mod post_tag;\npub mod profile;\npub mod tag;\npub mod user;\npub mod user_follower;\npub mod user_mono;\n"
  },
  {
    "path": "sea-orm-sync/tests/common/blogger/post.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"post\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub user_id: i32,\n    pub title: String,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub author: HasOne<super::user::Entity>,\n    #[sea_orm(has_many)]\n    pub comments: HasMany<super::comment::Entity>,\n    #[sea_orm(has_many)]\n    pub attachments: HasMany<super::attachment::Entity>,\n    #[sea_orm(has_many, via = \"post_tag\")]\n    pub tags: HasMany<super::tag::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/blogger/post_tag.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n#[sea_orm(table_name = \"post_tag\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub post_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub tag_id: i32,\n    #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n    pub post: Option<super::post::Entity>,\n    #[sea_orm(belongs_to, from = \"tag_id\", to = \"id\")]\n    pub tag: Option<super::tag::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/blogger/profile.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"profile\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub picture: String,\n    #[sea_orm(unique)]\n    pub user_id: i32,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub user: HasOne<super::user::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/blogger/tag.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"tag\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub tag: String,\n    #[sea_orm(has_many, via = \"post_tag\")]\n    pub posts: HasMany<super::post::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/blogger/user.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"user\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(unique)]\n    pub email: String,\n    #[sea_orm(has_one)]\n    pub profile: HasOne<super::profile::Entity>,\n    #[sea_orm(has_many)]\n    pub posts: HasMany<super::post::Entity>,\n    #[sea_orm(self_ref, via = \"user_follower\", from = \"User\", to = \"Follower\")]\n    pub followers: HasMany<Entity>,\n    #[sea_orm(self_ref, via = \"user_follower\", reverse)]\n    pub following: HasMany<Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\npub use super::user_follower::Entity as Follower;\n// the name `EntityReverse` is still subject to change\npub use super::user_follower::EntityReverse as Following;\n\n// the following trait impl will be generated by the marco:\n// impl RelatedSelfVia<super::user_follower::Entity> for Entity {\n//     fn to() -> RelationDef {\n//         super::user_follower::Relation::Follower.def()\n//     }\n//     fn via() -> RelationDef {\n//         super::user_follower::Relation::User.def().rev()\n//     }\n// }\n"
  },
  {
    "path": "sea-orm-sync/tests/common/blogger/user_follower.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n#[sea_orm(table_name = \"user_follower\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub user_id: i32,\n    #[sea_orm(primary_key)]\n    pub follower_id: i32,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub user: Option<super::user::Entity>,\n    #[sea_orm(\n        belongs_to,\n        relation_enum = \"Follower\",\n        from = \"follower_id\",\n        to = \"id\"\n    )]\n    pub follower: Option<super::user::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/blogger/user_mono.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"user\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(unique)]\n    pub email: String,\n    #[sea_orm(self_ref, via = \"user_follower\", from = \"User\", to = \"Follower\")]\n    pub followers: HasMany<Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/active_enum.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"sqlx-postgres\", sea_orm(schema_name = \"public\"))]\n#[sea_orm(table_name = \"active_enum\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub category: Option<Category>,\n    pub color: Option<Color>,\n    pub tea: Option<Tea>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::active_enum_child::Entity\")]\n    ActiveEnumChild,\n}\n\nimpl Related<super::active_enum_child::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::ActiveEnumChild.def()\n    }\n}\n\npub struct ActiveEnumChildLink;\n\nimpl Linked for ActiveEnumChildLink {\n    type FromEntity = Entity;\n\n    type ToEntity = super::active_enum_child::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::ActiveEnumChild.def()]\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/active_enum_child.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"sqlx-postgres\", sea_orm(schema_name = \"public\"))]\n#[sea_orm(table_name = \"active_enum_child\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub parent_id: i32,\n    pub category: Option<Category>,\n    pub color: Option<Color>,\n    pub tea: Option<Tea>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        fk_name = \"fk-active_enum_child-active_enum\",\n        belongs_to = \"super::active_enum::Entity\",\n        from = \"Column::ParentId\",\n        to = \"super::active_enum::Column::Id\"\n    )]\n    ActiveEnum,\n}\n\nimpl Related<super::active_enum::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::ActiveEnum.def()\n    }\n}\n\npub struct ActiveEnumLink;\n\nimpl Linked for ActiveEnumLink {\n    type FromEntity = Entity;\n\n    type ToEntity = super::active_enum::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::ActiveEnum.def()]\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/active_enum_vec.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"sqlx-postgres\", sea_orm(schema_name = \"public\"))]\n#[sea_orm(table_name = \"active_enum\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub categories: Option<Vec<Category>>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/applog.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"applog\", comment = \"app logs\")]\npub struct Model {\n    #[sea_orm(primary_key, comment = \"ID\")]\n    pub id: i32,\n    #[sea_orm(comment = \"action\")]\n    pub action: String,\n    #[sea_orm(comment = \"action data\")]\n    pub json: Json,\n    #[sea_orm(comment = \"create time\")]\n    pub created_at: DateTimeWithTimeZone,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/binary.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"binary\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Binary(1)\")]\n    pub binary: Vec<u8>,\n    #[sea_orm(column_type = \"Binary(10)\")]\n    pub binary_10: Vec<u8>,\n    #[sea_orm(column_type = \"VarBinary(StringLen::N(16))\")]\n    pub var_binary_16: Vec<u8>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/bits.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bits\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(\n        column_type = r#\"custom(\"BIT\")\"#,\n        select_as = \"BIGINT\",\n        save_as = \"BIT\"\n    )]\n    pub bit0: i64,\n    #[sea_orm(\n        column_type = r#\"custom(\"BIT(1)\")\"#,\n        select_as = \"BIGINT\",\n        save_as = \"BIT(1)\"\n    )]\n    pub bit1: i64,\n    #[sea_orm(\n        column_type = r#\"custom(\"BIT(8)\")\"#,\n        select_as = \"BIGINT\",\n        save_as = \"BIT(8)\"\n    )]\n    pub bit8: i64,\n    #[sea_orm(\n        column_type = r#\"custom(\"BIT(16)\")\"#,\n        select_as = \"BIGINT\",\n        save_as = \"BIT(16)\"\n    )]\n    pub bit16: i64,\n    #[sea_orm(\n        column_type = r#\"custom(\"BIT(32)\")\"#,\n        select_as = \"BIGINT\",\n        save_as = \"BIT(32)\"\n    )]\n    pub bit32: i64,\n    #[sea_orm(\n        column_type = r#\"custom(\"BIT(64)\")\"#,\n        select_as = \"BIGINT\",\n        save_as = \"BIT(64)\"\n    )]\n    pub bit64: i64,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/byte_primary_key.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"byte_primary_key\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id: Vec<u8>,\n    pub value: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/categories.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"categories\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id: i32,\n    pub categories: Option<Vec<Category>>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/collection.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::compact_model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"collection\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(\n        column_type = r#\"custom(\"citext\")\"#,\n        select_as = \"text\",\n        save_as = \"citext\"\n    )]\n    pub name: String,\n    pub integers: Vec<i32>,\n    pub integers_opt: Option<Vec<i32>>,\n    pub teas: Vec<Tea>,\n    pub teas_opt: Option<Vec<Tea>>,\n    pub colors: Vec<Color>,\n    pub colors_opt: Option<Vec<Color>>,\n    pub uuid: Vec<Uuid>,\n    pub uuid_hyphenated: Vec<uuid::fmt::Hyphenated>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/collection_expanded.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option<&str> {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> &'static str {\n        \"collection\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub integers: Vec<i32>,\n    pub integers_opt: Option<Vec<i32>>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Integers,\n    IntegersOpt,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Integers => ColumnType::Array(RcOrArc::new(ColumnType::Integer)).def(),\n            Self::IntegersOpt => ColumnType::Array(RcOrArc::new(ColumnType::Integer))\n                .def()\n                .null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        panic!(\"No RelationDef\")\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/custom_active_model.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\nuse sea_orm::{ActiveValue, IntoActiveValue};\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[cfg_attr(feature = \"sqlx-postgres\", sea_orm(schema_name = \"public\"))]\n#[sea_orm(table_name = \"custom_active_model\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub age: i32,\n    pub weight: Option<f32>,\n    pub amount: Option<i32>,\n    pub tea: Tea,\n    pub category: Option<Category>,\n    pub color: Option<Color>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[derive(Clone, Debug, PartialEq, DeriveIntoActiveModel)]\npub struct CustomActiveModel {\n    pub age: Option<i32>,\n    pub weight: Option<f32>,\n    pub amount: Option<Option<i32>>,\n    pub tea: Option<Tea>,\n    pub category: Option<Category>,\n    pub color: Option<Option<Color>>,\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/dyn_table_name.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity {\n    pub table_name: u32,\n}\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> &'static str {\n        match self.table_name {\n            1 => \"dyn_table_1\",\n            2 => \"dyn_table_2\",\n            _ => \"\",\n        }\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::None).def(),\n        }\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/edit_log.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"edit_log\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub action: String,\n    pub values: Json,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/embedding.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"embedding\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id: i32,\n    pub embedding: PgVector,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/event_trigger.rs",
    "content": "use sea_orm::entity::prelude::*;\nuse sea_orm::{\n    TryGetError, TryGetable,\n    sea_query::{ArrayType, ColumnType, ValueType},\n};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"event_trigger\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub events: Events,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Event(pub String);\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Events(pub Vec<Event>);\n\nimpl From<Events> for Value {\n    fn from(events: Events) -> Self {\n        let Events(events) = events;\n        let vec: Vec<String> = events.into_iter().map(|Event(s)| s).collect();\n        vec.into()\n    }\n}\n\nimpl TryGetable for Events {\n    fn try_get_by<I: sea_orm::ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        let vec: Vec<String> = res.try_get_by(idx).map_err(TryGetError::DbErr)?;\n        Ok(Events(vec.into_iter().map(Event).collect()))\n    }\n}\n\nimpl ValueType for Events {\n    fn try_from(v: Value) -> Result<Self, sea_query::ValueTypeErr> {\n        let value: Option<Vec<String>> =\n            v.expect(\"This Value::Array should consist of Value::String\");\n        let vec = match value {\n            Some(v) => v.into_iter().map(Event).collect(),\n            None => vec![],\n        };\n        Ok(Events(vec))\n    }\n\n    fn type_name() -> String {\n        stringify!(Events).to_owned()\n    }\n\n    fn array_type() -> ArrayType {\n        ArrayType::String\n    }\n\n    fn column_type() -> ColumnType {\n        ColumnType::Array(RcOrArc::new(ColumnType::String(StringLen::None)))\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/host_network.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"host_network\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub hostname: String,\n    pub ipaddress: IpNetwork,\n    #[sea_orm(column_type = \"Cidr\")]\n    pub network: IpNetwork,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/insert_default.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"insert_default\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/json_struct.rs",
    "content": "use sea_orm::FromJsonQueryResult;\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize, Serializer};\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"json_struct\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub json: Json,\n    pub json_value: KeyValue,\n    pub json_value_opt: Option<KeyValue>,\n    pub json_non_serializable: Option<NonSerializableStruct>,\n}\n\n#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, FromJsonQueryResult)]\npub struct KeyValue {\n    pub id: i32,\n    pub name: String,\n    pub price: f32,\n    pub notes: Option<String>,\n}\n\n#[derive(Clone, Debug, PartialEq, Deserialize, FromJsonQueryResult)]\npub struct NonSerializableStruct;\n\nimpl Serialize for NonSerializableStruct {\n    fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: Serializer,\n    {\n        Err(serde::ser::Error::custom(\n            \"intentionally failing serialization\",\n        ))\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/json_vec.rs",
    "content": "use sea_orm::TryGetableFromJson;\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"json_vec\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub str_vec: Option<StringVec>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]\npub struct StringVec(pub Vec<String>);\n\nimpl TryGetableFromJson for StringVec {}\n\nimpl From<StringVec> for Value {\n    fn from(source: StringVec) -> Self {\n        sea_orm::Value::Json(serde_json::to_value(source).ok().map(std::boxed::Box::new))\n    }\n}\n\nimpl sea_query::ValueType for StringVec {\n    fn try_from(v: Value) -> Result<Self, sea_query::ValueTypeErr> {\n        match v {\n            sea_orm::Value::Json(Some(json)) => {\n                Ok(serde_json::from_value(*json).map_err(|_| sea_orm::sea_query::ValueTypeErr)?)\n            }\n            _ => Err(sea_orm::sea_query::ValueTypeErr),\n        }\n    }\n\n    fn type_name() -> String {\n        stringify!(StringVec).to_owned()\n    }\n\n    fn array_type() -> sea_orm::sea_query::ArrayType {\n        sea_orm::sea_query::ArrayType::Json\n    }\n\n    fn column_type() -> sea_query::ColumnType {\n        sea_query::ColumnType::Json\n    }\n}\n\nimpl sea_orm::sea_query::Nullable for StringVec {\n    fn null() -> sea_orm::Value {\n        sea_orm::Value::Json(None)\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/json_vec_derive.rs",
    "content": "pub mod json_string_vec {\n    use sea_orm::FromJsonQueryResult;\n    use sea_orm::entity::prelude::*;\n    use serde::{Deserialize, Serialize};\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"json_string_vec\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub str_vec: Option<StringVec>,\n    }\n\n    #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, FromJsonQueryResult)]\n    pub struct StringVec(pub Vec<String>);\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod json_struct_vec {\n    use sea_orm::entity::prelude::*;\n    use sea_orm_macros::FromJsonQueryResult;\n    use serde::{Deserialize, Serialize};\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"json_struct_vec\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_type = \"JsonBinary\")]\n        pub struct_vec: Vec<JsonColumn>,\n    }\n\n    #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, FromJsonQueryResult)]\n    pub struct JsonColumn {\n        pub value: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/metadata.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"metadata\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub uuid: Uuid,\n    #[sea_orm(column_name = \"type\", enum_name = \"Type\")]\n    pub ty: String,\n    pub key: String,\n    pub value: String,\n    #[sea_orm(column_type = \"var_binary(32)\")]\n    pub bytes: Vec<u8>,\n    pub date: Option<Date>,\n    pub time: Option<Time>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/mod.rs",
    "content": "pub mod active_enum;\npub mod active_enum_child;\npub mod active_enum_vec;\npub mod applog;\npub mod binary;\npub mod bits;\npub mod byte_primary_key;\npub mod categories;\npub mod collection;\npub mod collection_expanded;\npub mod custom_active_model;\npub mod dyn_table_name;\npub mod edit_log;\n#[cfg(feature = \"postgres-vector\")]\npub mod embedding;\npub mod event_trigger;\n#[cfg(feature = \"with-ipnetwork\")]\npub mod host_network;\npub mod insert_default;\npub mod json_struct;\npub mod json_vec;\npub mod json_vec_derive;\npub mod metadata;\n#[cfg(feature = \"with-bigdecimal\")]\npub mod pi;\npub mod repository;\npub mod satellite;\npub mod schema;\npub mod sea_orm_active_enums;\npub mod self_join;\npub mod teas;\npub mod transaction_log;\npub mod uuid_fmt;\npub mod value_type;\n\npub use active_enum::Entity as ActiveEnum;\npub use active_enum_child::Entity as ActiveEnumChild;\npub use active_enum_vec::Entity as ActiveEnumVec;\npub use applog::Entity as Applog;\npub use binary::Entity as Binary;\npub use bits::Entity as Bits;\npub use byte_primary_key::Entity as BytePrimaryKey;\npub use categories::Entity as Categories;\npub use collection::Entity as Collection;\npub use collection_expanded::Entity as CollectionExpanded;\npub use dyn_table_name::Entity as DynTableName;\npub use edit_log::Entity as EditLog;\n#[cfg(feature = \"postgres-vector\")]\npub use embedding::Entity as Embedding;\npub use event_trigger::Entity as EventTrigger;\npub use insert_default::Entity as InsertDefault;\npub use json_struct::Entity as JsonStruct;\npub use json_vec::Entity as JsonVec;\npub use json_vec_derive::json_string_vec::Entity as JsonStringVec;\npub use json_vec_derive::json_struct_vec::Entity as JsonStructVec;\npub use metadata::Entity as Metadata;\npub use repository::Entity as Repository;\npub use satellite::Entity as Satellite;\npub use schema::*;\npub use sea_orm_active_enums::*;\npub use self_join::Entity as SelfJoin;\npub use teas::Entity as Teas;\npub use transaction_log::Entity as TransactionLog;\npub use uuid_fmt::Entity as UuidFmt;\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/pi.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"pi\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Decimal(Some((11, 10)))\")]\n    pub decimal: Decimal,\n    #[sea_orm(column_type = \"Decimal(Some((11, 10)))\")]\n    pub big_decimal: BigDecimal,\n    #[sea_orm(column_type = \"Decimal(Some((11, 10)))\")]\n    pub decimal_opt: Option<Decimal>,\n    #[sea_orm(column_type = \"Decimal(Some((11, 10)))\")]\n    pub big_decimal_opt: Option<BigDecimal>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/repository.rs",
    "content": "use super::edit_log;\nuse sea_orm::{ConnectionTrait, Set, TryIntoModel, entity::prelude::*};\nuse serde::Serialize;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize)]\n#[sea_orm(table_name = \"repository\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id: String,\n    pub owner: String,\n    pub name: String,\n    pub description: Option<String>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {\n    fn before_save<C>(self, db: &C, _: bool) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let model = self.clone().try_into_model()?;\n        insert_edit_log(\"before_save\", &model, db)?;\n        Ok(self)\n    }\n\n    fn after_save<C>(model: Model, db: &C, _: bool) -> Result<Model, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        insert_edit_log(\"after_save\", &model, db)?;\n        Ok(model)\n    }\n\n    fn before_delete<C>(self, db: &C) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let model = self.clone().try_into_model()?;\n        insert_edit_log(\"before_delete\", &model, db)?;\n        Ok(self)\n    }\n\n    fn after_delete<C>(self, db: &C) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let model = self.clone().try_into_model()?;\n        insert_edit_log(\"after_delete\", &model, db)?;\n        Ok(self)\n    }\n}\n\nfn insert_edit_log<T, M, C>(action: T, model: &M, db: &C) -> Result<(), DbErr>\nwhere\n    T: Into<String>,\n    M: Serialize,\n    C: ConnectionTrait,\n{\n    edit_log::ActiveModel {\n        action: Set(action.into()),\n        values: Set(serde_json::json!(model)),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/satellite.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"satellite\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub satellite_name: String,\n    #[sea_orm(default_value = \"2022-01-26 16:24:00\")]\n    pub launch_date: DateTimeUtc,\n    #[sea_orm(default_value = \"2022-01-26 16:24:00\")]\n    pub deployment_date: DateTimeLocal,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/schema.rs",
    "content": "use super::*;\nuse crate::common::setup::{\n    create_enum, create_table, create_table_from_entity, create_table_without_asserts,\n};\nuse sea_orm::{\n    ConnectionTrait, DatabaseConnection, DbBackend, DbConn, EntityName, ExecResult, Schema,\n    error::*, sea_query,\n};\nuse sea_query::{\n    Alias, ColumnDef, ColumnType, ForeignKeyCreateStatement, IntoIden, IntoTableRef, StringLen,\n    extension::postgres::Type,\n};\n\npub fn create_tea_enum(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let db_backend = db.get_database_backend();\n    let create_enum_stmts = match db_backend {\n        DbBackend::MySql | DbBackend::Sqlite => Vec::new(),\n        DbBackend::Postgres => {\n            let schema = Schema::new(db_backend);\n            let enum_create_stmt = Type::create()\n                .as_enum(\"tea\")\n                .values([\"EverydayTea\", \"BreakfastTea\", \"AfternoonTea\"])\n                .to_owned();\n            assert_eq!(\n                db_backend.build(&enum_create_stmt),\n                db_backend.build(&schema.create_enum_from_active_enum::<Tea>().unwrap())\n            );\n            vec![enum_create_stmt]\n        }\n        db => {\n            return Err(DbErr::BackendNotSupported {\n                db: db.as_str(),\n                ctx: \"create_tea_enum\",\n            });\n        }\n    };\n    create_enum(db, &create_enum_stmts, ActiveEnum)?;\n    Ok(())\n}\n\npub fn create_log_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(applog::Entity)\n        .comment(\"app logs\")\n        .col(\n            ColumnDef::new(applog::Column::Id)\n                .integer()\n                .not_null()\n                .comment(\"ID\")\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(applog::Column::Action)\n                .string()\n                .not_null()\n                .comment(\"action\"),\n        )\n        .col(\n            ColumnDef::new(applog::Column::Json)\n                .json()\n                .not_null()\n                .comment(\"action data\"),\n        )\n        .col(\n            ColumnDef::new(applog::Column::CreatedAt)\n                .timestamp_with_time_zone()\n                .not_null()\n                .comment(\"create time\"),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, Applog)\n}\n\npub fn create_metadata_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(metadata::Entity)\n        .col(\n            ColumnDef::new(metadata::Column::Uuid)\n                .uuid()\n                .not_null()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(metadata::Column::Type).string().not_null())\n        .col(ColumnDef::new(metadata::Column::Key).string().not_null())\n        .col(ColumnDef::new(metadata::Column::Value).string().not_null())\n        .col(\n            ColumnDef::new_with_type(\n                metadata::Column::Bytes,\n                ColumnType::VarBinary(StringLen::N(32)),\n            )\n            .not_null(),\n        )\n        .col(ColumnDef::new(metadata::Column::Date).date())\n        .col(ColumnDef::new(metadata::Column::Time).time())\n        .to_owned();\n\n    create_table(db, &stmt, Metadata)\n}\n\npub fn create_repository_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(repository::Entity)\n        .col(\n            ColumnDef::new(repository::Column::Id)\n                .string()\n                .not_null()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(repository::Column::Owner)\n                .string()\n                .not_null(),\n        )\n        .col(ColumnDef::new(repository::Column::Name).string().not_null())\n        .col(ColumnDef::new(repository::Column::Description).string())\n        .to_owned();\n\n    create_table(db, &stmt, Repository)\n}\n\npub fn create_self_join_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(self_join::Entity)\n        .col(\n            ColumnDef::new(self_join::Column::Uuid)\n                .uuid()\n                .not_null()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(self_join::Column::UuidRef).uuid())\n        .col(ColumnDef::new(self_join::Column::Time).time())\n        .foreign_key(\n            ForeignKeyCreateStatement::new()\n                .name(\"fk-self_join-uuid_ref\")\n                .from_tbl(SelfJoin)\n                .from_col(self_join::Column::UuidRef)\n                .to_tbl(SelfJoin)\n                .to_col(self_join::Column::Uuid),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, SelfJoin)\n}\n\npub fn create_byte_primary_key_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let mut primary_key_col = ColumnDef::new(byte_primary_key::Column::Id);\n    match db.get_database_backend() {\n        DbBackend::MySql => primary_key_col.binary_len(3),\n        DbBackend::Sqlite | DbBackend::Postgres => primary_key_col.binary(),\n        db => {\n            return Err(DbErr::BackendNotSupported {\n                db: db.as_str(),\n                ctx: \"create_byte_primary_key_table\",\n            });\n        }\n    };\n\n    let stmt = sea_query::Table::create()\n        .table(byte_primary_key::Entity)\n        .col(primary_key_col.not_null().primary_key())\n        .col(\n            ColumnDef::new(byte_primary_key::Column::Value)\n                .string()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table_without_asserts(db, &stmt)\n}\n\npub fn create_active_enum_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(active_enum::Entity.table_ref())\n        .col(\n            ColumnDef::new(active_enum::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(active_enum::Column::Category).string_len(1))\n        .col(ColumnDef::new(active_enum::Column::Color).integer())\n        .col(ColumnDef::new(active_enum::Column::Tea).enumeration(\n            TeaEnum,\n            [\n                TeaVariant::EverydayTea,\n                TeaVariant::BreakfastTea,\n                TeaVariant::AfternoonTea,\n            ],\n        ))\n        .to_owned();\n\n    create_table(db, &create_table_stmt, ActiveEnum)\n}\n\npub fn create_active_enum_child_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(active_enum_child::Entity.table_ref())\n        .col(\n            ColumnDef::new(active_enum_child::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(active_enum_child::Column::ParentId)\n                .integer()\n                .not_null(),\n        )\n        .col(ColumnDef::new(active_enum_child::Column::Category).string_len(1))\n        .col(ColumnDef::new(active_enum_child::Column::Color).integer())\n        .col(ColumnDef::new(active_enum_child::Column::Tea).enumeration(\n            TeaEnum,\n            [\n                TeaVariant::EverydayTea,\n                TeaVariant::BreakfastTea,\n                TeaVariant::AfternoonTea,\n            ],\n        ))\n        .foreign_key(\n            ForeignKeyCreateStatement::new()\n                .name(\"fk-active_enum_child-active_enum\")\n                .from_tbl(ActiveEnumChild)\n                .from_col(active_enum_child::Column::ParentId)\n                .to_tbl(if cfg!(feature = \"sqlx-postgres\") {\n                    (\"public\", ActiveEnum).into_table_ref()\n                } else {\n                    ActiveEnum.into_table_ref()\n                })\n                .to_col(active_enum::Column::Id),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, ActiveEnumChild)\n}\n\npub fn create_satellites_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(satellite::Entity)\n        .col(\n            ColumnDef::new(satellite::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(satellite::Column::SatelliteName)\n                .string()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(satellite::Column::LaunchDate)\n                .timestamp_with_time_zone()\n                .not_null()\n                .default(\"2022-01-26 16:24:00\"),\n        )\n        .col(\n            ColumnDef::new(satellite::Column::DeploymentDate)\n                .timestamp_with_time_zone()\n                .not_null()\n                .default(\"2022-01-26 16:24:00\"),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, Satellite)\n}\n\npub fn create_transaction_log_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(transaction_log::Entity)\n        .col(\n            ColumnDef::new(transaction_log::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(transaction_log::Column::Date)\n                .date()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(transaction_log::Column::Time)\n                .time()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(transaction_log::Column::DateTime)\n                .date_time()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(transaction_log::Column::DateTimeTz)\n                .timestamp_with_time_zone()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, TransactionLog)\n}\n\npub fn create_insert_default_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(insert_default::Entity.table_ref())\n        .col(\n            ColumnDef::new(insert_default::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, InsertDefault)\n}\n\npub fn create_json_vec_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(json_vec::Entity.table_ref())\n        .col(\n            ColumnDef::new(json_vec::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(json_vec::Column::StrVec).json())\n        .to_owned();\n\n    create_table(db, &create_table_stmt, JsonVec)\n}\n\npub fn create_json_struct_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(json_struct::Entity)\n        .col(\n            ColumnDef::new(json_struct::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(json_struct::Column::Json).json().not_null())\n        .col(\n            ColumnDef::new(json_struct::Column::JsonValue)\n                .json()\n                .not_null(),\n        )\n        .col(ColumnDef::new(json_struct::Column::JsonValueOpt).json())\n        .col(ColumnDef::new(json_struct::Column::JsonNonSerializable).json())\n        .to_owned();\n\n    create_table(db, &stmt, JsonStruct)\n}\n\npub fn create_json_string_vec_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(JsonStringVec.table_ref())\n        .col(\n            ColumnDef::new(json_vec_derive::json_string_vec::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(json_vec_derive::json_string_vec::Column::StrVec).json())\n        .to_owned();\n\n    create_table(db, &create_table_stmt, JsonStringVec)\n}\n\npub fn create_json_struct_vec_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(JsonStructVec.table_ref())\n        .col(\n            ColumnDef::new(json_vec_derive::json_struct_vec::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(json_vec_derive::json_struct_vec::Column::StructVec)\n                .json_binary()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, JsonStructVec)\n}\n\npub fn create_collection_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    db.execute_raw(sea_orm::Statement::from_string(\n        db.get_database_backend(),\n        \"CREATE EXTENSION IF NOT EXISTS citext\",\n    ))?;\n\n    let stmt = sea_query::Table::create()\n        .table(collection::Entity)\n        .col(\n            ColumnDef::new(collection::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(collection::Column::Name)\n                .custom(\"citext\")\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(collection::Column::Integers)\n                .array(sea_query::ColumnType::Integer)\n                .not_null(),\n        )\n        .col(ColumnDef::new(collection::Column::IntegersOpt).array(sea_query::ColumnType::Integer))\n        .col(\n            ColumnDef::new(collection::Column::Teas)\n                .array(sea_query::ColumnType::Enum {\n                    name: TeaEnum.into_iden(),\n                    variants: vec![\n                        TeaVariant::EverydayTea.into_iden(),\n                        TeaVariant::BreakfastTea.into_iden(),\n                        TeaVariant::AfternoonTea.into_iden(),\n                    ],\n                })\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(collection::Column::TeasOpt).array(sea_query::ColumnType::Enum {\n                name: TeaEnum.into_iden(),\n                variants: vec![\n                    TeaVariant::EverydayTea.into_iden(),\n                    TeaVariant::BreakfastTea.into_iden(),\n                    TeaVariant::AfternoonTea.into_iden(),\n                ],\n            }),\n        )\n        .col(\n            ColumnDef::new(collection::Column::Colors)\n                .array(sea_query::ColumnType::Integer)\n                .not_null(),\n        )\n        .col(ColumnDef::new(collection::Column::ColorsOpt).array(sea_query::ColumnType::Integer))\n        .col(\n            ColumnDef::new(collection::Column::Uuid)\n                .array(sea_query::ColumnType::Uuid)\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(collection::Column::UuidHyphenated)\n                .array(sea_query::ColumnType::Uuid)\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, Collection)\n}\n\n#[cfg(feature = \"with-ipnetwork\")]\npub fn create_host_network_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(host_network::Entity)\n        .col(\n            ColumnDef::new(host_network::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(host_network::Column::Hostname)\n                .string()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(host_network::Column::Ipaddress)\n                .inet()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(host_network::Column::Network)\n                .cidr()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, host_network::Entity)\n}\n\n#[cfg(feature = \"with-bigdecimal\")]\npub fn create_pi_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(pi::Entity)\n        .col(\n            ColumnDef::new(pi::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(pi::Column::Decimal)\n                .decimal_len(11, 10)\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(pi::Column::BigDecimal)\n                .decimal_len(11, 10)\n                .not_null(),\n        )\n        .col(ColumnDef::new(pi::Column::DecimalOpt).decimal_len(11, 10))\n        .col(ColumnDef::new(pi::Column::BigDecimalOpt).decimal_len(11, 10))\n        .to_owned();\n\n    create_table(db, &stmt, pi::Entity)\n}\n\npub fn create_event_trigger_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(event_trigger::Entity)\n        .col(\n            ColumnDef::new(event_trigger::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(event_trigger::Column::Events)\n                .array(sea_query::ColumnType::String(StringLen::None))\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, EventTrigger)\n}\n\npub fn create_uuid_fmt_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(uuid_fmt::Entity)\n        .col(\n            ColumnDef::new(uuid_fmt::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(uuid_fmt::Column::Uuid).uuid().not_null())\n        .col(\n            ColumnDef::new(uuid_fmt::Column::UuidBraced)\n                .uuid()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(uuid_fmt::Column::UuidHyphenated)\n                .uuid()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(uuid_fmt::Column::UuidSimple)\n                .uuid()\n                .not_null(),\n        )\n        .col(ColumnDef::new(uuid_fmt::Column::UuidUrn).uuid().not_null())\n        .to_owned();\n\n    create_table(db, &stmt, UuidFmt)\n}\n\npub fn create_edit_log_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(edit_log::Entity)\n        .col(\n            ColumnDef::new(edit_log::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(edit_log::Column::Action).string().not_null())\n        .col(ColumnDef::new(edit_log::Column::Values).json().not_null())\n        .to_owned();\n\n    create_table(db, &stmt, EditLog)\n}\n\npub fn create_teas_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(teas::Entity.table_ref())\n        .col(\n            ColumnDef::new(teas::Column::Id)\n                .enumeration(\n                    TeaEnum,\n                    [\n                        TeaVariant::EverydayTea,\n                        TeaVariant::BreakfastTea,\n                        TeaVariant::AfternoonTea,\n                    ],\n                )\n                .not_null()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(teas::Column::Category).string_len(1))\n        .col(ColumnDef::new(teas::Column::Color).integer())\n        .to_owned();\n\n    create_table(db, &create_table_stmt, Teas)\n}\n\npub fn create_categories_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(categories::Entity.table_ref())\n        .col(\n            ColumnDef::new(categories::Column::Id)\n                .integer()\n                .not_null()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(categories::Column::Categories)\n                .array(ColumnType::String(StringLen::N(1))),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, Categories)\n}\n\n#[cfg(feature = \"postgres-vector\")]\npub fn create_embedding_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    db.execute(sea_orm::Statement::from_string(\n        db.get_database_backend(),\n        \"CREATE EXTENSION IF NOT EXISTS vector\",\n    ))?;\n\n    let create_table_stmt = sea_query::Table::create()\n        .table(embedding::Entity.table_ref())\n        .col(\n            ColumnDef::new(embedding::Column::Id)\n                .integer()\n                .not_null()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(embedding::Column::Embedding)\n                .vector(None)\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, Embedding)\n}\n\npub fn create_binary_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(binary::Entity.table_ref())\n        .col(\n            ColumnDef::new(binary::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(binary::Column::Binary).binary().not_null())\n        .col(\n            ColumnDef::new(binary::Column::Binary10)\n                .binary_len(10)\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(binary::Column::VarBinary16)\n                .var_binary(16)\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, Binary)\n}\n\npub fn create_bits_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(bits::Entity.table_ref())\n        .col(\n            ColumnDef::new(bits::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(bits::Column::Bit0).custom(\"BIT\").not_null())\n        .col(\n            ColumnDef::new(bits::Column::Bit1)\n                .custom(\"BIT(1)\")\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(bits::Column::Bit8)\n                .custom(\"BIT(8)\")\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(bits::Column::Bit16)\n                .custom(\"BIT(16)\")\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(bits::Column::Bit32)\n                .custom(\"BIT(32)\")\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(bits::Column::Bit64)\n                .custom(\"BIT(64)\")\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, Bits)\n}\n\npub fn create_dyn_table_name_lazy_static_table(db: &DbConn) -> Result<(), DbErr> {\n    use dyn_table_name::*;\n\n    let entities = [Entity { table_name: 1 }, Entity { table_name: 2 }];\n    for entity in entities {\n        let create_table_stmt = sea_query::Table::create()\n            .table(entity.table_ref())\n            .col(\n                ColumnDef::new(Column::Id)\n                    .integer()\n                    .not_null()\n                    .auto_increment()\n                    .primary_key(),\n            )\n            .col(ColumnDef::new(Column::Name).string().not_null())\n            .to_owned();\n\n        create_table(db, &create_table_stmt, entity)?;\n    }\n\n    Ok(())\n}\n\npub fn create_value_type_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let general_stmt = sea_query::Table::create()\n        .table(value_type::value_type_general::Entity)\n        .col(\n            ColumnDef::new(value_type::value_type_general::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(value_type::value_type_general::Column::Number)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(value_type::value_type_general::Column::Tag1)\n                .string()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(value_type::value_type_general::Column::Tag2)\n                .text()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &general_stmt, value_type::value_type_general::Entity)?;\n    create_table_from_entity(db, value_type::value_type_pk::Entity)\n}\n\npub fn create_value_type_postgres_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let postgres_stmt = sea_query::Table::create()\n        .table(value_type::value_type_pg::Entity)\n        .col(\n            ColumnDef::new(value_type::value_type_pg::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(value_type::value_type_pg::Column::Number)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(value_type::value_type_pg::Column::StrVec)\n                .array(sea_query::ColumnType::String(StringLen::None))\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &postgres_stmt, value_type::value_type_pg::Entity)\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/sea_orm_active_enums.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"String\", db_type = \"String(StringLen::N(1))\")]\npub enum Category {\n    #[sea_orm(string_value = \"B\")]\n    Big,\n    #[sea_orm(string_value = \"S\")]\n    Small,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"i32\", db_type = \"Integer\")]\npub enum Color {\n    #[sea_orm(num_value = 0)]\n    Black,\n    #[sea_orm(num_value = 1)]\n    White,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n#[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"tea\")]\npub enum Tea {\n    #[sea_orm(string_value = \"EverydayTea\")]\n    EverydayTea,\n    #[sea_orm(string_value = \"BreakfastTea\")]\n    BreakfastTea,\n    #[sea_orm(string_value = \"AfternoonTea\")]\n    AfternoonTea,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Copy)]\n#[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"media_type\")]\npub enum MediaType {\n    #[sea_orm(string_value = \"UNKNOWN\")]\n    Unknown,\n    #[sea_orm(string_value = \"BITMAP\")]\n    Bitmap,\n    #[sea_orm(string_value = \"DRAWING\")]\n    Drawing,\n    #[sea_orm(string_value = \"AUDIO\")]\n    Audio,\n    #[sea_orm(string_value = \"VIDEO\")]\n    Video,\n    #[sea_orm(string_value = \"MULTIMEDIA\")]\n    Multimedia,\n    #[sea_orm(string_value = \"OFFICE\")]\n    Office,\n    #[sea_orm(string_value = \"TEXT\")]\n    Text,\n    #[sea_orm(string_value = \"EXECUTABLE\")]\n    Executable,\n    #[sea_orm(string_value = \"ARCHIVE\")]\n    Archive,\n    #[sea_orm(string_value = \"3D\")]\n    _3D,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n#[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"tea\")]\npub enum DisplayTea {\n    #[sea_orm(string_value = \"EverydayTea\", display_value = \"Everyday\")]\n    EverydayTea,\n    #[sea_orm(string_value = \"BreakfastTea\", display_value = \"Breakfast\")]\n    BreakfastTea,\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/self_join.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"self_join\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub uuid: Uuid,\n    pub uuid_ref: Option<Uuid>,\n    pub time: Option<Time>,\n    #[sea_orm(self_ref, relation_enum = \"SelfRef\", from = \"uuid_ref\", to = \"uuid\")]\n    pub other: HasOne<Entity>,\n}\n\npub struct SelfReferencingLink;\n\nimpl Linked for SelfReferencingLink {\n    type FromEntity = Entity;\n\n    type ToEntity = Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::SelfRef.def()]\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/teas.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"teas\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id: Tea,\n    pub category: Option<Category>,\n    pub color: Option<Color>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/transaction_log.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"transaction_log\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub date: TimeDate,\n    pub time: TimeTime,\n    pub date_time: TimeDateTime,\n    pub date_time_tz: TimeDateTimeWithTimeZone,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/uuid_fmt.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"uuid_fmt\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub uuid: Uuid,\n    pub uuid_braced: uuid::fmt::Braced,\n    pub uuid_hyphenated: uuid::fmt::Hyphenated,\n    pub uuid_simple: uuid::fmt::Simple,\n    pub uuid_urn: uuid::fmt::Urn,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/features/value_type.rs",
    "content": "pub mod value_type_general {\n    use super::*;\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"value_type\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub number: MyInteger,\n        pub tag_1: Tag1,\n        pub tag_2: Tag2,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod value_type_pg {\n    use super::*;\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"value_type_postgres\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub number: MyInteger,\n        pub str_vec: StringVec,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod value_type_pk {\n    use super::*;\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"value_type_pk\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: MyInteger,\n        pub val: MyInteger,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveValueType)]\npub struct MyInteger(pub i32);\n\nimpl<T> From<T> for MyInteger\nwhere\n    T: Into<i32>,\n{\n    fn from(v: T) -> MyInteger {\n        MyInteger(v.into())\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveValueType)]\npub struct StringVec(pub Vec<String>);\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(value_type = \"String\")]\npub enum Tag1 {\n    Hard,\n    Soft,\n}\n\nimpl std::fmt::Display for Tag1 {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(\n            f,\n            \"{}\",\n            match self {\n                Self::Hard => \"hard\",\n                Self::Soft => \"soft\",\n            }\n        )\n    }\n}\n\nimpl std::str::FromStr for Tag1 {\n    type Err = sea_query::ValueTypeErr;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        Ok(match s {\n            \"hard\" => Self::Hard,\n            \"soft\" => Self::Soft,\n            _ => return Err(sea_query::ValueTypeErr),\n        })\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(\n    value_type = \"String\",\n    from_str = \"Tag2::from_str\",\n    to_str = \"Tag2::to_str\",\n    column_type = \"Text\"\n)]\npub enum Tag2 {\n    Color,\n    Grey,\n}\n\nimpl Tag2 {\n    fn to_str(&self) -> &'static str {\n        match self {\n            Self::Color => \"color\",\n            Self::Grey => \"grey\",\n        }\n    }\n\n    fn from_str(s: &str) -> Result<Self, sea_query::ValueTypeErr> {\n        Ok(match s {\n            \"color\" => Self::Color,\n            \"grey\" => Self::Grey,\n            _ => return Err(sea_query::ValueTypeErr),\n        })\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(value_type = \"String\")]\npub struct Tag3 {\n    pub i: i64,\n}\n\nimpl std::fmt::Display for Tag3 {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", self.i)\n    }\n}\n\nimpl std::str::FromStr for Tag3 {\n    type Err = std::num::ParseIntError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        let i: i64 = s.parse()?;\n        Ok(Self { i })\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(value_type = \"String\")]\npub struct Tag4(pub i64);\n\nimpl std::fmt::Display for Tag4 {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", self.0)\n    }\n}\n\nimpl std::str::FromStr for Tag4 {\n    type Err = std::num::ParseIntError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        let i: i64 = s.parse()?;\n        Ok(Self(i))\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(value_type = \"String\")]\n// Test with inner type that doesn't implement ToString/FromStr\npub struct Tag5(pub std::path::PathBuf);\n\nimpl std::fmt::Display for Tag5 {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", self.0.display())\n    }\n}\n\nimpl std::str::FromStr for Tag5 {\n    type Err = std::num::ParseIntError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        Ok(Self(std::path::PathBuf::from(s)))\n    }\n}\n\n// Test for try_from_u64 attribute with type alias\ntype UserId = i32;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(try_from_u64)]\npub struct MyUserId(pub UserId);\n"
  },
  {
    "path": "sea-orm-sync/tests/common/film_store.rs",
    "content": "pub mod film {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"film\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub title: String,\n        #[sea_orm(has_many, via = \"film_actor\")]\n        pub actors: HasMany<super::actor::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod actor {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"actor\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub name: String,\n        #[sea_orm(has_many, via = \"film_actor\")]\n        pub films: HasMany<super::film::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod film_actor {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"film_actor\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique_key = \"film_actor\")]\n        pub film_id: i32,\n        #[sea_orm(unique_key = \"film_actor\")]\n        pub actor_id: i32,\n        #[sea_orm(belongs_to, from = \"film_id\", to = \"id\")]\n        pub film: HasOne<super::film::Entity>,\n        #[sea_orm(belongs_to, from = \"actor_id\", to = \"id\")]\n        pub actor: HasOne<super::actor::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod staff {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"staff\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n        pub reports_to_id: Option<i32>,\n        #[sea_orm(\n            self_ref,\n            relation_enum = \"ReportsTo\",\n            relation_reverse = \"Manages\",\n            from = \"reports_to_id\",\n            to = \"id\"\n        )]\n        pub reports_to: HasOne<Entity>,\n        #[sea_orm(self_ref, relation_enum = \"Manages\", relation_reverse = \"ReportsTo\")]\n        pub manages: HasMany<Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod staff_mono {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"staff\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n        pub reports_to_id: Option<i32>,\n        #[sea_orm(\n            self_ref,\n            relation_enum = \"ReportsTo\",\n            from = \"reports_to_id\",\n            to = \"id\"\n        )]\n        pub reports_to: HasOne<Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod staff_compact {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::compact_model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"staff\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n        pub reports_to_id: Option<i32>,\n        #[sea_orm(self_ref, relation_enum = \"ReportsTo\")]\n        pub reports_to: HasOne<Entity>,\n        #[sea_orm(self_ref, relation_enum = \"Manages\")]\n        pub manages: HasMany<Entity>,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {\n        #[sea_orm(belongs_to = \"Entity\", from = \"Column::ReportsToId\", to = \"Column::Id\")]\n        ReportsTo,\n        #[sea_orm(has_many = \"Entity\", via_rel = \"Relation::ReportsTo\")]\n        Manages,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/mod.rs",
    "content": "pub mod bakery_chain;\npub mod bakery_dense;\npub mod blogger;\npub mod features;\npub mod film_store;\n#[cfg(not(feature = \"sync\"))]\npub mod runtime;\npub mod setup;\n\nuse sea_orm::DatabaseConnection;\n\npub struct TestContext {\n    base_url: String,\n    db_name: String,\n    pub db: DatabaseConnection,\n}\n\nimpl TestContext {\n    pub fn new(test_name: &str) -> Self {\n        dotenv::from_filename(\".env.local\").ok();\n        dotenv::from_filename(\".env\").ok();\n\n        let base_url =\n            std::env::var(\"DATABASE_URL\").expect(\"Environment variable 'DATABASE_URL' not set\");\n        let db: DatabaseConnection = setup::setup(&base_url, test_name);\n\n        Self {\n            base_url,\n            db_name: test_name.to_string(),\n            db,\n        }\n    }\n\n    pub fn delete(&self) {\n        setup::tear_down(&self.base_url, &self.db_name);\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/runtime.rs",
    "content": "#[cfg(feature = \"runtime-async-std\")]\n#[macro_export]\nmacro_rules! block_on {\n    ($($expr:tt)*) => {\n        ::async_std::task::block_on( $($expr)* )\n    };\n}\n\n#[cfg(feature = \"runtime-tokio\")]\n#[macro_export]\nmacro_rules! block_on {\n    ($($expr:tt)*) => {\n        ::tokio::runtime::Runtime::new()\n            .unwrap()\n            .block_on( $($expr)* )\n    };\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/common/sakila/NOTES.md",
    "content": "To re-generate diagram, run at project root:\n```sh\nDATABASE_URL=\"postgres://sea:sea@localhost/sakila\" cargo run --manifest-path sea-orm-cli/Cargo.toml -- generate entity -o tests/common/sakila --entity-format dense --er-diagram\n```"
  },
  {
    "path": "sea-orm-sync/tests/common/sakila/entities.mermaid",
    "content": "erDiagram\n    actor {\n        int actor_id PK\n        varchar first_name\n        varchar last_name\n        datetime last_update\n    }\n    address {\n        int address_id PK\n        varchar address\n        varchar address2\n        varchar district\n        int city_id FK\n        varchar postal_code\n        varchar phone\n        datetime last_update\n    }\n    category {\n        int category_id PK\n        varchar name\n        datetime last_update\n    }\n    city {\n        int city_id PK\n        varchar city\n        int country_id FK\n        datetime last_update\n    }\n    country {\n        int country_id PK\n        varchar country\n        datetime last_update\n    }\n    customer {\n        int customer_id PK\n        int store_id FK\n        varchar first_name\n        varchar last_name\n        varchar email\n        int address_id FK\n        bool activebool\n        date create_date\n        datetime last_update\n        int active\n    }\n    film {\n        int film_id PK\n        varchar title\n        text description\n        int release_year\n        int language_id FK\n        int original_language_id FK\n        int rental_duration\n        decimal rental_rate\n        int length\n        decimal replacement_cost\n        enum rating\n        datetime last_update\n        array special_features\n        custom fulltext\n        json metadata\n    }\n    film_actor {\n        int actor_id PK,FK\n        int film_id PK,FK\n        datetime last_update\n    }\n    film_category {\n        int film_id PK,FK\n        int category_id PK,FK\n        datetime last_update\n    }\n    inventory {\n        int inventory_id PK\n        int film_id FK\n        int store_id FK\n        datetime last_update\n    }\n    language {\n        int language_id PK\n        char name\n        datetime last_update\n    }\n    payment {\n        int payment_id PK\n        int customer_id FK\n        int staff_id FK\n        int rental_id FK\n        decimal amount\n        datetime payment_date\n    }\n    rental {\n        int rental_id PK\n        datetime rental_date UK\n        int inventory_id FK,UK\n        int customer_id FK,UK\n        datetime return_date\n        int staff_id FK\n        datetime last_update\n    }\n    staff {\n        int staff_id PK\n        varchar first_name\n        varchar last_name\n        int address_id FK\n        int reports_to_id FK\n        varchar email\n        int store_id FK\n        bool active\n        varchar username\n        varchar password\n        datetime last_update\n        blob picture\n    }\n    store {\n        int store_id PK\n        int manager_staff_id FK,UK\n        int address_id FK\n        datetime last_update\n    }\n    actor }o--o{ film : \"[film_actor]\"\n    address }o--|| city : \"city_id\"\n    category }o--o{ film : \"[film_category]\"\n    city }o--|| country : \"country_id\"\n    customer }o--|| address : \"address_id\"\n    customer }o--|| store : \"store_id\"\n    film }o--|| language : \"language_id\"\n    film }o--|| language : \"original_language_id\"\n    film_actor }o--|| actor : \"actor_id\"\n    film_actor }o--|| film : \"film_id\"\n    film_category }o--|| category : \"category_id\"\n    film_category }o--|| film : \"film_id\"\n    inventory }o--|| film : \"film_id\"\n    inventory }o--|| store : \"store_id\"\n    payment }o--|| customer : \"customer_id\"\n    payment }o--|| rental : \"rental_id\"\n    payment }o--|| staff : \"staff_id\"\n    rental }o--|| customer : \"customer_id\"\n    rental }o--|| inventory : \"inventory_id\"\n    rental }o--|| staff : \"staff_id\"\n    staff }o--|| address : \"address_id\"\n    staff }o--|| staff : \"reports_to_id\"\n    staff }o--|| store : \"store_id\"\n    store }o--|| address : \"address_id\"\n    store }o--|| staff : \"manager_staff_id\"\n"
  },
  {
    "path": "sea-orm-sync/tests/common/setup/mod.rs",
    "content": "use pretty_assertions::assert_eq;\nuse sea_orm::{\n    ColumnTrait, ColumnType, ConnectOptions, ConnectionTrait, Database, DatabaseBackend,\n    DatabaseConnection, DbBackend, DbConn, DbErr, EntityTrait, ExecResult, Iterable, Schema,\n    Statement,\n};\nuse sea_query::{\n    SeaRc, Table, TableCreateStatement,\n    extension::postgres::{Type, TypeCreateStatement},\n};\n\npub fn setup(base_url: &str, db_name: &str) -> DatabaseConnection {\n    if cfg!(feature = \"sqlx-mysql\") {\n        let url = format!(\"{base_url}/mysql\");\n        let db = Database::connect(&url).unwrap();\n        let _drop_db_result = db.execute_raw(Statement::from_string(\n            DatabaseBackend::MySql,\n            format!(\"DROP DATABASE IF EXISTS `{db_name}`;\"),\n        ));\n\n        let _create_db_result = db.execute_raw(Statement::from_string(\n            DatabaseBackend::MySql,\n            format!(\"CREATE DATABASE `{db_name}`;\"),\n        ));\n\n        let url = format!(\"{base_url}/{db_name}\");\n        let mut options: ConnectOptions = url.into();\n        options.sqlx_logging(false);\n        Database::connect(options).unwrap()\n    } else if cfg!(feature = \"sqlx-postgres\") {\n        let url = format!(\"{base_url}/postgres\");\n        let db = Database::connect(&url).unwrap();\n        let _drop_db_result = db.execute_raw(Statement::from_string(\n            DatabaseBackend::Postgres,\n            format!(\"DROP DATABASE IF EXISTS \\\"{db_name}\\\";\"),\n        ));\n\n        let _create_db_result = db.execute_raw(Statement::from_string(\n            DatabaseBackend::Postgres,\n            format!(\"CREATE DATABASE \\\"{db_name}\\\";\"),\n        ));\n\n        let url = format!(\"{base_url}/{db_name}\");\n        let mut options: ConnectOptions = url.into();\n        options.sqlx_logging(false);\n        Database::connect(options).unwrap()\n    } else {\n        let mut options: ConnectOptions = base_url.into();\n        options.sqlx_logging(false);\n        Database::connect(options).unwrap()\n    }\n}\n\npub fn tear_down(base_url: &str, db_name: &str) {\n    if cfg!(feature = \"sqlx-mysql\") {\n        let url = format!(\"{base_url}/mysql\");\n        let db = Database::connect(&url).unwrap();\n        let _ = db.execute_raw(Statement::from_string(\n            DatabaseBackend::MySql,\n            format!(\"DROP DATABASE IF EXISTS \\\"{db_name}\\\";\"),\n        ));\n    } else if cfg!(feature = \"sqlx-postgres\") {\n        let url = format!(\"{base_url}/postgres\");\n        let db = Database::connect(&url).unwrap();\n        let _ = db.execute_raw(Statement::from_string(\n            DatabaseBackend::Postgres,\n            format!(\"DROP DATABASE IF EXISTS \\\"{db_name}\\\";\"),\n        ));\n    };\n}\n\npub fn create_enum<E>(db: &DbConn, creates: &[TypeCreateStatement], entity: E) -> Result<(), DbErr>\nwhere\n    E: EntityTrait,\n{\n    let builder = db.get_database_backend();\n    if builder == DbBackend::Postgres {\n        for col in E::Column::iter() {\n            let col_def = col.def();\n            let col_type = col_def.get_column_type();\n            if !matches!(col_type, ColumnType::Enum { .. }) {\n                continue;\n            }\n            let name = match col_type {\n                ColumnType::Enum { name, .. } => name,\n                _ => unreachable!(),\n            };\n            db.execute(Type::drop().name(name.clone()).if_exists().cascade())?;\n        }\n    }\n\n    let expect_stmts: Vec<Statement> = creates.iter().map(|stmt| builder.build(stmt)).collect();\n    let schema = Schema::new(builder);\n    let create_from_entity_stmts: Vec<Statement> = schema\n        .create_enum_from_entity(entity)\n        .iter()\n        .map(|stmt| builder.build(stmt))\n        .collect();\n\n    assert_eq!(expect_stmts, create_from_entity_stmts);\n\n    for stmt in creates.iter() {\n        db.execute(stmt)?;\n    }\n\n    Ok(())\n}\n\npub fn create_table<E>(\n    db: &DbConn,\n    create: &TableCreateStatement,\n    entity: E,\n) -> Result<ExecResult, DbErr>\nwhere\n    E: EntityTrait,\n{\n    let builder = db.get_database_backend();\n    let schema = Schema::new(builder);\n    assert_eq!(\n        builder.build(&schema.create_table_from_entity(entity)),\n        builder.build(create)\n    );\n\n    create_table_without_asserts(db, create)\n}\n\npub fn create_table_with_index<E>(\n    db: &DbConn,\n    create: &TableCreateStatement,\n    entity: E,\n) -> Result<ExecResult, DbErr>\nwhere\n    E: EntityTrait,\n{\n    let res = create_table(db, create, entity)?;\n    let backend = db.get_database_backend();\n    for stmt in Schema::new(backend).create_index_from_entity(entity) {\n        db.execute(&stmt)?;\n    }\n    Ok(res)\n}\n\npub fn create_table_from_entity<E>(db: &DbConn, entity: E) -> Result<ExecResult, DbErr>\nwhere\n    E: EntityTrait,\n{\n    let builder = db.get_database_backend();\n    let schema = Schema::new(builder);\n    let stmt = schema.create_table_from_entity(entity);\n\n    db.execute(&stmt)\n}\n\npub fn create_table_without_asserts(\n    db: &DbConn,\n    create: &TableCreateStatement,\n) -> Result<ExecResult, DbErr> {\n    let builder = db.get_database_backend();\n    if builder != DbBackend::Sqlite {\n        let stmt = Table::drop()\n            .table(create.get_table_name().unwrap().clone())\n            .if_exists()\n            .cascade()\n            .take();\n        db.execute(&stmt)?;\n    }\n    db.execute(create)\n}\n\npub fn rust_dec<T: ToString>(v: T) -> rust_decimal::Decimal {\n    use std::str::FromStr;\n    rust_decimal::Decimal::from_str(&v.to_string()).unwrap()\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/connection_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::prelude::*;\n\n#[sea_orm_macros::test]\npub fn connection_ping() {\n    let ctx = TestContext::new(\"connection_ping\");\n\n    ctx.db.ping().unwrap();\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-mysql\")]\npub fn connection_ping_closed_mysql() {\n    let ctx = std::rc::Rc::new(Box::new(TestContext::new(\"connection_ping_closed\")));\n    let ctx_ping = std::rc::Rc::clone(&ctx);\n\n    ctx.db.get_mysql_connection_pool().close();\n    assert_eq!(\n        ctx_ping.db.ping(),\n        Err(DbErr::ConnectionAcquire(ConnAcquireErr::ConnectionClosed))\n    );\n\n    let base_url = std::env::var(\"DATABASE_URL\").unwrap();\n    let mut opt = sea_orm::ConnectOptions::new(format!(\"{base_url}/connection_ping_closed\"));\n    opt\n        // The connection pool has a single connection only\n        .max_connections(1)\n        // A controlled connection acquire timeout\n        .acquire_timeout(std::time::Duration::from_secs(2));\n\n    let db = sea_orm::Database::connect(opt).unwrap();\n\n    fn transaction_blocked(db: &DatabaseConnection) {\n        let _txn = sea_orm::TransactionTrait::begin(db).unwrap();\n        // Occupy the only connection, thus forcing others fail to acquire connection\n        tokio::time::sleep(std::time::Duration::from_secs(3));\n    }\n\n    fn transaction(db: &DatabaseConnection) {\n        // Should fail to acquire\n        let txn = sea_orm::TransactionTrait::begin(db);\n        assert_eq!(\n            txn.expect_err(\"should be a time out\"),\n            crate::DbErr::ConnectionAcquire(ConnAcquireErr::Timeout)\n        )\n    }\n\n    tokio::join!(transaction_blocked(&db), transaction(&db));\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\n#[cfg(all(feature = \"sqlx-sqlite\", not(feature = \"sync\")))]\npub fn connection_ping_closed_sqlite() {\n    let ctx = std::rc::Rc::new(Box::new(TestContext::new(\"connection_ping_closed\")));\n    let ctx_ping = std::rc::Rc::clone(&ctx);\n\n    ctx.db.get_sqlite_connection_pool().close();\n    assert_eq!(\n        ctx_ping.db.ping(),\n        Err(DbErr::ConnectionAcquire(ConnAcquireErr::ConnectionClosed))\n    );\n\n    let base_url = std::env::var(\"DATABASE_URL\").unwrap();\n    let mut opt = sea_orm::ConnectOptions::new(base_url);\n    opt\n        // The connection pool has a single connection only\n        .max_connections(1)\n        // A controlled connection acquire timeout\n        .acquire_timeout(std::time::Duration::from_secs(2));\n\n    let db = sea_orm::Database::connect(opt).unwrap();\n\n    fn transaction_blocked(db: &DatabaseConnection) {\n        let _txn = sea_orm::TransactionTrait::begin(db).unwrap();\n        // Occupy the only connection, thus forcing others fail to acquire connection\n        tokio::time::sleep(std::time::Duration::from_secs(3));\n    }\n\n    fn transaction(db: &DatabaseConnection) {\n        // Should fail to acquire\n        let txn = sea_orm::TransactionTrait::begin(db);\n        assert_eq!(\n            txn.expect_err(\"should be a time out\"),\n            crate::DbErr::ConnectionAcquire(ConnAcquireErr::Timeout)\n        )\n    }\n\n    tokio::join!(transaction_blocked(&db), transaction(&db));\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-postgres\")]\npub fn connection_ping_closed_postgres() {\n    let ctx = std::rc::Rc::new(Box::new(TestContext::new(\"connection_ping_closed\")));\n    let ctx_ping = std::rc::Rc::clone(&ctx);\n\n    ctx.db.get_postgres_connection_pool().close();\n    assert_eq!(\n        ctx_ping.db.ping(),\n        Err(DbErr::ConnectionAcquire(ConnAcquireErr::ConnectionClosed))\n    );\n\n    let base_url = std::env::var(\"DATABASE_URL\").unwrap();\n    let mut opt = sea_orm::ConnectOptions::new(format!(\"{base_url}/connection_ping_closed\"));\n    opt\n        // The connection pool has a single connection only\n        .max_connections(1)\n        // A controlled connection acquire timeout\n        .acquire_timeout(std::time::Duration::from_secs(2));\n\n    let db = sea_orm::Database::connect(opt).unwrap();\n\n    fn transaction_blocked(db: &DatabaseConnection) {\n        let _txn = sea_orm::TransactionTrait::begin(db).unwrap();\n        // Occupy the only connection, thus forcing others fail to acquire connection\n        tokio::time::sleep(std::time::Duration::from_secs(3));\n    }\n\n    fn transaction(db: &DatabaseConnection) {\n        // Should fail to acquire\n        let txn = sea_orm::TransactionTrait::begin(db);\n        assert_eq!(\n            txn.expect_err(\"should be a time out\"),\n            crate::DbErr::ConnectionAcquire(ConnAcquireErr::Timeout)\n        )\n    }\n\n    tokio::join!(transaction_blocked(&db), transaction(&db));\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-postgres\")]\npub fn connection_with_search_path_postgres() {\n    let ctx = TestContext::new(\"connection_with_search_path\");\n\n    let base_url = std::env::var(\"DATABASE_URL\").unwrap();\n    let mut opt = sea_orm::ConnectOptions::new(format!(\"{base_url}/connection_with_search_path\"));\n    opt\n        // The connection pool has a single connection only\n        .max_connections(1)\n        // A controlled connection acquire timeout\n        .acquire_timeout(std::time::Duration::from_secs(2))\n        .set_schema_search_path(\"schema-with-special-characters\");\n\n    let db = sea_orm::Database::connect(opt);\n    assert!(db.is_ok());\n\n    ctx.delete();\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/crud/create_baker.rs",
    "content": "pub use super::*;\nuse serde::{Deserialize, Serialize};\n\npub fn test_create_baker(db: &DbConn) {\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .expect(\"could not insert bakery\");\n\n    #[derive(Serialize, Deserialize)]\n    struct ContactDetails {\n        mobile: String,\n        home: String,\n        address: String,\n    }\n\n    let baker_bob_contact = ContactDetails {\n        mobile: \"+61424000000\".to_owned(),\n        home: \"0395555555\".to_owned(),\n        address: \"12 Test St, Testville, Vic, Australia\".to_owned(),\n    };\n    let baker_bob = baker::ActiveModel {\n        name: Set(\"Baker Bob\".to_owned()),\n        contact_details: Set(serde_json::json!(baker_bob_contact)),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n    let res = Baker::insert(baker_bob)\n        .exec(db)\n        .expect(\"could not insert baker\");\n\n    let baker: Option<baker::Model> = Baker::find_by_id(res.last_insert_id)\n        .one(db)\n        .expect(\"could not find baker\");\n\n    assert!(baker.is_some());\n    let baker_model = baker.unwrap();\n    assert_eq!(baker_model.name, \"Baker Bob\");\n    assert_eq!(\n        baker_model.contact_details[\"mobile\"],\n        baker_bob_contact.mobile\n    );\n    assert_eq!(baker_model.contact_details[\"home\"], baker_bob_contact.home);\n    assert_eq!(\n        baker_model.contact_details[\"address\"],\n        baker_bob_contact.address\n    );\n    assert_eq!(\n        baker_model\n            .find_related(Bakery)\n            .one(db)\n            .expect(\"Bakery not found\")\n            .unwrap()\n            .name,\n        \"SeaSide Bakery\"\n    );\n\n    let bakery: Option<bakery::Model> = Bakery::find_by_id(bakery_insert_res.last_insert_id)\n        .one(db)\n        .unwrap();\n\n    let related_bakers: Vec<baker::Model> = bakery\n        .unwrap()\n        .find_related(Baker)\n        .all(db)\n        .expect(\"could not find related bakers\");\n    assert_eq!(related_bakers.len(), 1);\n    assert_eq!(related_bakers[0].name, \"Baker Bob\")\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/crud/create_cake.rs",
    "content": "pub use super::*;\nuse uuid::Uuid;\n\npub fn test_create_cake(db: &DbConn) {\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .expect(\"could not insert bakery\");\n\n    let baker_bob = baker::ActiveModel {\n        name: Set(\"Baker Bob\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n    let baker_insert_res = Baker::insert(baker_bob)\n        .exec(db)\n        .expect(\"could not insert baker\");\n    let uuid = Uuid::new_v4();\n\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(-10.25)),\n        gluten_free: Set(false),\n        serial: Set(uuid),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n\n    let cake_insert_res = Cake::insert(mud_cake)\n        .exec(db)\n        .expect(\"could not insert cake\");\n\n    let cake: Option<cake::Model> = Cake::find_by_id(cake_insert_res.last_insert_id)\n        .one(db)\n        .expect(\"could not find cake\");\n\n    let cake_baker = cakes_bakers::ActiveModel {\n        cake_id: Set(cake_insert_res.last_insert_id),\n        baker_id: Set(baker_insert_res.last_insert_id),\n    };\n    let cake_baker_res = CakesBakers::insert(cake_baker.clone())\n        .exec(db)\n        .expect(\"could not insert cake_baker\");\n    assert_eq!(\n        cake_baker_res.last_insert_id,\n        (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())\n    );\n\n    assert!(cake.is_some());\n    let cake_model = cake.unwrap();\n    assert_eq!(cake_model.name, \"Mud Cake\");\n    assert_eq!(cake_model.price, rust_dec(-10.25));\n    assert!(!cake_model.gluten_free);\n    assert_eq!(\n        cake_model\n            .find_related(Bakery)\n            .one(db)\n            .expect(\"Bakery not found\")\n            .unwrap()\n            .name,\n        \"SeaSide Bakery\"\n    );\n    assert_eq!(cake_model.serial, uuid);\n\n    let related_bakers: Vec<baker::Model> = cake_model\n        .find_related(Baker)\n        .all(db)\n        .expect(\"could not find related bakers\");\n    assert_eq!(related_bakers.len(), 1);\n    assert_eq!(related_bakers[0].name, \"Baker Bob\");\n\n    let baker: Option<baker::Model> = Baker::find_by_id(baker_insert_res.last_insert_id)\n        .one(db)\n        .expect(\"could not find baker\");\n\n    let related_cakes: Vec<cake::Model> = baker\n        .unwrap()\n        .find_related(Cake)\n        .all(db)\n        .expect(\"could not find related cakes\");\n    assert_eq!(related_cakes.len(), 1);\n    assert_eq!(related_cakes[0].name, \"Mud Cake\")\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/crud/create_lineitem.rs",
    "content": "pub use super::*;\nuse sea_orm::entity::prelude::{ChronoUtc, Uuid};\n\npub fn test_create_lineitem(db: &DbConn) {\n    // Bakery\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .expect(\"could not insert bakery\");\n\n    // Baker\n    let baker_bob = baker::ActiveModel {\n        name: Set(\"Baker Bob\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n    let baker_insert_res = Baker::insert(baker_bob)\n        .exec(db)\n        .expect(\"could not insert baker\");\n\n    // Cake\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n\n    let cake_insert_res = Cake::insert(mud_cake)\n        .exec(db)\n        .expect(\"could not insert cake\");\n\n    // Cake_Baker\n    let cake_baker = cakes_bakers::ActiveModel {\n        cake_id: Set(cake_insert_res.last_insert_id),\n        baker_id: Set(baker_insert_res.last_insert_id),\n    };\n    let cake_baker_res = CakesBakers::insert(cake_baker.clone())\n        .exec(db)\n        .expect(\"could not insert cake_baker\");\n    assert_eq!(\n        cake_baker_res.last_insert_id,\n        (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())\n    );\n\n    // Customer\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        notes: Set(Some(\"Loves cheese cake\".to_owned())),\n        ..Default::default()\n    };\n    let customer_insert_res = Customer::insert(customer_kate)\n        .exec(db)\n        .expect(\"could not insert customer\");\n\n    // Order\n    let order_1 = order::ActiveModel {\n        bakery_id: Set(bakery_insert_res.last_insert_id),\n        customer_id: Set(customer_insert_res.last_insert_id),\n        total: Set(rust_dec(7.55)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    };\n    let order_insert_res = Order::insert(order_1)\n        .exec(db)\n        .expect(\"could not insert order\");\n\n    // Lineitem\n    let lineitem_1 = lineitem::ActiveModel {\n        cake_id: Set(cake_insert_res.last_insert_id),\n        order_id: Set(order_insert_res.last_insert_id),\n        price: Set(rust_dec(7.55)),\n        quantity: Set(1),\n        ..Default::default()\n    };\n    let lineitem_insert_res = Lineitem::insert(lineitem_1)\n        .exec(db)\n        .expect(\"could not insert lineitem\");\n\n    let lineitem: Option<lineitem::Model> =\n        Lineitem::find_by_id(lineitem_insert_res.last_insert_id)\n            .one(db)\n            .expect(\"could not find lineitem\");\n\n    assert!(lineitem.is_some());\n    let lineitem_model = lineitem.unwrap();\n\n    assert_eq!(lineitem_model.price, rust_dec(7.55));\n\n    let cake: Option<cake::Model> = Cake::find_by_id(lineitem_model.cake_id)\n        .one(db)\n        .expect(\"could not find cake\");\n\n    let cake_model = cake.unwrap();\n    assert_eq!(cake_model.name, \"Mud Cake\");\n\n    let order: Option<order::Model> = Order::find_by_id(lineitem_model.order_id)\n        .one(db)\n        .expect(\"could not find order\");\n\n    let order_model = order.unwrap();\n    assert_eq!(order_model.customer_id, customer_insert_res.last_insert_id);\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/crud/create_order.rs",
    "content": "pub use super::*;\nuse sea_orm::entity::prelude::{ChronoUtc, Uuid};\n\npub fn test_create_order(db: &DbConn) {\n    // Bakery\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .expect(\"could not insert bakery\");\n\n    // Baker\n    let baker_bob = baker::ActiveModel {\n        name: Set(\"Baker Bob\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n    let baker_insert_res = Baker::insert(baker_bob)\n        .exec(db)\n        .expect(\"could not insert baker\");\n\n    // Cake\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n\n    let cake_insert_res = Cake::insert(mud_cake)\n        .exec(db)\n        .expect(\"could not insert cake\");\n\n    // Cake_Baker\n    let cake_baker = cakes_bakers::ActiveModel {\n        cake_id: Set(cake_insert_res.last_insert_id),\n        baker_id: Set(baker_insert_res.last_insert_id),\n    };\n    let cake_baker_res = CakesBakers::insert(cake_baker.clone())\n        .exec(db)\n        .expect(\"could not insert cake_baker\");\n    assert_eq!(\n        cake_baker_res.last_insert_id,\n        (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())\n    );\n\n    // Customer\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        notes: Set(Some(\"Loves cheese cake\".to_owned())),\n        ..Default::default()\n    };\n    let customer_insert_res = Customer::insert(customer_kate)\n        .exec(db)\n        .expect(\"could not insert customer\");\n\n    // Order\n    let order_1 = order::ActiveModel {\n        bakery_id: Set(bakery_insert_res.last_insert_id),\n        customer_id: Set(customer_insert_res.last_insert_id),\n        total: Set(rust_dec(15.10)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    };\n    let order_insert_res = Order::insert(order_1)\n        .exec(db)\n        .expect(\"could not insert order\");\n\n    // Lineitem\n    let lineitem_1 = lineitem::ActiveModel {\n        cake_id: Set(cake_insert_res.last_insert_id),\n        order_id: Set(order_insert_res.last_insert_id),\n        price: Set(rust_dec(7.55)),\n        quantity: Set(2),\n        ..Default::default()\n    };\n    let _lineitem_insert_res = Lineitem::insert(lineitem_1)\n        .exec(db)\n        .expect(\"could not insert lineitem\");\n\n    let order: Option<order::Model> = Order::find_by_id(order_insert_res.last_insert_id)\n        .one(db)\n        .expect(\"could not find order\");\n\n    assert!(order.is_some());\n    let order_model = order.unwrap();\n    assert_eq!(order_model.total, rust_dec(15.10));\n\n    let customer: Option<customer::Model> = Customer::find_by_id(order_model.customer_id)\n        .one(db)\n        .expect(\"could not find customer\");\n\n    let customer_model = customer.unwrap();\n    assert_eq!(customer_model.name, \"Kate\");\n\n    let bakery: Option<bakery::Model> = Bakery::find_by_id(order_model.bakery_id)\n        .one(db)\n        .expect(\"could not find bakery\");\n\n    let bakery_model = bakery.unwrap();\n    assert_eq!(bakery_model.name, \"SeaSide Bakery\");\n\n    let related_lineitems: Vec<lineitem::Model> = order_model\n        .find_related(Lineitem)\n        .all(db)\n        .expect(\"could not find related lineitems\");\n    assert_eq!(related_lineitems.len(), 1);\n    assert_eq!(related_lineitems[0].price, rust_dec(7.55));\n    assert_eq!(related_lineitems[0].quantity, 2);\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/crud/deletes.rs",
    "content": "pub use super::*;\nuse uuid::Uuid;\n\npub fn test_delete_cake(db: &DbConn) {\n    let initial_cakes = Cake::find().all(db).unwrap().len();\n\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .expect(\"could not insert bakery\");\n\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n\n    let cake = mud_cake.save(db).expect(\"could not insert cake\");\n\n    let cakes = Cake::find().all(db).unwrap();\n    assert_eq!(cakes.len(), initial_cakes + 1);\n\n    let _result = cake.delete(db).expect(\"failed to delete cake\");\n\n    let cakes = Cake::find().all(db).unwrap();\n    assert_eq!(cakes.len(), initial_cakes);\n}\n\npub fn test_delete_bakery(db: &DbConn) {\n    let initial_bakeries = Bakery::find().all(db).unwrap().len();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert bakery\");\n\n    assert_eq!(Bakery::find().all(db).unwrap().len(), initial_bakeries + 1);\n\n    let _result = bakery.delete(db).expect(\"failed to delete bakery\");\n\n    assert_eq!(Bakery::find().all(db).unwrap().len(), initial_bakeries);\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/crud/error.rs",
    "content": "pub use super::*;\nuse sea_orm::error::*;\n#[cfg(any(\n    feature = \"sqlx-mysql\",\n    feature = \"sqlx-sqlite\",\n    feature = \"sqlx-postgres\"\n))]\nuse sqlx::Error;\nuse uuid::Uuid;\n\npub fn test_cake_error_sqlx(db: &DbConn) {\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Moldy Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(None),\n        ..Default::default()\n    };\n\n    let cake = mud_cake.save(db).expect(\"could not insert cake\");\n\n    #[allow(unused_variables)]\n    let error: DbErr = cake\n        .into_active_model()\n        .insert(db)\n        .expect_err(\"inserting should fail due to duplicate primary key\");\n\n    check_error(&error);\n}\n\nfn check_error(error: &DbErr) {\n    #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n    match error {\n        DbErr::Exec(RuntimeErr::SqlxError(error)) => match std::ops::Deref::deref(error) {\n            Error::Database(e) => {\n                #[cfg(feature = \"sqlx-mysql\")]\n                assert_eq!(e.code().unwrap(), \"23000\");\n                #[cfg(feature = \"rusqlite\")]\n                assert_eq!(e.code().unwrap(), \"1555\");\n            }\n            _ => panic!(\"Unexpected sqlx-error kind\"),\n        },\n        #[cfg(all(feature = \"sqlx-sqlite\", feature = \"sqlite-use-returning-for-3_35\"))]\n        DbErr::Query(RuntimeErr::SqlxError(error)) => match std::ops::Deref::deref(error) {\n            Error::Database(e) => assert_eq!(e.code().unwrap(), \"1555\"),\n            _ => panic!(\"Unexpected sqlx-error kind\"),\n        },\n        _ => panic!(\"Unexpected Error kind\"),\n    }\n    #[cfg(feature = \"sqlx-postgres\")]\n    match error {\n        DbErr::Query(RuntimeErr::SqlxError(error)) => match std::ops::Deref::deref(error) {\n            Error::Database(e) => assert_eq!(e.code().unwrap(), \"23505\"),\n            _ => panic!(\"Unexpected sqlx-error kind\"),\n        },\n        _ => panic!(\"Unexpected Error kind\"),\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/crud/mod.rs",
    "content": "pub mod create_baker;\npub mod create_cake;\npub mod create_lineitem;\npub mod create_order;\npub mod deletes;\npub mod error;\npub mod updates;\n\npub use create_baker::*;\npub use create_cake::*;\npub use create_lineitem::*;\npub use create_order::*;\npub use deletes::*;\npub use error::*;\npub use updates::*;\n\npub use super::common::bakery_chain::*;\npub use crate::common::setup::rust_dec;\nuse sea_orm::{DbConn, entity::*};\n\npub fn test_create_bakery(db: &DbConn) {\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .expect(\"could not insert bakery\");\n\n    let bakery: Option<bakery::Model> = Bakery::find_by_id(res.last_insert_id)\n        .one(db)\n        .expect(\"could not find bakery\");\n\n    assert!(bakery.is_some());\n    let bakery_model = bakery.unwrap();\n    assert_eq!(bakery_model.name, \"SeaSide Bakery\");\n    assert!((bakery_model.profit_margin - 10.4).abs() < f64::EPSILON);\n}\n\npub fn test_create_customer(db: &DbConn) {\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        notes: Set(Some(\"Loves cheese cake\".to_owned())),\n        ..Default::default()\n    };\n    let res = Customer::insert(customer_kate)\n        .exec(db)\n        .expect(\"could not insert customer\");\n\n    let customer: Option<customer::Model> = Customer::find_by_id(res.last_insert_id)\n        .one(db)\n        .expect(\"could not find customer\");\n\n    assert!(customer.is_some());\n    let customer_model = customer.unwrap();\n    assert_eq!(customer_model.name, \"Kate\");\n    assert_eq!(customer_model.notes, Some(\"Loves cheese cake\".to_owned()));\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/crud/updates.rs",
    "content": "pub use super::*;\nuse sea_orm::{DbErr, query::*};\nuse uuid::Uuid;\n\npub fn test_update_cake(db: &DbConn) {\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .expect(\"could not insert bakery\");\n\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n\n    let cake_insert_res = Cake::insert(mud_cake)\n        .exec(db)\n        .expect(\"could not insert cake\");\n\n    let cake: Option<cake::Model> = Cake::find_by_id(cake_insert_res.last_insert_id)\n        .one(db)\n        .expect(\"could not find cake\");\n\n    assert!(cake.is_some());\n    let cake_model = cake.unwrap();\n    assert_eq!(cake_model.name, \"Mud Cake\");\n    assert_eq!(cake_model.price, rust_dec(10.25));\n    assert!(!cake_model.gluten_free);\n\n    let large_number = \"1234_5678_9012.3456\".parse().unwrap();\n\n    let mut cake_am: cake::ActiveModel = cake_model.into();\n    cake_am.name = Set(\"Extra chocolate mud cake\".to_owned());\n    cake_am.price = Set(large_number);\n\n    let _cake_update_res: cake::Model = cake_am.update(db).expect(\"could not update cake\");\n\n    let cake: Option<cake::Model> = Cake::find_by_id(cake_insert_res.last_insert_id)\n        .one(db)\n        .expect(\"could not find cake\");\n    let cake_model = cake.unwrap();\n    assert_eq!(cake_model.name, \"Extra chocolate mud cake\");\n    assert_eq!(cake_model.price, large_number);\n    assert!(!cake_model.gluten_free);\n}\n\npub fn test_update_bakery(db: &DbConn) {\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .expect(\"could not insert bakery\");\n\n    let bakery: Option<bakery::Model> = Bakery::find_by_id(bakery_insert_res.last_insert_id)\n        .one(db)\n        .expect(\"could not find bakery\");\n\n    assert!(bakery.is_some());\n    let bakery_model = bakery.unwrap();\n    assert_eq!(bakery_model.name, \"SeaSide Bakery\");\n    assert!((bakery_model.profit_margin - 10.40).abs() < f64::EPSILON);\n\n    let mut bakery_am: bakery::ActiveModel = bakery_model.into();\n    bakery_am.name = Set(\"SeaBreeze Bakery\".to_owned());\n    bakery_am.profit_margin = Set(12.00);\n\n    let _bakery_update_res: bakery::Model = bakery_am.update(db).expect(\"could not update bakery\");\n\n    let bakery: Option<bakery::Model> = Bakery::find_by_id(bakery_insert_res.last_insert_id)\n        .one(db)\n        .expect(\"could not find bakery\");\n    let bakery_model = bakery.unwrap();\n    assert_eq!(bakery_model.name, \"SeaBreeze Bakery\");\n    assert!((bakery_model.profit_margin - 12.00).abs() < f64::EPSILON);\n}\n\npub fn test_update_deleted_customer(db: &DbConn) {\n    let init_n_customers = Customer::find().count(db).unwrap();\n\n    let customer = customer::ActiveModel {\n        name: Set(\"John\".to_owned()),\n        notes: Set(None),\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert customer\");\n\n    assert_eq!(Customer::find().count(db).unwrap(), init_n_customers + 1);\n\n    let customer_id = customer.id.clone().unwrap();\n\n    let _ = customer.delete(db);\n    assert_eq!(Customer::find().count(db).unwrap(), init_n_customers);\n\n    let customer = customer::ActiveModel {\n        id: Set(customer_id),\n        name: Set(\"John 2\".to_owned()),\n        ..Default::default()\n    };\n\n    let customer_update_res = customer.update(db);\n\n    assert_eq!(customer_update_res, Err(DbErr::RecordNotUpdated));\n\n    assert_eq!(Customer::find().count(db).unwrap(), init_n_customers);\n\n    let customer: Option<customer::Model> = Customer::find_by_id(customer_id)\n        .one(db)\n        .expect(\"could not find customer\");\n\n    assert_eq!(customer, None);\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/crud_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\nmod crud;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\npub use crud::*;\nuse sea_orm::DatabaseConnection;\n\n// Run the test locally:\n// DATABASE_URL=\"sqlite::memory:\" cargo test --features rusqlite --test crud_tests\n// DATABASE_URL=\"sqlite::memory:\" cargo test --features sqlx-sqlite,runtime-tokio --test crud_tests\n// DATABASE_URL=\"mysql://sea:sea@localhost\" cargo test --features sqlx-mysql,runtime-tokio-native-tls --test crud_tests\n// DATABASE_URL=\"postgres://sea:sea@localhost\" cargo test --features sqlx-postgres,runtime-tokio-native-tls --test crud_tests\n#[sea_orm_macros::test]\nfn main() {\n    let ctx = TestContext::new(\"bakery_chain_schema_crud_tests\");\n    create_tables(&ctx.db).unwrap();\n    create_entities(&ctx.db);\n    ctx.delete();\n}\n\npub fn create_entities(db: &DatabaseConnection) {\n    test_create_bakery(db);\n    test_create_baker(db);\n    test_create_customer(db);\n    test_create_cake(db);\n    test_create_lineitem(db);\n    test_create_order(db);\n\n    test_update_cake(db);\n    test_update_bakery(db);\n    test_update_deleted_customer(db);\n\n    test_delete_cake(db);\n    test_cake_error_sqlx(db);\n    test_delete_bakery(db);\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/cursor_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DerivePartialModel, FromQueryResult, QuerySelect, Set, entity::prelude::*};\nuse sea_query::ExprTrait;\nuse serde_json::json;\n\n#[sea_orm_macros::test]\nfn cursor_tests() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"cursor_tests\");\n    create_insert_default_table(&ctx.db)?;\n    create_insert_default(&ctx.db)?;\n    cursor_pagination(&ctx.db)?;\n    bakery_chain_schema::create_bakery_table(&ctx.db)?;\n    bakery_chain_schema::create_baker_table(&ctx.db)?;\n    bakery_chain_schema::create_cake_table(&ctx.db)?;\n    bakery_chain_schema::create_cakes_bakers_table(&ctx.db)?;\n    create_baker_cake(&ctx.db)?;\n    cursor_related_pagination(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    for _ in 0..10 {\n        ActiveModel {\n            ..Default::default()\n        }\n        .insert(db)?;\n    }\n\n    assert_eq!(\n        Entity::find().all(db)?,\n        [\n            Model { id: 1 },\n            Model { id: 2 },\n            Model { id: 3 },\n            Model { id: 4 },\n            Model { id: 5 },\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    Ok(())\n}\n\npub fn cursor_pagination(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    // Before 5, i.e. id < 5\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.before(5);\n\n    assert_eq!(\n        cursor.first(4).all(db)?,\n        [\n            Model { id: 1 },\n            Model { id: 2 },\n            Model { id: 3 },\n            Model { id: 4 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(5).all(db)?,\n        [\n            Model { id: 1 },\n            Model { id: 2 },\n            Model { id: 3 },\n            Model { id: 4 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(4).all(db)?,\n        [\n            Model { id: 1 },\n            Model { id: 2 },\n            Model { id: 3 },\n            Model { id: 4 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(5).all(db)?,\n        [\n            Model { id: 1 },\n            Model { id: 2 },\n            Model { id: 3 },\n            Model { id: 4 },\n        ]\n    );\n\n    // Before 5 DESC, i.e. id > 5\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.before(5).desc();\n\n    assert_eq!(\n        cursor.first(4).all(db)?,\n        [\n            Model { id: 10 },\n            Model { id: 9 },\n            Model { id: 8 },\n            Model { id: 7 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(5).all(db)?,\n        [\n            Model { id: 10 },\n            Model { id: 9 },\n            Model { id: 8 },\n            Model { id: 7 },\n            Model { id: 6 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(4).all(db)?,\n        [\n            Model { id: 9 },\n            Model { id: 8 },\n            Model { id: 7 },\n            Model { id: 6 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(5).all(db)?,\n        [\n            Model { id: 10 },\n            Model { id: 9 },\n            Model { id: 8 },\n            Model { id: 7 },\n            Model { id: 6 },\n        ]\n    );\n\n    // After 5, i.e. id > 5\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(5);\n\n    assert_eq!(\n        cursor.first(4).all(db)?,\n        [\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(5).all(db)?,\n        [\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(6).all(db)?,\n        [\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(4).all(db)?,\n        [\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(5).all(db)?,\n        [\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(6).all(db)?,\n        [\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    // After 5 DESC, i.e. id < 5\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(5).desc();\n\n    assert_eq!(\n        cursor.first(3).all(db)?,\n        [Model { id: 4 }, Model { id: 3 }, Model { id: 2 },]\n    );\n\n    assert_eq!(\n        cursor.first(4).all(db)?,\n        [\n            Model { id: 4 },\n            Model { id: 3 },\n            Model { id: 2 },\n            Model { id: 1 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(5).all(db)?,\n        [\n            Model { id: 4 },\n            Model { id: 3 },\n            Model { id: 2 },\n            Model { id: 1 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(3).all(db)?,\n        [Model { id: 3 }, Model { id: 2 }, Model { id: 1 },]\n    );\n\n    assert_eq!(\n        cursor.last(4).all(db)?,\n        [\n            Model { id: 4 },\n            Model { id: 3 },\n            Model { id: 2 },\n            Model { id: 1 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(5).all(db)?,\n        [\n            Model { id: 4 },\n            Model { id: 3 },\n            Model { id: 2 },\n            Model { id: 1 },\n        ]\n    );\n\n    // Between 5 and 8, i.e. id > 5 AND id < 8\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(5).before(8);\n\n    assert_eq!(cursor.first(1).all(db)?, [Model { id: 6 }]);\n\n    assert_eq!(cursor.first(2).all(db)?, [Model { id: 6 }, Model { id: 7 }]);\n\n    assert_eq!(cursor.first(3).all(db)?, [Model { id: 6 }, Model { id: 7 }]);\n\n    assert_eq!(cursor.last(1).all(db)?, [Model { id: 7 }]);\n\n    assert_eq!(cursor.last(2).all(db)?, [Model { id: 6 }, Model { id: 7 }]);\n\n    assert_eq!(cursor.last(3).all(db)?, [Model { id: 6 }, Model { id: 7 }]);\n\n    // Between 8 and 5 DESC, i.e. id < 8 AND id > 5\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(8).before(5).desc();\n\n    assert_eq!(cursor.first(1).all(db)?, [Model { id: 7 }]);\n\n    assert_eq!(cursor.first(2).all(db)?, [Model { id: 7 }, Model { id: 6 }]);\n\n    assert_eq!(cursor.first(3).all(db)?, [Model { id: 7 }, Model { id: 6 }]);\n\n    assert_eq!(cursor.last(1).all(db)?, [Model { id: 6 }]);\n\n    assert_eq!(cursor.last(2).all(db)?, [Model { id: 7 }, Model { id: 6 }]);\n\n    assert_eq!(cursor.last(3).all(db)?, [Model { id: 7 }, Model { id: 6 }]);\n\n    // Ensure asc/desc order can be changed\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.first(2);\n\n    assert_eq!(cursor.all(db)?, [Model { id: 1 }, Model { id: 2 },]);\n\n    assert_eq!(cursor.asc().all(db)?, [Model { id: 1 }, Model { id: 2 },]);\n\n    assert_eq!(cursor.desc().all(db)?, [Model { id: 10 }, Model { id: 9 },]);\n\n    assert_eq!(cursor.asc().all(db)?, [Model { id: 1 }, Model { id: 2 },]);\n\n    assert_eq!(cursor.desc().all(db)?, [Model { id: 10 }, Model { id: 9 },]);\n\n    // Fetch custom struct\n\n    #[derive(FromQueryResult, Debug, PartialEq, Clone)]\n    struct Row {\n        id: i32,\n    }\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(5).before(8);\n\n    let mut cursor = cursor.into_model::<Row>();\n\n    assert_eq!(cursor.first(2).all(db)?, [Row { id: 6 }, Row { id: 7 }]);\n\n    assert_eq!(cursor.first(3).all(db)?, [Row { id: 6 }, Row { id: 7 }]);\n\n    // Fetch custom struct desc\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(8).before(5).desc();\n\n    let mut cursor = cursor.into_model::<Row>();\n\n    assert_eq!(cursor.first(2).all(db)?, [Row { id: 7 }, Row { id: 6 }]);\n\n    assert_eq!(cursor.first(3).all(db)?, [Row { id: 7 }, Row { id: 6 }]);\n\n    // Fetch JSON value\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(5).before(8);\n\n    let mut cursor = cursor.into_json();\n\n    assert_eq!(\n        cursor.first(2).all(db)?,\n        [json!({ \"id\": 6 }), json!({ \"id\": 7 })]\n    );\n\n    assert_eq!(\n        cursor.first(3).all(db)?,\n        [json!({ \"id\": 6 }), json!({ \"id\": 7 })]\n    );\n\n    #[derive(DerivePartialModel, Debug, PartialEq, Clone)]\n    #[sea_orm(entity = \"Entity\")]\n    struct PartialRow {\n        #[sea_orm(from_col = \"id\")]\n        id: i32,\n        #[sea_orm(from_expr = \"sea_query::Expr::col(Column::Id).add(1000)\")]\n        id_shifted: i32,\n    }\n\n    let mut cursor = cursor.into_partial_model::<PartialRow>();\n\n    assert_eq!(\n        cursor.first(2).all(db)?,\n        [\n            PartialRow {\n                id: 6,\n                id_shifted: 1006,\n            },\n            PartialRow {\n                id: 7,\n                id_shifted: 1007,\n            }\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(3).all(db)?,\n        [\n            PartialRow {\n                id: 6,\n                id_shifted: 1006,\n            },\n            PartialRow {\n                id: 7,\n                id_shifted: 1007,\n            }\n        ]\n    );\n\n    // Fetch JSON value desc\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(8).before(5).desc();\n\n    let mut cursor = cursor.into_json();\n\n    assert_eq!(\n        cursor.first(2).all(db)?,\n        [json!({ \"id\": 7 }), json!({ \"id\": 6 })]\n    );\n\n    assert_eq!(\n        cursor.first(3).all(db)?,\n        [json!({ \"id\": 7 }), json!({ \"id\": 6 })]\n    );\n\n    let mut cursor = cursor.into_partial_model::<PartialRow>();\n\n    assert_eq!(\n        cursor.first(2).all(db)?,\n        [\n            PartialRow {\n                id: 7,\n                id_shifted: 1007,\n            },\n            PartialRow {\n                id: 6,\n                id_shifted: 1006,\n            }\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(3).all(db)?,\n        [\n            PartialRow {\n                id: 7,\n                id_shifted: 1007,\n            },\n            PartialRow {\n                id: 6,\n                id_shifted: 1006,\n            },\n        ]\n    );\n\n    Ok(())\n}\n\nuse common::bakery_chain::{\n    Baker, Bakery, Cake, CakesBakers, baker, bakery, cake, cakes_bakers,\n    schema as bakery_chain_schema,\n};\n\nfn bakery(i: i32) -> bakery::Model {\n    bakery::Model {\n        name: i.to_string(),\n        profit_margin: 10.4,\n        id: i,\n    }\n}\n\nfn baker(c: char) -> baker::Model {\n    baker::Model {\n        name: c.clone().to_string(),\n        contact_details: serde_json::json!({\n            \"mobile\": \"+61424000000\",\n        }),\n        bakery_id: Some((c as i32 - 65) % 10 + 1),\n        id: c as i32 - 64,\n    }\n}\n\n#[derive(Debug, FromQueryResult, PartialEq)]\npub struct CakeBakerlite {\n    pub cake_name: String,\n    pub cake_id: i32,\n    pub baker_name: String,\n}\n\nfn cakebaker(cake: char, baker: char) -> CakeBakerlite {\n    CakeBakerlite {\n        cake_name: cake.to_string(),\n        cake_id: cake as i32 - 96,\n        baker_name: baker.to_string(),\n    }\n}\n\npub fn create_baker_cake(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let mut bakeries: Vec<bakery::ActiveModel> = vec![];\n    // bakeries named from 1 to 10\n    for i in 1..=10 {\n        bakeries.push(bakery::ActiveModel {\n            name: Set(i.to_string()),\n            profit_margin: Set(10.4),\n            ..Default::default()\n        });\n    }\n    let _ = Bakery::insert_many(bakeries).exec(db)?;\n\n    let mut bakers: Vec<baker::ActiveModel> = vec![];\n    let mut cakes: Vec<cake::ActiveModel> = vec![];\n    let mut cakes_bakers: Vec<cakes_bakers::ActiveModel> = vec![];\n    // baker and cakes named from \"A\" to \"Z\" and from \"a\" to \"z\"\n    for c in 'A'..='Z' {\n        bakers.push(baker::ActiveModel {\n            name: Set(c.clone().to_string()),\n            contact_details: Set(serde_json::json!({\n                \"mobile\": \"+61424000000\",\n            })),\n            bakery_id: Set(Some((c as i32 - 65) % 10 + 1)),\n            ..Default::default()\n        });\n        cakes.push(cake::ActiveModel {\n            name: Set(c.to_ascii_lowercase().to_string()),\n            price: Set(rust_dec(10.25)),\n            gluten_free: Set(false),\n            serial: Set(Uuid::new_v4()),\n            bakery_id: Set(Some((c as i32 - 65) % 10 + 1)),\n            ..Default::default()\n        });\n        cakes_bakers.push(cakes_bakers::ActiveModel {\n            cake_id: Set(c as i32 - 64),\n            baker_id: Set(c as i32 - 64),\n        })\n    }\n    cakes_bakers.append(\n        vec![\n            cakes_bakers::ActiveModel {\n                cake_id: Set(2),\n                baker_id: Set(1),\n            },\n            cakes_bakers::ActiveModel {\n                cake_id: Set(1),\n                baker_id: Set(2),\n            },\n        ]\n        .as_mut(),\n    );\n    Baker::insert_many(bakers).exec(db)?;\n    Cake::insert_many(cakes).exec(db)?;\n    CakesBakers::insert_many(cakes_bakers).exec(db)?;\n\n    Ok(())\n}\n\npub fn cursor_related_pagination(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use common::bakery_chain::*;\n\n    assert_eq!(\n        bakery::Entity::find()\n            .cursor_by(bakery::Column::Id)\n            .before(5)\n            .first(4)\n            .all(db)?,\n        [bakery(1), bakery(2), bakery(3), bakery(4),]\n    );\n\n    assert_eq!(\n        bakery::Entity::find()\n            .cursor_by(bakery::Column::Id)\n            .before(5)\n            .first(4)\n            .desc()\n            .all(db)?,\n        [bakery(10), bakery(9), bakery(8), bakery(7),]\n    );\n\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Id)\n            .before(5)\n            .first(20)\n            .all(db)?,\n        [\n            (bakery(1), Some(baker('A'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(2), Some(baker('B'))),\n            (bakery(2), Some(baker('L'))),\n            (bakery(2), Some(baker('V'))),\n            (bakery(3), Some(baker('C'))),\n            (bakery(3), Some(baker('M'))),\n            (bakery(3), Some(baker('W'))),\n            (bakery(4), Some(baker('D'))),\n            (bakery(4), Some(baker('N'))),\n            (bakery(4), Some(baker('X'))),\n        ]\n    );\n\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Id)\n            .after(5)\n            .last(20)\n            .desc()\n            .all(db)?,\n        [\n            (bakery(4), Some(baker('X'))),\n            (bakery(4), Some(baker('N'))),\n            (bakery(4), Some(baker('D'))),\n            (bakery(3), Some(baker('W'))),\n            (bakery(3), Some(baker('M'))),\n            (bakery(3), Some(baker('C'))),\n            (bakery(2), Some(baker('V'))),\n            (bakery(2), Some(baker('L'))),\n            (bakery(2), Some(baker('B'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('A'))),\n        ]\n    );\n\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Id)\n            .before(5)\n            .first(4)\n            .all(db)?,\n        [\n            (bakery(1), Some(baker('A'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(2), Some(baker('B'))),\n        ]\n    );\n\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Id)\n            .after(5)\n            .last(4)\n            .desc()\n            .all(db)?,\n        [\n            (bakery(2), Some(baker('B'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('A'))),\n        ]\n    );\n\n    // since \"10\" is before \"2\" lexicologically, it return that first\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Name)\n            .after(\"3\")\n            .last(4)\n            .desc()\n            .all(db)?,\n        [\n            (bakery(10), Some(baker('J'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('A'))),\n        ]\n    );\n\n    // since \"10\" is before \"2\" lexicologically, it return that first\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Name)\n            .before(\"3\")\n            .first(4)\n            .all(db)?,\n        [\n            (bakery(1), Some(baker('A'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(10), Some(baker('J'))),\n        ]\n    );\n\n    // since \"10\" is before \"2\" lexicologically, it return that first\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Name)\n            .after(\"3\")\n            .last(4)\n            .desc()\n            .all(db)?,\n        [\n            (bakery(10), Some(baker('J'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('A'))),\n        ]\n    );\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n    enum QueryAs {\n        CakeId,\n        CakeName,\n        BakerName,\n    }\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by(cake::Column::Name)\n            .before(\"e\")\n            .first(4)\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)?,\n        vec![\n            cakebaker('a', 'A'),\n            cakebaker('a', 'B'),\n            cakebaker('b', 'A'),\n            cakebaker('b', 'B')\n        ]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by(cake::Column::Name)\n            .after(\"e\")\n            .last(4)\n            .desc()\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)?,\n        vec![\n            cakebaker('b', 'B'),\n            cakebaker('b', 'A'),\n            cakebaker('a', 'B'),\n            cakebaker('a', 'A')\n        ]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by(cake::Column::Name)\n            .before(\"b\")\n            .first(4)\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)?,\n        vec![cakebaker('a', 'A'), cakebaker('a', 'B')]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by(cake::Column::Name)\n            .after(\"b\")\n            .last(4)\n            .desc()\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)?,\n        vec![cakebaker('a', 'B'), cakebaker('a', 'A')]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by_other(baker::Column::Name)\n            .before(\"B\")\n            .first(4)\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)?,\n        vec![cakebaker('a', 'A'), cakebaker('b', 'A'),]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by_other(baker::Column::Name)\n            .after(\"B\")\n            .last(4)\n            .desc()\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)?,\n        vec![cakebaker('b', 'A'), cakebaker('a', 'A'),]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by_other(baker::Column::Name)\n            .before(\"E\")\n            .first(20)\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)?,\n        vec![\n            cakebaker('a', 'A'),\n            cakebaker('b', 'A'),\n            cakebaker('a', 'B'),\n            cakebaker('b', 'B'),\n            cakebaker('c', 'C'),\n            cakebaker('d', 'D'),\n        ]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by_other(baker::Column::Name)\n            .after(\"E\")\n            .last(20)\n            .desc()\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)?,\n        vec![\n            cakebaker('d', 'D'),\n            cakebaker('c', 'C'),\n            cakebaker('b', 'B'),\n            cakebaker('a', 'B'),\n            cakebaker('b', 'A'),\n            cakebaker('a', 'A'),\n        ]\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/database_executor_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseExecutor, IntoDatabaseExecutor, Set, TransactionTrait, prelude::*};\n\n#[sea_orm_macros::test]\npub fn connection_or_transaction_from_connection() {\n    let ctx = TestContext::new(\"connection_or_transaction_from_connection\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let cot = DatabaseExecutor::from(&ctx.db);\n\n    bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&cot)\n    .unwrap();\n\n    let bakeries = Bakery::find().all(&cot).unwrap();\n    assert_eq!(bakeries.len(), 1);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn connection_or_transaction_from_transaction() {\n    let ctx = TestContext::new(\"connection_or_transaction_from_transaction\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let txn = ctx.db.begin().unwrap();\n    let cot = DatabaseExecutor::from(&txn);\n\n    bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&cot)\n    .unwrap();\n\n    let bakeries = Bakery::find().all(&cot).unwrap();\n    assert_eq!(bakeries.len(), 1);\n\n    txn.commit().unwrap();\n\n    let bakeries = Bakery::find().all(&ctx.db).unwrap();\n    assert_eq!(bakeries.len(), 1);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn connection_or_transaction_begin() {\n    let ctx = TestContext::new(\"connection_or_transaction_begin\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let cot = DatabaseExecutor::from(&ctx.db);\n    let txn = cot.begin().unwrap();\n\n    bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&txn)\n    .unwrap();\n\n    let bakeries = Bakery::find().all(&txn).unwrap();\n    assert_eq!(bakeries.len(), 1);\n\n    txn.commit().unwrap();\n\n    let bakeries = Bakery::find().all(&ctx.db).unwrap();\n    assert_eq!(bakeries.len(), 1);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn connection_or_transaction_nested() {\n    let ctx = TestContext::new(\"connection_or_transaction_nested\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let txn = ctx.db.begin().unwrap();\n    let cot = DatabaseExecutor::from(&txn);\n\n    bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&cot)\n    .unwrap();\n\n    // Begin nested transaction from DatabaseExecutor\n    let nested_txn = cot.begin().unwrap();\n\n    bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&nested_txn)\n    .unwrap();\n\n    let bakeries = Bakery::find().all(&nested_txn).unwrap();\n    assert_eq!(bakeries.len(), 2);\n\n    nested_txn.commit().unwrap();\n    txn.commit().unwrap();\n\n    let bakeries = Bakery::find().all(&ctx.db).unwrap();\n    assert_eq!(bakeries.len(), 2);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn connection_or_transaction_rollback() {\n    let ctx = TestContext::new(\"connection_or_transaction_rollback\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    {\n        let txn = ctx.db.begin().unwrap();\n        let cot = DatabaseExecutor::from(&txn);\n\n        bakery::ActiveModel {\n            name: Set(\"SeaSide Bakery\".to_owned()),\n            profit_margin: Set(10.4),\n            ..Default::default()\n        }\n        .save(&cot)\n        .unwrap();\n\n        let bakeries = Bakery::find().all(&cot).unwrap();\n        assert_eq!(bakeries.len(), 1);\n\n        // Transaction dropped without commit - should rollback\n    }\n\n    let bakeries = Bakery::find().all(&ctx.db).unwrap();\n    assert_eq!(bakeries.len(), 0);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn into_database_executor_trait() {\n    let ctx = TestContext::new(\"into_database_executor_trait\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    fn save_bakery<'c, C>(db: C, name: &str) -> Result<(), DbErr>\n    where\n        C: IntoDatabaseExecutor<'c>,\n    {\n        let db = db.into_database_executor();\n        bakery::ActiveModel {\n            name: Set(name.to_owned()),\n            profit_margin: Set(10.0),\n            ..Default::default()\n        }\n        .save(&db)?;\n        Ok(())\n    }\n\n    // Test with connection\n    save_bakery(&ctx.db, \"Bakery 1\").unwrap();\n\n    // Test with transaction\n    let txn = ctx.db.begin().unwrap();\n    save_bakery(&txn, \"Bakery 2\").unwrap();\n    txn.commit().unwrap();\n\n    let bakeries = Bakery::find().all(&ctx.db).unwrap();\n    assert_eq!(bakeries.len(), 2);\n\n    ctx.delete();\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/delete_by_id_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\npub use common::{TestContext, features::*, setup::*};\nuse sea_orm::{DatabaseConnection, IntoActiveModel, entity::prelude::*};\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"delete_by_id_tests\");\n    create_log_table(&ctx.db)?;\n    create_and_delete_applog(&ctx.db)?;\n\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn create_and_delete_applog(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let log1 = applog::Model {\n        id: 1,\n        action: \"Testing\".to_owned(),\n        json: Json::String(\"HI\".to_owned()),\n        created_at: \"2021-09-17T17:50:20+08:00\".parse().unwrap(),\n    };\n\n    Applog::insert(log1.clone().into_active_model()).exec(db)?;\n\n    let log2 = applog::Model {\n        id: 2,\n        action: \"Tests\".to_owned(),\n        json: Json::String(\"HELLO\".to_owned()),\n        created_at: \"2022-09-17T17:50:20+08:00\".parse().unwrap(),\n    };\n\n    Applog::insert(log2.clone().into_active_model()).exec(db)?;\n\n    let delete_res = Applog::delete_by_id(2).exec(db)?;\n    assert_eq!(delete_res.rows_affected, 1);\n\n    let find_res = Applog::find_by_id(1).all(db)?;\n    assert_eq!(find_res, [log1]);\n\n    let find_res = Applog::find_by_id(2).all(db)?;\n    assert_eq!(find_res, []);\n\n    let delete_res = Applog::delete_by_id(3).exec(db)?;\n    assert_eq!(delete_res.rows_affected, 0);\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/derive_iden_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\npub use common::{TestContext, features::*, setup::*};\nuse sea_orm::entity::prelude::*;\n\n#[derive(DeriveIden)]\npub enum ClassName {\n    Table,\n    Id,\n    Title,\n    Text,\n}\n\n#[derive(DeriveIden)]\npub enum Book {\n    #[sea_orm(iden = \"book_table\")]\n    Table,\n    Id,\n    #[sea_orm(iden = \"turtle\")]\n    Title,\n    #[sea_orm(iden = \"TeXt\")]\n    Text,\n    #[sea_orm(iden = \"ty_pe\")]\n    Type,\n}\n\n#[derive(DeriveIden)]\nstruct GlyphToken;\n\n#[derive(DeriveIden)]\n#[sea_orm(iden = \"weRd\")]\nstruct Word;\n\n#[test]\nfn main() -> Result<(), DbErr> {\n    assert_eq!(ClassName::Table.to_string(), \"class_name\");\n    assert_eq!(ClassName::Id.to_string(), \"id\");\n    assert_eq!(ClassName::Title.to_string(), \"title\");\n    assert_eq!(ClassName::Text.to_string(), \"text\");\n\n    assert_eq!(Book::Id.to_string(), \"id\");\n    assert_eq!(Book::Table.to_string(), \"book_table\");\n    assert_eq!(Book::Title.to_string(), \"turtle\");\n    assert_eq!(Book::Text.to_string(), \"TeXt\");\n    assert_eq!(Book::Type.to_string(), \"ty_pe\");\n\n    assert_eq!(GlyphToken.to_string(), \"glyph_token\");\n\n    assert_eq!(Word.to_string(), \"weRd\");\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/derive_model_tests.rs",
    "content": "use sea_orm::prelude::{HasMany, HasOne};\n\nmod cake {\n    use sea_orm::prelude::*;\n    use serde::Serialize;\n\n    #[sea_orm::model]\n    #[derive(DeriveEntityModel, Debug, Clone, Serialize)]\n    #[sea_orm(table_name = \"cake\")]\n    #[sea_orm(model_attrs(serde(rename_all = \"UPPERCASE\")))]\n    #[sea_orm(model_ex_attrs(serde(rename_all = \"PascalCase\")))]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(has_many)]\n        pub fruits: HasMany<super::fruit::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod fruit {\n    use sea_orm::prelude::*;\n    use serde::Serialize;\n\n    #[sea_orm::model]\n    #[derive(DeriveEntityModel, Debug, Clone)]\n    #[sea_orm(\n        table_name = \"fruit\",\n        model_attrs(derive(Serialize), serde(rename_all = \"UPPERCASE\")),\n        model_ex_attrs(derive(Serialize), serde(rename_all = \"PascalCase\"))\n    )]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub cake_id: Option<i32>,\n        #[sea_orm(belongs_to, from = \"cake_id\", to = \"id\")]\n        pub cake: HasOne<super::cake::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[test]\nfn main() -> Result<(), serde_json::Error> {\n    use sea_orm::EntityName;\n    assert_eq!(cake::Entity.table_name(), \"cake\");\n    assert_eq!(fruit::Entity.table_name(), \"fruit\");\n\n    assert_eq!(serde_json::to_string(&cake::Model { id: 1 })?, \"{\\\"ID\\\":1}\");\n    assert_eq!(\n        serde_json::to_string(&cake::ModelEx {\n            id: 1,\n            fruits: HasMany::Loaded(Vec::new()),\n        })?,\n        \"{\\\"Id\\\":1,\\\"Fruits\\\":[]}\"\n    );\n\n    assert_eq!(\n        serde_json::to_string(&fruit::Model {\n            id: 2,\n            cake_id: Some(1)\n        })?,\n        \"{\\\"ID\\\":2,\\\"CAKE_ID\\\":1}\"\n    );\n    assert_eq!(\n        serde_json::to_string(&fruit::ModelEx {\n            id: 2,\n            cake_id: Some(1),\n            cake: HasOne::Unloaded,\n        })?,\n        \"{\\\"Id\\\":2,\\\"CakeId\\\":1,\\\"Cake\\\":null}\"\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/derive_tests.rs",
    "content": "use sea_orm::{FromQueryResult, TryGetable};\n\n#[derive(FromQueryResult)]\nstruct SimpleTest {\n    _foo: i32,\n    _bar: String,\n}\n\n#[derive(FromQueryResult)]\nstruct GenericTest<T: TryGetable> {\n    _foo: i32,\n    _bar: T,\n}\n\n#[derive(FromQueryResult)]\nstruct DoubleGenericTest<T: TryGetable, F: TryGetable> {\n    _foo: T,\n    _bar: F,\n}\n\n#[derive(FromQueryResult)]\nstruct BoundsGenericTest<T: TryGetable + Copy + Clone + 'static> {\n    _foo: T,\n}\n\n#[derive(FromQueryResult)]\nstruct WhereGenericTest<T>\nwhere\n    T: TryGetable + Copy + Clone + 'static,\n{\n    _foo: T,\n}\n\n#[derive(FromQueryResult)]\nstruct AlreadySpecifiedBoundsGenericTest<T: TryGetable> {\n    _foo: T,\n}\n\n#[derive(FromQueryResult)]\nstruct MixedGenericTest<T: TryGetable + Clone, F>\nwhere\n    F: TryGetable + Copy + Clone + 'static,\n{\n    _foo: T,\n    _bar: F,\n}\n\ntrait MyTrait {\n    type Item: TryGetable;\n}\n\n#[derive(FromQueryResult)]\nstruct TraitAssociateTypeTest<T>\nwhere\n    T: MyTrait,\n{\n    _foo: T::Item,\n}\n\n#[derive(FromQueryResult)]\nstruct FromQueryAttributeTests {\n    #[sea_orm(skip)]\n    _foo: i32,\n    _bar: String,\n}\n\n#[derive(FromQueryResult)]\nstruct FromQueryResultNested {\n    #[sea_orm(nested)]\n    _test: SimpleTest,\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/dyn_table_name_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{\n    DatabaseConnection, Delete, IntoActiveModel, Iterable, QueryTrait, Set, Update,\n    entity::prelude::*,\n};\nuse sea_query::{Expr, ExprTrait, Query};\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"dyn_table_name_tests\");\n    create_dyn_table_name_lazy_static_table(&ctx.db)?;\n    dyn_table_name(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn dyn_table_name(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use dyn_table_name::*;\n\n    for i in 1..=2 {\n        let entity = Entity {\n            table_name: i as u32,\n        };\n        let model = Model {\n            id: 1,\n            name: \"1st Row\".into(),\n        };\n        // Prepare insert statement\n        let mut insert = Entity::insert(model.clone().into_active_model());\n        // Reset the table name of insert statement\n        insert.query().into_table(entity.table_ref());\n        // Execute the insert statement\n        assert_eq!(insert.exec(db)?.last_insert_id, 1);\n\n        // Prepare select statement\n        let mut select = Entity::find();\n        // Override the select statement\n        *QueryTrait::query(&mut select) = Query::select()\n            .exprs(Column::iter().map(|col| col.select_as(Expr::col(col))))\n            .from(entity.table_ref())\n            .to_owned();\n        // Execute the select statement\n        assert_eq!(select.clone().one(db)?, Some(model.clone()));\n\n        // Prepare update statement\n        let update = Update::many(entity).set(ActiveModel {\n            name: Set(\"1st Row (edited)\".into()),\n            ..model.clone().into_active_model()\n        });\n        // Execute the update statement\n        assert_eq!(update.exec(db)?.rows_affected, 1);\n\n        assert_eq!(\n            select.clone().one(db)?,\n            Some(Model {\n                id: 1,\n                name: \"1st Row (edited)\".into(),\n            })\n        );\n\n        // Prepare delete statement\n        let delete = Delete::many(entity).filter(Expr::col(Column::Id).eq(1));\n        // Execute the delete statement\n        assert_eq!(delete.exec(db)?.rows_affected, 1);\n        assert_eq!(select.one(db)?, None);\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/embedding_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, DerivePartialModel, entity::prelude::*, entity::*};\nuse serde_json::json;\n\n#[cfg(feature = \"postgres-vector\")]\nmod test {\n\n    #[sea_orm_macros::test]\n    fn main() -> Result<(), DbErr> {\n        let ctx = TestContext::new(\"embedding_tests\");\n        create_embedding_table(&ctx.db)?;\n        insert_embedding(&ctx.db)?;\n        update_embedding(&ctx.db)?;\n        select_embedding(&ctx.db)?;\n        ctx.delete();\n\n        Ok(())\n    }\n\n    pub fn insert_embedding(db: &DatabaseConnection) -> Result<(), DbErr> {\n        use embedding::*;\n\n        assert_eq!(\n            Model {\n                id: 1,\n                embedding: PgVector::from(vec![1.]),\n            }\n            .into_active_model()\n            .insert(db)?,\n            Model {\n                id: 1,\n                embedding: PgVector::from(vec![1.]),\n            }\n        );\n\n        assert_eq!(\n            Model {\n                id: 2,\n                embedding: PgVector::from(vec![1., 2.]),\n            }\n            .into_active_model()\n            .insert(db)?,\n            Model {\n                id: 2,\n                embedding: PgVector::from(vec![1., 2.]),\n            }\n        );\n\n        assert_eq!(\n            Model {\n                id: 3,\n                embedding: PgVector::from(vec![1., 2., 3.]),\n            }\n            .into_active_model()\n            .insert(db)?,\n            Model {\n                id: 3,\n                embedding: PgVector::from(vec![1., 2., 3.]),\n            }\n        );\n\n        assert_eq!(\n            Entity::find_by_id(3).into_json().one(db)?,\n            Some(json!({\n                \"id\": 3,\n                \"embedding\": [1., 2., 3.],\n            }))\n        );\n\n        Ok(())\n    }\n\n    pub fn update_embedding(db: &DatabaseConnection) -> Result<(), DbErr> {\n        use embedding::*;\n\n        let model = Entity::find_by_id(1).one(db)?.unwrap();\n\n        ActiveModel {\n            embedding: Set(PgVector::from(vec![10.])),\n            ..model.into_active_model()\n        }\n        .update(db)?;\n\n        ActiveModel {\n            id: Unchanged(3),\n            embedding: Set(PgVector::from(vec![10., 20., 30.])),\n        }\n        .update(db)?;\n\n        Ok(())\n    }\n\n    pub fn select_embedding(db: &DatabaseConnection) -> Result<(), DbErr> {\n        use embedding::*;\n\n        #[derive(DerivePartialModel, Debug, PartialEq)]\n        #[sea_orm(entity = \"Entity\")]\n        struct PartialSelectResult {\n            embedding: PgVector,\n        }\n\n        let result = Entity::find_by_id(1)\n            .into_partial_model::<PartialSelectResult>()\n            .one(db)?;\n\n        assert_eq!(\n            result,\n            Some(PartialSelectResult {\n                embedding: PgVector::from(vec![10.]),\n            })\n        );\n\n        let result = Entity::find_by_id(2)\n            .into_partial_model::<PartialSelectResult>()\n            .one(db)?;\n\n        assert_eq!(\n            result,\n            Some(PartialSelectResult {\n                embedding: PgVector::from(vec![1., 2.]),\n            })\n        );\n\n        let result = Entity::find_by_id(3)\n            .into_partial_model::<PartialSelectResult>()\n            .one(db)?;\n\n        assert_eq!(\n            result,\n            Some(PartialSelectResult {\n                embedding: PgVector::from(vec![10., 20., 30.]),\n            })\n        );\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/empty_insert_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\nmod crud;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\npub use sea_orm::{\n    DatabaseConnection, DbBackend, EntityName, ExecResult, entity::*, error::DbErr, tests_cfg,\n};\n\npub use crud::*;\n// use common::bakery_chain::*;\nuse sea_orm::{DbConn, TryInsertResult};\n\n#[sea_orm_macros::test]\nfn main() {\n    let ctx = TestContext::new(\"bakery_chain_empty_insert_tests\");\n    create_bakery_table(&ctx.db).unwrap();\n    test(&ctx.db);\n    ctx.delete();\n}\n\npub fn test(db: &DbConn) {\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n\n    let res = Bakery::insert(seaside_bakery).exec(db);\n\n    assert!(res.is_ok());\n\n    let double_seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        id: Set(1),\n        ..Default::default()\n    };\n\n    let conflict_insert = Bakery::insert_many([double_seaside_bakery])\n        .on_conflict_do_nothing()\n        .exec(db);\n\n    assert!(matches!(conflict_insert, Ok(TryInsertResult::Conflicted)));\n\n    let empty_insert = Bakery::insert_many(std::iter::empty::<bakery::ActiveModel>())\n        .exec(db)\n        .unwrap();\n\n    assert!(empty_insert.last_insert_id.is_none());\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/entity_loader_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{\n    TestContext,\n    bakery_chain::{create_tables, seed_data},\n    bakery_dense::*,\n    setup::*,\n};\nuse sea_orm::{DbConn, DbErr, EntityLoaderTrait, RuntimeErr, Set, prelude::*, query::*};\n\n#[sea_orm_macros::test]\nfn cake_entity_loader() -> Result<(), DbErr> {\n    use common::bakery_dense::prelude::*;\n    use sea_orm::compound::EntityLoaderTrait;\n\n    let ctx = TestContext::new(\"test_cake_entity_loader\");\n    let db = &ctx.db;\n    create_tables(db)?;\n\n    let bakery_1 = insert_bakery(db, \"SeaSide Bakery\")?;\n    let bakery_2 = insert_bakery(db, \"LakeSide Bakery\")?;\n\n    let baker_1 = insert_baker(db, \"Jane\", bakery_1.id)?;\n    let baker_2 = insert_baker(db, \"Peter\", bakery_1.id)?;\n    let baker_3 = insert_baker(db, \"Fred\", bakery_2.id)?; // does not make cake\n\n    let cake_1 = insert_cake(db, \"Cheesecake\", Some(bakery_1.id))?;\n    let cake_2 = insert_cake(db, \"Coffee\", Some(bakery_1.id))?;\n    let cake_3 = insert_cake(db, \"Chiffon\", Some(bakery_2.id))?;\n    let cake_4 = insert_cake(db, \"Apple Pie\", None)?; // no one makes apple pie\n\n    insert_cake_baker(db, baker_1.id, cake_1.id)?;\n    insert_cake_baker(db, baker_1.id, cake_2.id)?;\n    insert_cake_baker(db, baker_2.id, cake_2.id)?;\n    insert_cake_baker(db, baker_2.id, cake_3.id)?;\n\n    let cakes = Cake::load().all(db)?;\n    assert_eq!(\n        cakes,\n        [\n            cake_1.clone(),\n            cake_2.clone(),\n            cake_3.clone(),\n            cake_4.clone(),\n        ]\n    );\n\n    let cakes = Cake::load().filter(Cake::COLUMN.name.like(\"Ch%\")).all(db)?;\n    assert_eq!(cakes, [cake_1.clone(), cake_3.clone()]);\n    assert!(cakes[0].bakers.is_empty());\n    assert!(cakes[0].bakery.is_unloaded());\n\n    assert_eq!(\n        Cake::load()\n            .filter(Cake::COLUMN.name.like(\"Ch%\"))\n            .order_by_desc(Cake::COLUMN.name)\n            .one(db)?\n            .unwrap(),\n        cake_3\n    );\n\n    let cakes = Cake::load().with(Bakery).all(db)?;\n    assert_eq!(\n        cakes,\n        [\n            cake_1.clone(),\n            cake_2.clone(),\n            cake_3.clone(),\n            cake_4.clone(),\n        ]\n    );\n    assert_eq!(cakes[0].bakery.as_ref().unwrap(), &bakery_1);\n    assert_eq!(cakes[1].bakery.as_ref().unwrap(), &bakery_1);\n    assert_eq!(cakes[2].bakery.as_ref().unwrap(), &bakery_2);\n    assert_eq!(cakes[3].bakery, None);\n\n    // low-level API\n    assert_eq!(\n        cakes,\n        cake::EntityLoader::load(\n            Cake::load().all(db)?,\n            &cake::EntityLoaderWith {\n                bakery: true,\n                lineitems: false,\n                bakers: false,\n            },\n            &Default::default(),\n            db\n        )?\n    );\n\n    let cake_with_bakery = Cake::load()\n        .filter(Cake::COLUMN.name.eq(\"Cheesecake\"))\n        .with(Bakery)\n        .one(db)?\n        .unwrap();\n    assert_eq!(cake_with_bakery, cake_1);\n    assert_eq!(cake_with_bakery.bakery.unwrap(), bakery_1);\n    assert!(cake_with_bakery.bakers.is_empty());\n\n    assert_eq!(\n        Cake::load()\n            .filter_by_id(cake_2.id)\n            .with(Bakery)\n            .one(db)?\n            .unwrap(),\n        {\n            let mut cake_2 = cake_2.clone().into_ex();\n            cake_2.bakery = HasOne::loaded(bakery_1.clone());\n            cake_2\n        }\n    );\n\n    let cakes = Cake::load().with(Bakery).with(Baker).all(db)?;\n    assert_eq!(\n        cakes,\n        [\n            cake_1.clone(),\n            cake_2.clone(),\n            cake_3.clone(),\n            cake_4.clone()\n        ]\n    );\n    assert_eq!(cakes[0].bakery.as_ref().unwrap(), &bakery_1);\n    assert_eq!(cakes[1].bakery.as_ref().unwrap(), &bakery_1);\n    assert_eq!(cakes[2].bakery.as_ref().unwrap(), &bakery_2);\n    assert_eq!(cakes[3].bakery, None);\n    assert_eq!(cakes[0].bakers, [baker_1.clone()]);\n    assert_eq!(cakes[1].bakers, [baker_1.clone(), baker_2.clone()]);\n    assert_eq!(cakes[2].bakers, [baker_2.clone()]);\n    assert!(cakes[3].bakers.is_empty());\n\n    let cake_with_bakery_baker = Cake::load()\n        .filter(Cake::COLUMN.name.eq(\"Chiffon\"))\n        .with(Bakery)\n        .with(Baker)\n        .one(db)?\n        .unwrap();\n    assert_eq!(cake_with_bakery_baker, cake_3);\n    assert_eq!(cake_with_bakery_baker.bakery.unwrap(), bakery_2);\n    assert_eq!(cake_with_bakery_baker.bakers, [baker_2.clone()]);\n\n    // start again from baker\n\n    let bakers = baker::Entity::find().all(db)?;\n    assert_eq!(bakers, [baker_1.clone(), baker_2.clone(), baker_3.clone()]);\n\n    let bakers = baker::Entity::load().with(cake::Entity).all(db)?;\n    assert_eq!(bakers[0].id, baker_1.id);\n    assert_eq!(bakers[1].id, baker_2.id);\n    assert_eq!(bakers[2].id, baker_3.id);\n    assert_eq!(bakers[0].cakes, [cake_1.clone(), cake_2.clone()]);\n    assert_eq!(bakers[1].cakes, [cake_2.clone(), cake_3.clone()]);\n    assert!(bakers[2].cakes.is_empty());\n\n    // alternative API\n    assert_eq!(\n        bakers,\n        baker::EntityLoader::load(\n            baker::Entity::load().all(db)?,\n            &baker::EntityLoaderWith {\n                cakes: true,\n                bakery: false,\n            },\n            &Default::default(),\n            db\n        )?\n    );\n\n    // 2 many\n    // bakery -> baker\n    //        -> cake\n\n    let bakeries = bakery::Entity::load()\n        .with(Baker)\n        .with(cake::Entity)\n        .order_by_asc(bakery::Column::Id)\n        .all(db)?;\n\n    assert_eq!(bakeries[0].bakers, [baker_1.clone(), baker_2.clone()]);\n    assert_eq!(bakeries[1].bakers, [baker_3.clone()]);\n    assert_eq!(bakeries[0].cakes, [cake_1.clone(), cake_2.clone()]);\n    assert_eq!(bakeries[1].cakes, [cake_3.clone()]);\n\n    // nested\n    // cake -> bakery -> baker\n\n    let cakes = Cake::load().with((Bakery, Baker)).all(db)?;\n    assert_eq!(cakes[0].bakery.as_ref().unwrap().name, bakery_1.name);\n    assert_eq!(cakes[1].bakery.as_ref().unwrap().name, bakery_1.name);\n    assert_eq!(cakes[2].bakery.as_ref().unwrap().name, bakery_2.name);\n    assert_eq!(cakes[3].bakery, None);\n    assert_eq!(\n        cakes[0].bakery.as_ref().unwrap().bakers,\n        [baker_1.clone(), baker_2.clone()]\n    );\n    assert_eq!(\n        cakes[1].bakery.as_ref().unwrap().bakers,\n        [baker_1.clone(), baker_2.clone()]\n    );\n    assert_eq!(cakes[2].bakery.as_ref().unwrap().bakers, [baker_3.clone()]);\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn entity_loader_join_three() {\n    let ctx = TestContext::new(\"entity_loader_join_three\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    let db = &ctx.db;\n\n    // verify basics\n    let cake_13 = cake::Entity::find_by_id(13).one(db).unwrap().unwrap();\n    let cake_15 = cake::Entity::find_by_id(15).one(db).unwrap().unwrap();\n\n    // new find by key feature\n    #[rustfmt::skip]\n    assert_eq!(cake::Entity::find_by_name(\"Cheesecake\").one(db).unwrap().unwrap().id, 13);\n    #[rustfmt::skip]\n    assert_eq!(cake::Entity::find_by_name(\"Chocolate\").one(db).unwrap().unwrap().id, 15);\n\n    // new load by key feature\n    #[rustfmt::skip]\n    assert_eq!(cake::Entity::load().filter_by_name(\"Cheesecake\").one(db).unwrap().unwrap().id, 13);\n    #[rustfmt::skip]\n    assert_eq!(cake::Entity::load().filter_by_name(\"Chocolate\").one(db).unwrap().unwrap().id, 15);\n\n    let lineitems = lineitem::Entity::load().all(db).unwrap();\n    assert_eq!(lineitems[0].cake_id, 13);\n    assert_eq!(lineitems[1].cake_id, 15);\n    assert_eq!(lineitems[0].order_id, 101);\n    assert_eq!(lineitems[1].order_id, 101);\n\n    // lineitem join order\n    let lineitems = lineitem::Entity::load()\n        .with(order::Entity)\n        .all(db)\n        .unwrap();\n    assert_eq!(lineitems[0].order.as_ref().unwrap().id, 101);\n    assert_eq!(lineitems[0].order.as_ref().unwrap().total, 10.into());\n    assert_eq!(lineitems[1].order.as_ref().unwrap().id, 101);\n    assert_eq!(lineitems[1].order.as_ref().unwrap().total, 10.into());\n\n    // lineitem join cake\n    let lineitems = lineitem::Entity::load().with(cake::Entity).all(db).unwrap();\n    assert_eq!(lineitems[0].cake.as_ref().unwrap().id, 13);\n    assert_eq!(lineitems[0].cake.as_ref().unwrap().name, \"Cheesecake\");\n    assert_eq!(lineitems[1].cake.as_ref().unwrap().id, 15);\n    assert_eq!(lineitems[1].cake.as_ref().unwrap().name, \"Chocolate\");\n\n    // lineitem join order + cake\n    let lineitems = lineitem::Entity::load()\n        .with(order::Entity)\n        .with(cake::Entity)\n        .all(db)\n        .unwrap();\n    assert_eq!(lineitems[0].order.as_ref().unwrap().id, 101);\n    assert_eq!(lineitems[0].order.as_ref().unwrap().total, 10.into());\n    assert_eq!(lineitems[1].order.as_ref().unwrap().id, 101);\n    assert_eq!(lineitems[1].order.as_ref().unwrap().total, 10.into());\n    assert_eq!(lineitems[0].cake.as_ref().unwrap().id, 13);\n    assert_eq!(lineitems[0].cake.as_ref().unwrap().name, \"Cheesecake\");\n    assert_eq!(lineitems[1].cake.as_ref().unwrap().id, 15);\n    assert_eq!(lineitems[1].cake.as_ref().unwrap().name, \"Chocolate\");\n\n    // 1 layer select\n    let order = order::Entity::load()\n        .with(customer::Entity)\n        .order_by_asc(order::Column::Id)\n        .one(db)\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(\n        order,\n        order::ModelEx {\n            id: 101,\n            total: 10.into(),\n            bakery_id: 42,\n            customer_id: 11,\n            placed_at: \"2020-01-01 00:00:00Z\".parse().unwrap(),\n            bakery: HasOne::Unloaded,\n            customer: HasOne::loaded(customer::Model {\n                id: 11,\n                name: \"Bob\".to_owned(),\n                notes: Some(\"Sweet tooth\".into()),\n            }),\n            lineitems: HasMany::Unloaded,\n        }\n    );\n\n    // 1 layer select\n    let order = order::Entity::load()\n        .with(bakery::Entity)\n        .with(customer::Entity)\n        .order_by_asc(order::Column::Id)\n        .one(db)\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(\n        order,\n        order::ModelEx {\n            id: 101,\n            total: 10.into(),\n            bakery_id: 42,\n            customer_id: 11,\n            placed_at: \"2020-01-01 00:00:00Z\".parse().unwrap(),\n            bakery: HasOne::loaded(bakery::Model {\n                id: 42,\n                name: \"cool little bakery\".into(),\n                profit_margin: 4.1,\n            }),\n            customer: HasOne::loaded(customer::ModelEx {\n                id: 11,\n                name: \"Bob\".to_owned(),\n                notes: Some(\"Sweet tooth\".into()),\n                orders: HasMany::Unloaded,\n            }),\n            lineitems: HasMany::Unloaded,\n        }\n    );\n\n    // 1 layer select\n    let order = order::Entity::load()\n        .with(customer::Entity)\n        .with(lineitem::Entity)\n        .order_by_asc(order::Column::Id)\n        .one(db)\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(\n        order,\n        order::ModelEx {\n            id: 101,\n            total: 10.into(),\n            bakery_id: 42,\n            customer_id: 11,\n            placed_at: \"2020-01-01 00:00:00Z\".parse().unwrap(),\n            bakery: HasOne::Unloaded,\n            customer: HasOne::loaded(customer::ModelEx {\n                id: 11,\n                name: \"Bob\".to_owned(),\n                notes: Some(\"Sweet tooth\".into()),\n                orders: HasMany::Unloaded,\n            }),\n            lineitems: HasMany::Loaded(vec![\n                lineitem::ModelEx {\n                    id: 1,\n                    price: 2.into(),\n                    quantity: 2,\n                    order_id: 101,\n                    cake_id: 13,\n                    order: HasOne::Unloaded,\n                    cake: HasOne::Unloaded,\n                },\n                lineitem::ModelEx {\n                    id: 2,\n                    price: 3.into(),\n                    quantity: 2,\n                    order_id: 101,\n                    cake_id: 15,\n                    order: HasOne::Unloaded,\n                    cake: HasOne::Unloaded,\n                }\n            ]),\n        }\n    );\n\n    // 2 layers\n    let order = order::Entity::load()\n        .with(customer::Entity)\n        .with((lineitem::Entity, cake::Entity))\n        .order_by_asc(order::Column::Id)\n        .one(db)\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(\n        order,\n        order::ModelEx {\n            id: 101,\n            total: 10.into(),\n            bakery_id: 42,\n            customer_id: 11,\n            placed_at: \"2020-01-01 00:00:00Z\".parse().unwrap(),\n            bakery: HasOne::Unloaded,\n            customer: HasOne::loaded(customer::Model {\n                id: 11,\n                name: \"Bob\".to_owned(),\n                notes: Some(\"Sweet tooth\".into()),\n            }),\n            lineitems: HasMany::Loaded(vec![\n                lineitem::ModelEx {\n                    id: 1,\n                    price: 2.into(),\n                    quantity: 2,\n                    order_id: 101,\n                    cake_id: 13,\n                    order: HasOne::Unloaded,\n                    cake: HasOne::loaded(cake_13),\n                },\n                lineitem::ModelEx {\n                    id: 2,\n                    price: 3.into(),\n                    quantity: 2,\n                    order_id: 101,\n                    cake_id: 15,\n                    order: HasOne::Unloaded,\n                    cake: HasOne::loaded(cake_15),\n                }\n            ]),\n        }\n    );\n}\n\n#[sea_orm_macros::test]\nfn entity_loader_self_join() -> Result<(), DbErr> {\n    use common::film_store::{staff, staff_compact, staff_mono};\n\n    let ctx = TestContext::new(\"entity_loader_self_join\");\n    let db = &ctx.db;\n\n    db.get_schema_builder().register(staff::Entity).apply(db)?;\n\n    let alan = staff::ActiveModel {\n        name: Set(\"Alan\".into()),\n        reports_to_id: Set(None),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    staff::ActiveModel {\n        name: Set(\"Ben\".into()),\n        reports_to_id: Set(Some(alan.id)),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    staff::ActiveModel {\n        name: Set(\"Alice\".into()),\n        reports_to_id: Set(Some(alan.id)),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    staff::ActiveModel {\n        name: Set(\"Elle\".into()),\n        reports_to_id: Set(None),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    // load belongs_to\n\n    let staff = staff::Entity::load()\n        .with(staff::Relation::ReportsTo)\n        .all(db)?;\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(staff[0].reports_to, None);\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(staff[2].reports_to.as_ref().unwrap().name, \"Alan\");\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(staff[3].reports_to, None);\n\n    // load belongs_to reverse\n\n    let staff = staff::Entity::load()\n        .with(staff::Relation::Manages)\n        .all(db)?;\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(staff[0].manages[0].name, \"Ben\");\n    assert_eq!(staff[0].manages[1].name, \"Alice\");\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert!(staff[1].manages.is_empty());\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert!(staff[2].manages.is_empty());\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert!(staff[3].manages.is_empty());\n\n    // load both sides\n\n    let staff = staff::Entity::load()\n        .with(staff::Relation::ReportsTo)\n        .with(staff::Relation::Manages)\n        .all(db)?;\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(staff[0].reports_to, None);\n    assert_eq!(staff[0].manages[0].name, \"Ben\");\n    assert_eq!(staff[0].manages[1].name, \"Alice\");\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n    assert!(staff[1].manages.is_empty());\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(staff[2].reports_to.as_ref().unwrap().name, \"Alan\");\n    assert!(staff[2].manages.is_empty());\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(staff[3].reports_to, None);\n    assert!(staff[3].manages.is_empty());\n\n    // test self_ref on model without reverse relation (not dual)\n\n    let staff = staff_mono::Entity::load()\n        .filter_by_id(2)\n        .with(staff_mono::Relation::ReportsTo)\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(staff.name, \"Ben\");\n    assert_eq!(\n        staff.reports_to.unwrap(),\n        staff_mono::Entity::find_by_id(alan.id).one(db)?.unwrap()\n    );\n\n    // test self_ref on compact_model\n\n    let staff = staff_compact::Entity::load()\n        .with(staff_compact::Relation::ReportsTo)\n        .with(staff_compact::Relation::Manages)\n        .all(db)?;\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(staff[0].reports_to, None);\n    assert_eq!(staff[0].manages[0].name, \"Ben\");\n    assert_eq!(staff[0].manages[1].name, \"Alice\");\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n    assert!(staff[1].manages.is_empty());\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(staff[2].reports_to.as_ref().unwrap().name, \"Alan\");\n    assert!(staff[2].manages.is_empty());\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(staff[3].reports_to, None);\n    assert!(staff[3].manages.is_empty());\n\n    // test pagination on loader\n\n    let mut pager = staff::Entity::load()\n        .with(staff::Relation::ReportsTo)\n        .order_by_asc(staff::COLUMN.id)\n        .paginate(db, 2);\n\n    let staff = pager.fetch_and_next()?.unwrap();\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(staff[0].reports_to, None);\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n\n    let staff = pager.fetch_and_next()?.unwrap();\n\n    assert_eq!(staff[0].name, \"Alice\");\n    assert_eq!(staff[0].reports_to.as_ref().unwrap().name, \"Alan\");\n\n    assert_eq!(staff[1].name, \"Elle\");\n    assert_eq!(staff[1].reports_to, None);\n\n    assert!(pager.fetch_and_next()?.is_none());\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn entity_loader_self_join_via() -> Result<(), DbErr> {\n    use common::blogger::{profile, user, user_follower, user_mono};\n\n    let ctx = TestContext::new(\"test_entity_loader_self_join_via\");\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(profile::Entity)\n        .register(user::Entity)\n        .register(user_follower::Entity)\n        .apply(db)?;\n\n    let alice = user::ActiveModel::builder()\n        .set_name(\"Alice\")\n        .set_email(\"@1\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Alice.jpg\"))\n        .insert(db)?;\n\n    let bob = user::ActiveModel::builder()\n        .set_name(\"Bob\")\n        .set_email(\"@2\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Bob.jpg\"))\n        .insert(db)?;\n\n    let sam = user::ActiveModel::builder()\n        .set_name(\"Sam\")\n        .set_email(\"@3\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Sam.jpg\"))\n        .insert(db)?;\n\n    user_follower::ActiveModel {\n        user_id: Set(alice.id),\n        follower_id: Set(bob.id),\n    }\n    .insert(db)?;\n\n    user_follower::ActiveModel {\n        user_id: Set(alice.id),\n        follower_id: Set(sam.id),\n    }\n    .insert(db)?;\n\n    user_follower::ActiveModel {\n        user_id: Set(bob.id),\n        follower_id: Set(sam.id),\n    }\n    .insert(db)?;\n\n    // test user + follower\n\n    let users = user::Entity::load().with(user_follower::Entity).all(db)?;\n\n    assert_eq!(users[0].name, alice.name);\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0].name, bob.name);\n    assert_eq!(users[0].followers[1].name, sam.name);\n\n    assert_eq!(users[1].name, bob.name);\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0].name, sam.name);\n\n    assert_eq!(users[2].name, sam.name);\n    assert!(users[2].followers.is_empty());\n\n    // test user + follower, but on an Entity without reverse relation (following)\n\n    let users = user_mono::Entity::load()\n        .with(user_follower::Entity)\n        .all(db)?;\n\n    assert_eq!(users[0].name, alice.name);\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0].name, bob.name);\n    assert_eq!(users[0].followers[1].name, sam.name);\n\n    assert_eq!(users[1].name, bob.name);\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0].name, sam.name);\n\n    assert_eq!(users[2].name, sam.name);\n    assert!(users[2].followers.is_empty());\n\n    // test user + follower + following (both sides)\n\n    let users = user::Entity::load()\n        .with(user::Follower)\n        .with(user::Following)\n        .all(db)?;\n\n    assert_eq!(users[0].name, alice.name);\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0].name, bob.name);\n    assert_eq!(users[0].followers[1].name, sam.name);\n    assert!(users[0].following.is_empty());\n\n    assert_eq!(users[1].name, bob.name);\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0].name, sam.name);\n    assert_eq!(users[1].following.len(), 1);\n    assert_eq!(users[1].following[0].name, alice.name);\n\n    assert_eq!(users[2].name, sam.name);\n    assert!(users[2].followers.is_empty());\n    assert_eq!(users[2].following.len(), 2);\n    assert_eq!(users[2].following[0].name, alice.name);\n    assert_eq!(users[2].following[1].name, bob.name);\n\n    // test user + profile\n\n    let users = user::Entity::load()\n        .with(profile::Entity)\n        .with(user_follower::Entity)\n        .all(db)?;\n\n    assert_eq!(users[0].profile, alice.profile);\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0].name, bob.name);\n    assert_eq!(users[0].followers[1].name, sam.name);\n\n    assert_eq!(users[1].profile, bob.profile);\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0].name, sam.name);\n\n    assert_eq!(users[2].profile, sam.profile);\n    assert!(users[2].followers.is_empty());\n\n    // test user + profile with nested user + profile\n\n    let users = user::Entity::load()\n        .with(profile::Entity)\n        .with((user::Follower, profile::Entity))\n        .all(db)?;\n\n    assert_eq!(users[0].profile, alice.profile);\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0], bob);\n    assert_eq!(users[0].followers[1], sam);\n\n    assert_eq!(users[1].profile, bob.profile);\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0], sam);\n\n    assert_eq!(users[2].profile, sam.profile);\n    assert!(users[2].followers.is_empty());\n\n    // test all: user profile + follower profile + following profile\n\n    let users = user::Entity::load()\n        .with(profile::Entity)\n        .with((user::Follower, profile::Entity))\n        .with((user::Following, profile::Entity))\n        .all(db)?;\n\n    assert_eq!(users[0].profile, alice.profile);\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0], bob);\n    assert_eq!(users[0].followers[1], sam);\n    assert!(users[0].following.is_empty());\n\n    assert_eq!(users[1].profile, bob.profile);\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0], sam);\n    assert_eq!(users[1].following.len(), 1);\n    assert_eq!(users[1].following[0], alice);\n\n    assert_eq!(users[2].profile, sam.profile);\n    assert!(users[2].followers.is_empty());\n    assert_eq!(users[2].following.len(), 2);\n    assert_eq!(users[2].following[0], alice);\n    assert_eq!(users[2].following[1], bob);\n\n    // test nested loading, but left right swapped\n\n    let alice_profile = profile::Entity::load()\n        .filter_by_id(alice.profile.as_ref().unwrap().id)\n        .with(sea_orm::compound::EntityLoaderWithSelf(\n            user::Entity,\n            user::Follower,\n        ))\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(\n        alice_profile.picture,\n        alice.profile.as_ref().unwrap().picture\n    );\n    assert_eq!(alice_profile.user.as_ref().unwrap().followers.len(), 2);\n    assert_eq!(\n        alice_profile.user.as_ref().unwrap().followers[0].name,\n        bob.name\n    );\n    assert_eq!(\n        alice_profile.user.as_ref().unwrap().followers[1].name,\n        sam.name\n    );\n\n    let sam_profile = profile::Entity::load()\n        .filter_by_id(sam.profile.as_ref().unwrap().id)\n        .with(sea_orm::compound::EntityLoaderWithSelfRev(\n            user::Entity,\n            user::Following,\n        ))\n        .one(db)?\n        .unwrap();\n    assert_eq!(sam_profile.picture, sam.profile.as_ref().unwrap().picture);\n    assert_eq!(sam_profile.user.as_ref().unwrap().following.len(), 2);\n    assert_eq!(\n        sam_profile.user.as_ref().unwrap().following[0].name,\n        alice.name\n    );\n    assert_eq!(\n        sam_profile.user.as_ref().unwrap().following[1].name,\n        bob.name\n    );\n\n    Ok(())\n}\n\npub fn insert_bakery(db: &DbConn, name: &str) -> Result<bakery::Model, DbErr> {\n    bakery::ActiveModel {\n        name: Set(name.to_owned()),\n        profit_margin: Set(1.0),\n        ..Default::default()\n    }\n    .insert(db)\n}\n\npub fn insert_baker(db: &DbConn, name: &str, bakery_id: i32) -> Result<baker::Model, DbErr> {\n    baker::ActiveModel {\n        name: Set(name.to_owned()),\n        contact_details: Set(serde_json::json!({})),\n        bakery_id: Set(Some(bakery_id)),\n        ..Default::default()\n    }\n    .insert(db)\n}\n\npub fn insert_cake(db: &DbConn, name: &str, bakery_id: Option<i32>) -> Result<cake::Model, DbErr> {\n    cake::ActiveModel {\n        name: Set(name.to_owned()),\n        price: Set(rust_decimal::Decimal::ONE),\n        gluten_free: Set(false),\n        bakery_id: Set(bakery_id),\n        ..Default::default()\n    }\n    .insert(db)\n}\n\npub fn insert_cake_baker(\n    db: &DbConn,\n    baker_id: i32,\n    cake_id: i32,\n) -> Result<cakes_bakers::Model, DbErr> {\n    cakes_bakers::ActiveModel {\n        cake_id: Set(cake_id),\n        baker_id: Set(baker_id),\n    }\n    .insert(db)\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/enum_primary_key_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{\n    ActiveEnum as ActiveEnumTrait, DatabaseConnection,\n    entity::prelude::*,\n    entity::*,\n    sea_query::{BinOper, Expr},\n};\nuse sea_query::ExprTrait;\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"enum_primary_key_tests\");\n    create_tea_enum(&ctx.db)?;\n    create_teas_table(&ctx.db)?;\n    insert_teas(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn insert_teas(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use teas::*;\n\n    let model = Model {\n        id: Tea::EverydayTea,\n        category: None,\n        color: None,\n    };\n\n    assert_eq!(\n        model,\n        ActiveModel {\n            id: Set(Tea::EverydayTea),\n            category: Set(None),\n            color: Set(None),\n        }\n        .insert(db)?\n    );\n    assert_eq!(model, Entity::find().one(db)?.unwrap());\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.is_not_null())\n            .filter(Column::Category.is_null())\n            .filter(Column::Color.is_null())\n            .one(db)?\n            .unwrap()\n    );\n\n    // UNIQUE constraint failed\n    assert!(\n        ActiveModel {\n            id: Set(Tea::EverydayTea),\n            category: Set(Some(Category::Big)),\n            color: Set(Some(Color::Black)),\n        }\n        .insert(db)\n        .is_err()\n    );\n\n    // UNIQUE constraint failed\n    assert!(\n        Entity::insert(ActiveModel {\n            id: Set(Tea::EverydayTea),\n            category: Set(Some(Category::Big)),\n            color: Set(Some(Color::Black)),\n        })\n        .exec(db)\n        .is_err()\n    );\n\n    let _ = ActiveModel {\n        category: Set(Some(Category::Big)),\n        color: Set(Some(Color::Black)),\n        ..model.into_active_model()\n    }\n    .save(db)?;\n\n    let model = Entity::find().one(db)?.unwrap();\n    assert_eq!(\n        model,\n        Model {\n            id: Tea::EverydayTea,\n            category: Some(Category::Big),\n            color: Some(Color::Black),\n        }\n    );\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.eq(Tea::EverydayTea))\n            .filter(Column::Category.eq(Category::Big))\n            .filter(Column::Color.eq(Color::Black))\n            .one(db)?\n            .unwrap()\n    );\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Expr::col(Column::Id).binary(\n                BinOper::In,\n                Expr::tuple([ActiveEnumTrait::as_enum(&Tea::EverydayTea)])\n            ))\n            .one(db)?\n            .unwrap()\n    );\n    // Equivalent to the above.\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.is_in([Tea::EverydayTea]))\n            .one(db)?\n            .unwrap()\n    );\n\n    let res = model.delete(db)?;\n\n    assert_eq!(res.rows_affected, 1);\n    assert_eq!(Entity::find().one(db)?, None);\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/event_trigger_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{\n    TestContext,\n    features::{\n        event_trigger::{Event, Events},\n        *,\n    },\n    setup::*,\n};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\n\n#[sea_orm_macros::test]\n#[cfg(all(feature = \"sqlx-postgres\", feature = \"postgres-array\"))]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"event_trigger_tests\");\n    create_event_trigger_table(&ctx.db)?;\n    insert_event_trigger(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn insert_event_trigger(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let event_trigger = event_trigger::Model {\n        id: 1,\n        events: Events(\n            [\"A\", \"B\", \"C\"]\n                .into_iter()\n                .map(|s| Event(s.to_owned()))\n                .collect(),\n        ),\n    };\n\n    let result = event_trigger.clone().into_active_model().insert(db)?;\n\n    assert_eq!(result, event_trigger);\n\n    let model = event_trigger::Entity::find()\n        .filter(event_trigger::Column::Id.eq(event_trigger.id))\n        .one(db)?;\n\n    assert_eq!(model, Some(event_trigger));\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/execute_unprepared_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{ConnectionTrait, DatabaseConnection, entity::prelude::*};\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"execute_unprepared_tests\");\n    create_insert_default_table(&ctx.db)?;\n    execute_unprepared(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn execute_unprepared(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    db.execute_unprepared(\n        [\n            \"INSERT INTO insert_default (id) VALUES (1), (2), (3), (4), (5)\",\n            \"DELETE FROM insert_default WHERE id % 2 = 0\",\n        ]\n        .join(\";\")\n        .as_str(),\n    )?;\n\n    assert_eq!(\n        Entity::find().all(db)?,\n        [Model { id: 1 }, Model { id: 3 }, Model { id: 5 }]\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/exists_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\npub use sea_orm::entity::*;\npub use sea_orm::{ConnectionTrait, QueryFilter, QueryOrder, QuerySelect, SelectExt};\n\n#[sea_orm_macros::test]\npub fn exists_with_no_result() {\n    let ctx = TestContext::new(\"exists_with_no_result\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let exists = Bakery::find().exists(&ctx.db).unwrap();\n    assert_eq!(exists, false);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn exists_with_result() {\n    let ctx = TestContext::new(\"exists_with_result\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let _bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let exists = Bakery::find().exists(&ctx.db).unwrap();\n    assert_eq!(exists, true);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn exists_with_filter_no_result() {\n    let ctx = TestContext::new(\"exists_with_filter_no_result\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let _bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let exists = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Nonexistent\"))\n        .exists(&ctx.db)\n        .unwrap();\n    assert_eq!(exists, false);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn exists_with_filter_has_result() {\n    let ctx = TestContext::new(\"exists_with_filter_has_result\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let _bakery1 = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let _bakery2 = bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let exists = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"SeaSide\"))\n        .exists(&ctx.db)\n        .unwrap();\n    assert_eq!(exists, true);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn exists_with_complex_query() {\n    let ctx = TestContext::new(\"exists_with_complex_query\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let _bakery1 = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let _bakery2 = bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let _bakery3 = bakery::ActiveModel {\n        name: Set(\"Low Profit Bakery\".to_owned()),\n        profit_margin: Set(5.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    // Test with complex filter - exists bakery with profit margin > 12\n    let exists = Bakery::find()\n        .filter(bakery::Column::ProfitMargin.gt(12.0))\n        .exists(&ctx.db)\n        .unwrap();\n    assert_eq!(exists, true);\n\n    // Test with complex filter - exists bakery with profit margin > 20\n    let exists = Bakery::find()\n        .filter(bakery::Column::ProfitMargin.gt(20.0))\n        .exists(&ctx.db)\n        .unwrap();\n    assert_eq!(exists, false);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn exists_with_joins() {\n    let ctx = TestContext::new(\"exists_with_joins\");\n    create_bakery_table(&ctx.db).unwrap();\n    create_cake_table(&ctx.db).unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let _cake = cake::ActiveModel {\n        name: Set(\"Chocolate Cake\".to_owned()),\n        price: Set(rust_dec(12.50)), // 12.50\n        bakery_id: Set(Some(bakery.id.unwrap())),\n        gluten_free: Set(false),\n        serial: Set(uuid::Uuid::new_v4()),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert cake\");\n\n    // Test exists with join - exists cake from a specific bakery\n    let exists = Cake::find()\n        .inner_join(Bakery)\n        .filter(bakery::Column::Name.eq(\"SeaSide Bakery\"))\n        .exists(&ctx.db)\n        .unwrap();\n    assert_eq!(exists, true);\n\n    // Test exists with join - no cake from non-existent bakery\n    let exists = Cake::find()\n        .inner_join(Bakery)\n        .filter(bakery::Column::Name.eq(\"Non-existent Bakery\"))\n        .exists(&ctx.db)\n        .unwrap();\n    assert_eq!(exists, false);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn exists_with_ordering() {\n    let ctx = TestContext::new(\"exists_with_ordering\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let _bakery1 = bakery::ActiveModel {\n        name: Set(\"A Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let _bakery2 = bakery::ActiveModel {\n        name: Set(\"Z Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    // Test exists with order by - should still work and return true\n    let exists = Bakery::find()\n        .order_by_asc(bakery::Column::Name)\n        .exists(&ctx.db)\n        .unwrap();\n    assert_eq!(exists, true);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn exists_with_limit_offset() {\n    let ctx = TestContext::new(\"exists_with_limit_offset\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    // Insert multiple bakeries\n    for i in 1..=5 {\n        let _bakery = bakery::ActiveModel {\n            name: Set(format!(\"Bakery {}\", i)),\n            profit_margin: Set(10.0 + (i as f64)),\n            ..Default::default()\n        }\n        .save(&ctx.db)\n        .expect(\"could not insert bakery\");\n    }\n\n    // Test exists with limit - should still find records\n    let exists = Bakery::find().limit(2).exists(&ctx.db).unwrap();\n    assert_eq!(exists, true);\n\n    // Test exists with offset - should still find records\n    let exists = Bakery::find().offset(3).exists(&ctx.db).unwrap();\n    assert_eq!(exists, true);\n\n    // Test exists with limit and offset - exists() checks for existence regardless of offset\n    // This is the expected behavior since exists() is optimized to check if ANY record exists\n    let exists = Bakery::find()\n        .offset(10) // Beyond all records\n        .limit(1)\n        .exists(&ctx.db)\n        .unwrap();\n    assert_eq!(exists, true); // exists() ignores offset for performance optimization\n\n    ctx.delete();\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/from_query_result_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\nuse sea_orm::{\n    FromQueryResult, JoinType, Set,\n    prelude::*,\n    query::{QueryOrder, QuerySelect},\n};\n\nuse crate::common::TestContext;\nuse common::bakery_chain::*;\nuse serde_json::json;\n\nmod common;\n\n#[derive(FromQueryResult)]\nstruct Cake {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<CakeBakery>,\n}\n\n#[derive(FromQueryResult)]\nstruct CakeBakery {\n    #[sea_orm(alias = \"bakery_id\")]\n    id: i32,\n    #[sea_orm(alias = \"bakery_name\")]\n    title: String,\n}\n\n#[derive(FromQueryResult)]\nstruct BakeryDetails {\n    #[sea_orm(nested)]\n    basics: Bakery,\n    profit: f64,\n}\n\n#[derive(FromQueryResult)]\nstruct Bakery {\n    id: i32,\n    title: String,\n}\n\n#[derive(FromQueryResult)]\nstruct BakeryFlat {\n    id: i32,\n    name: String,\n    #[sea_orm(from_alias = \"profit_margin\")]\n    profit: f64,\n}\n\n#[derive(FromQueryResult)]\nstruct CakeWithOptionalBakeryModel {\n    #[sea_orm(alias = \"cake_id\")]\n    id: i32,\n    #[sea_orm(alias = \"cake_name\")]\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<bakery::Model>,\n}\n\n#[sea_orm_macros::test]\nfn from_query_result_left_join_does_not_exist() {\n    let ctx = TestContext::new(\"from_query_result_left_join_does_not_exist\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, false);\n\n    let cake: Cake = cake::Entity::find()\n        .select_only()\n        .column(cake::Column::Id)\n        .column(cake::Column::Name)\n        .column_as(bakery::Column::Id, \"bakery_id\")\n        .column_as(bakery::Column::Name, \"bakery_name\")\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert!(cake.bakery.is_none());\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn from_query_result_left_join_with_optional_model_does_not_exist() {\n    let ctx = TestContext::new(\"from_query_result_left_join_with_optional_model_does_not_exist\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, false);\n\n    let cake: CakeWithOptionalBakeryModel = cake::Entity::find()\n        .select_only()\n        .column_as(cake::Column::Id, \"cake_id\")\n        .column_as(cake::Column::Name, \"cake_name\")\n        .column(bakery::Column::Id)\n        .column(bakery::Column::Name)\n        .column(bakery::Column::ProfitMargin)\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert!(cake.bakery.is_none());\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn from_query_result_left_join_exists() {\n    let ctx = TestContext::new(\"from_query_result_left_join_exists\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    let cake: Cake = cake::Entity::find()\n        .select_only()\n        .column(cake::Column::Id)\n        .column(cake::Column::Name)\n        .column_as(bakery::Column::Id, \"bakery_id\")\n        .column_as(bakery::Column::Name, \"bakery_name\")\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    let bakery = cake.bakery.unwrap();\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.title, \"cool little bakery\");\n\n    let cake: CakeWithOptionalBakeryModel = cake::Entity::find()\n        .select_only()\n        .column_as(cake::Column::Id, \"cake_id\")\n        .column_as(cake::Column::Name, \"cake_name\")\n        .column(bakery::Column::Id)\n        .column(bakery::Column::Name)\n        .column(bakery::Column::ProfitMargin)\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    let bakery = cake.bakery.unwrap();\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.name, \"cool little bakery\");\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn from_query_result_flat() {\n    let ctx = TestContext::new(\"from_query_result_flat\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    let bakery: BakeryFlat = bakery::Entity::find()\n        .into_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.name, \"cool little bakery\");\n    assert_eq!(bakery.profit, 4.1);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn from_query_result_nested() {\n    let ctx = TestContext::new(\"from_query_result_nested\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    let bakery: BakeryDetails = bakery::Entity::find()\n        .select_only()\n        .column(bakery::Column::Id)\n        .column_as(bakery::Column::Name, \"title\")\n        .column_as(bakery::Column::ProfitMargin, \"profit\")\n        .into_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.basics.id, 42);\n    assert_eq!(bakery.basics.title, \"cool little bakery\");\n    assert_eq!(bakery.profit, 4.1);\n\n    ctx.delete();\n}\n\n#[derive(FromQueryResult)]\nstruct CakePlain {\n    id: i32,\n    name: String,\n    price: Decimal,\n    #[sea_orm(nested)]\n    baker: Option<cakes_bakers::Model>,\n    #[sea_orm(skip)]\n    hidden: i32,\n}\n\n#[sea_orm_macros::test]\nfn from_query_result_plain_model() {\n    let ctx = TestContext::new(\"from_query_result_plain_model\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    let cake: CakePlain = cake::Entity::find()\n        .column(cakes_bakers::Column::CakeId)\n        .column(cakes_bakers::Column::BakerId)\n        .join(JoinType::LeftJoin, cakes_bakers::Relation::Cake.def().rev())\n        .order_by_asc(cake::Column::Id)\n        .into_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert_eq!(cake.price, Decimal::from(2));\n    let baker = cake.baker.unwrap();\n    assert_eq!(baker.cake_id, 13);\n    assert_eq!(baker.baker_id, 22);\n\n    ctx.delete();\n}\n\n#[derive(Debug, FromQueryResult)]\nstruct WrongBakery {\n    id: String,\n    title: String,\n}\n\n#[derive(Debug, FromQueryResult)]\nstruct WrongCake {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<WrongBakery>,\n}\n\n#[sea_orm_macros::test]\nfn from_query_result_optional_field_but_type_error() {\n    let ctx = TestContext::new(\"from_query_result_nested_error\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, false);\n\n    let _: DbErr = cake::Entity::find()\n        .select_only()\n        .column(cake::Column::Id)\n        .left_join(bakery::Entity)\n        .into_model::<WrongCake>()\n        .one(&ctx.db)\n        .expect_err(\"should error instead of returning an empty Option\");\n\n    ctx.delete();\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/host_network_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n#![cfg(feature = \"with-ipnetwork\")]\n\npub mod common;\n\nuse common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\nuse std::net::{Ipv4Addr, Ipv6Addr};\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-postgres\")]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"host_network_tests\");\n    create_host_network_table(&ctx.db)?;\n    create_and_update_host_network(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\nfn create_and_update_host_network(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let addr = IpNetwork::new(Ipv4Addr::new(192, 168, 0, 20).into(), 24).unwrap();\n    let net = IpNetwork::new(addr.network(), addr.prefix()).unwrap();\n\n    let host = host_network::Model {\n        id: 1,\n        hostname: \"example.com\".to_owned(),\n        ipaddress: addr,\n        network: net,\n    };\n    let res = host.clone().into_active_model().insert(db)?;\n\n    let model = host_network::Entity::find().one(db)?.unwrap();\n    assert_eq!(model, res);\n    assert_eq!(model, host.clone());\n\n    let addrv6 = IpNetwork::new(\n        Ipv6Addr::new(0xfd89, 0x1926, 0x4cae, 0x8abd, 0, 0, 0, 0x6f52).into(),\n        64,\n    )\n    .unwrap();\n    let netv6 = IpNetwork::new(addr.network(), addr.prefix()).unwrap();\n\n    let res = host_network::ActiveModel {\n        id: Set(1),\n        ipaddress: Set(addrv6),\n        network: Set(netv6),\n        ..Default::default()\n    }\n    .update(db)?;\n\n    assert_eq!(\n        res,\n        host_network::Model {\n            id: 1,\n            hostname: \"example.com\".to_owned(),\n            ipaddress: addrv6,\n            network: netv6,\n        }\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/impl_from_for_active_model.rs",
    "content": "use sea_orm::{Set, tests_cfg::cake};\n\nstruct Cake {\n    id: i32,\n    name: String,\n}\n\nimpl From<Cake> for cake::ActiveModel {\n    fn from(value: Cake) -> Self {\n        Self {\n            id: Set(value.id),\n            name: Set(value.name),\n        }\n    }\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/insert_default_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"insert_default_tests\");\n    create_insert_default_table(&ctx.db)?;\n    create_insert_default(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    let active_model = ActiveModel {\n        ..Default::default()\n    };\n\n    active_model.clone().insert(db)?;\n    active_model.clone().insert(db)?;\n    active_model.insert(db)?;\n\n    assert_eq!(\n        Entity::find().all(db)?,\n        [Model { id: 1 }, Model { id: 2 }, Model { id: 3 }]\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/json_struct_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, DbBackend, ExprTrait, entity::prelude::*, entity::*};\nuse serde_json::json;\n\nmod json_compact {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::compact_model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"json_compact\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_type = \"JsonBinary\")]\n        pub json: Json,\n        #[sea_orm(column_type = \"JsonBinary\", nullable)]\n        pub json_opt: Option<Json>,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[sea_orm_macros::test]\nfn json_struct_tests() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"json_struct_tests\");\n    create_json_struct_table(&ctx.db)?;\n    insert_json_struct_1(&ctx.db)?;\n    insert_json_struct_2(&ctx.db)?;\n    insert_json_struct_3(&ctx.db)?;\n\n    ctx.delete();\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\n#[should_panic(\n    expected = \"Failed to serialize 'NonSerializableStruct': Error(\\\"intentionally failing serialization\\\", line: 0, column: 0)\"\n)]\nfn panic_on_non_serializable_insert() {\n    use json_struct::*;\n\n    let ctx = TestContext::new(\"json_struct_non_serializable_test\");\n\n    let model = Model {\n        id: 1,\n        json: json!({\n            \"id\": 1,\n            \"name\": \"apple\",\n            \"price\": 12.01,\n            \"notes\": \"hand picked, organic\",\n        }),\n        json_value: KeyValue {\n            id: 1,\n            name: \"apple\".into(),\n            price: 12.01,\n            notes: Some(\"hand picked, organic\".into()),\n        },\n        json_value_opt: Some(KeyValue {\n            id: 1,\n            name: \"apple\".into(),\n            price: 12.01,\n            notes: Some(\"hand picked, organic\".into()),\n        }),\n        json_non_serializable: Some(NonSerializableStruct),\n    };\n\n    let _ = model.into_active_model().insert(&ctx.db);\n}\n\npub fn insert_json_struct_1(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use json_struct::*;\n\n    let model = Model {\n        id: 1,\n        json: json!({\n            \"id\": 1,\n            \"name\": \"apple\",\n            \"price\": 12.01,\n            \"notes\": \"hand picked, organic\",\n        }),\n        json_value: KeyValue {\n            id: 1,\n            name: \"apple\".into(),\n            price: 12.01,\n            notes: Some(\"hand picked, organic\".into()),\n        },\n        json_value_opt: Some(KeyValue {\n            id: 1,\n            name: \"apple\".into(),\n            price: 12.01,\n            notes: Some(\"hand picked, organic\".into()),\n        }),\n        json_non_serializable: None,\n    };\n\n    let result = model.clone().into_active_model().insert(db)?;\n\n    assert_eq!(result, model);\n\n    assert_eq!(\n        Entity::find().filter(Column::Id.eq(model.id)).one(db)?,\n        Some(model)\n    );\n\n    Ok(())\n}\n\npub fn insert_json_struct_2(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use json_struct::*;\n\n    let model = Model {\n        id: 2,\n        json: json!({\n            \"id\": 2,\n            \"name\": \"orange\",\n            \"price\": 10.93,\n            \"notes\": \"sweet & juicy\",\n        }),\n        json_value: KeyValue {\n            id: 1,\n            name: \"orange\".into(),\n            price: 10.93,\n            notes: None,\n        },\n        json_value_opt: None,\n        json_non_serializable: None,\n    };\n\n    let result = model.clone().into_active_model().insert(db)?;\n\n    assert_eq!(result, model);\n\n    assert_eq!(\n        Entity::find().filter(Column::Id.eq(model.id)).one(db)?,\n        Some(model)\n    );\n\n    Ok(())\n}\n\npub fn insert_json_struct_3(db: &DatabaseConnection) -> Result<(), DbErr> {\n    db.get_schema_builder()\n        .register(json_compact::Entity)\n        .apply(db)?;\n\n    use json_compact::*;\n\n    let model = Model {\n        id: 3,\n        json: json!({ \"id\": 22 }),\n        json_opt: None,\n    };\n\n    let model_2 = model.into_active_model().insert(db)?;\n\n    if db.get_database_backend() == DbBackend::MySql {\n        // FIXME how can we abstract this?\n        // MariaDb doesn't require CAST AS json\n        if false {\n            assert_eq!(\n                Entity::find()\n                    .filter(\n                        Expr::col(COLUMN.json).eq(Expr::val(json!({ \"id\": 22 })).cast_as(\"json\"))\n                    )\n                    .one(db)?\n                    .unwrap(),\n                model_2\n            );\n        }\n    } else {\n        assert_eq!(\n            Entity::find()\n                .filter(COLUMN.json.eq(json!({ \"id\": 22 })))\n                .one(db)?\n                .unwrap(),\n            model_2\n        );\n    }\n\n    let model = Model {\n        id: 4,\n        json: json!({ \"id\": 11 }),\n        json_opt: Some(json!({ \"id\": 33 })),\n    };\n\n    let model_4 = model.into_active_model().insert(db)?;\n\n    if db.get_database_backend() == DbBackend::MySql {\n        // FIXME how can we abstract this?\n        // MariaDb doesn't require CAST AS json\n        if false {\n            assert_eq!(\n                Entity::find()\n                    .filter(\n                        Expr::col(COLUMN.json_opt)\n                            .eq(Expr::val(json!({ \"id\": 33 })).cast_as(\"json\"))\n                    )\n                    .one(db)?\n                    .unwrap(),\n                model_4\n            );\n        }\n    } else {\n        assert_eq!(\n            Entity::find()\n                .filter(COLUMN.json_opt.eq(json!({ \"id\": 33 })))\n                .one(db)?\n                .unwrap(),\n            model_4\n        );\n    }\n\n    assert_eq!(\n        Entity::find()\n            .filter(COLUMN.json_opt.eq(Option::<Json>::None))\n            .one(db)?\n            .unwrap(),\n        model_2\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/json_vec_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"json_vec_tests\");\n    create_json_vec_table(&ctx.db)?;\n    create_json_string_vec_table(&ctx.db)?;\n    create_json_struct_vec_table(&ctx.db)?;\n    insert_json_vec(&ctx.db)?;\n    insert_json_string_vec_derive(&ctx.db)?;\n    insert_json_struct_vec_derive(&ctx.db)?;\n\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn insert_json_vec(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let json_vec = json_vec::Model {\n        id: 1,\n        str_vec: Some(json_vec::StringVec(vec![\n            \"1\".to_string(),\n            \"2\".to_string(),\n            \"3\".to_string(),\n        ])),\n    };\n\n    let result = json_vec.clone().into_active_model().insert(db)?;\n\n    assert_eq!(result, json_vec);\n\n    let model = json_vec::Entity::find()\n        .filter(json_vec::Column::Id.eq(json_vec.id))\n        .one(db)?;\n\n    assert_eq!(model, Some(json_vec));\n\n    Ok(())\n}\n\npub fn insert_json_string_vec_derive(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let json_vec = json_vec_derive::json_string_vec::Model {\n        id: 1,\n        str_vec: Some(json_vec_derive::json_string_vec::StringVec(vec![\n            \"4\".to_string(),\n            \"5\".to_string(),\n            \"6\".to_string(),\n        ])),\n    };\n\n    let result = json_vec_derive::json_string_vec::ActiveModel {\n        id: NotSet,\n        ..json_vec.clone().into_active_model()\n    }\n    .insert(db)?;\n\n    assert_eq!(result, json_vec);\n\n    let model = json_vec_derive::json_string_vec::Entity::find()\n        .filter(json_vec_derive::json_string_vec::Column::Id.eq(json_vec.id))\n        .one(db)?;\n\n    assert_eq!(model, Some(json_vec));\n\n    let result = json_vec_derive::json_string_vec::ActiveModel {\n        id: NotSet,\n        str_vec: Set(None),\n    }\n    .insert(db)?;\n\n    assert_eq!(result.str_vec, None);\n\n    Ok(())\n}\n\npub fn insert_json_struct_vec_derive(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let json_vec = json_vec_derive::json_struct_vec::Model {\n        id: 2,\n        struct_vec: vec![\n            json_vec_derive::json_struct_vec::JsonColumn {\n                value: \"4\".to_string(),\n            },\n            json_vec_derive::json_struct_vec::JsonColumn {\n                value: \"5\".to_string(),\n            },\n            json_vec_derive::json_struct_vec::JsonColumn {\n                value: \"6\".to_string(),\n            },\n        ],\n    };\n\n    let _result = json_vec.clone().into_active_model().insert(db)?;\n\n    let model = json_vec_derive::json_struct_vec::Entity::find()\n        .filter(json_vec_derive::json_struct_vec::Column::Id.eq(json_vec.id))\n        .one(db)?;\n\n    assert_eq!(model, Some(json_vec));\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/loader_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\nuse sea_orm::{DbConn, DbErr, LoaderTraitEx, RuntimeErr, entity::*, query::*};\n\nmod enum_pk_models {\n    use crate::common::features::Tea;\n    use sea_orm::entity::prelude::*;\n\n    pub mod tea_inventory {\n        use super::tea_order;\n        use super::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"tea_inventory\")]\n        pub struct Model {\n            #[sea_orm(primary_key, auto_increment = false)]\n            pub tea: Tea,\n            pub stock: i32,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {\n            #[sea_orm(has_many = \"super::tea_order::Entity\")]\n            TeaOrder,\n        }\n\n        impl Related<tea_order::Entity> for Entity {\n            fn to() -> RelationDef {\n                Relation::TeaOrder.def()\n            }\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    pub mod tea_order {\n        use super::tea_inventory;\n        use super::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"tea_orders\")]\n        pub struct Model {\n            #[sea_orm(primary_key, auto_increment = false)]\n            pub order_id: i32,\n            #[sea_orm(primary_key, auto_increment = false)]\n            pub tea: Tea,\n            pub quantity: i32,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {\n            #[sea_orm(\n                belongs_to = \"super::tea_inventory::Entity\",\n                from = \"Column::Tea\",\n                to = \"super::tea_inventory::Column::Tea\"\n            )]\n            TeaInventory,\n        }\n\n        impl Related<tea_inventory::Entity> for Entity {\n            fn to() -> RelationDef {\n                Relation::TeaInventory.def()\n            }\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n}\n\nuse enum_pk_models::{tea_inventory, tea_order};\n\n#[sea_orm_macros::test]\nfn loader_load_one() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"loader_test_load_one\");\n    create_tables(&ctx.db)?;\n\n    let bakery_0 = insert_bakery(&ctx.db, \"SeaSide Bakery\")?;\n\n    let baker_1 = insert_baker(&ctx.db, \"Baker 1\", bakery_0.id)?;\n    let baker_2 = insert_baker(&ctx.db, \"Baker 2\", bakery_0.id)?;\n    let baker_3 = baker::ActiveModel {\n        name: Set(\"Baker 3\".to_owned()),\n        contact_details: Set(serde_json::json!({})),\n        bakery_id: Set(None),\n        ..Default::default()\n    }\n    .insert(&ctx.db)?;\n\n    let bakers = baker::Entity::find().all(&ctx.db)?;\n    let bakeries = bakers.load_one(bakery::Entity, &ctx.db)?;\n\n    assert_eq!(bakers, [baker_1.clone(), baker_2.clone(), baker_3.clone()]);\n    assert_eq!(\n        bakeries,\n        [Some(bakery_0.clone()), Some(bakery_0.clone()), None]\n    );\n\n    let bakers = vec![\n        Some(baker_1.clone().into_ex()),\n        None,\n        Some(baker_2.clone().into_ex()),\n        Some(baker_3.clone().into_ex()),\n        None,\n    ];\n    let bakeries = bakers.as_slice().load_one_ex(bakery::Entity, &ctx.db)?;\n    assert_eq!(\n        bakeries,\n        [\n            Some(bakery_0.clone()),\n            None,\n            Some(bakery_0.clone()),\n            None,\n            None\n        ]\n    );\n\n    // has many find, should use load_many instead\n    let bakeries = bakery::Entity::find().all(&ctx.db)?;\n    let bakers = bakeries.load_one(baker::Entity, &ctx.db);\n\n    assert_eq!(\n        bakers,\n        Err(DbErr::Query(RuntimeErr::Internal(\n            \"Relation is HasMany instead of HasOne\".to_string()\n        )))\n    );\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn loader_load_many() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"loader_test_load_many\");\n    create_tables(&ctx.db)?;\n\n    let bakery_1 = insert_bakery(&ctx.db, \"SeaSide Bakery\")?;\n    let bakery_2 = insert_bakery(&ctx.db, \"Offshore Bakery\")?;\n    let bakery_3 = insert_bakery(&ctx.db, \"Rocky Bakery\")?;\n\n    let baker_1 = insert_baker(&ctx.db, \"Baker 1\", bakery_1.id)?;\n    let baker_2 = insert_baker(&ctx.db, \"Baker 2\", bakery_1.id)?;\n\n    let baker_3 = insert_baker(&ctx.db, \"John\", bakery_2.id)?;\n    let baker_4 = insert_baker(&ctx.db, \"Baker 4\", bakery_2.id)?;\n\n    let bakeries = bakery::Entity::find().all(&ctx.db)?;\n    let bakers = bakeries.load_many(baker::Entity, &ctx.db)?;\n\n    assert_eq!(\n        bakeries,\n        [bakery_1.clone(), bakery_2.clone(), bakery_3.clone()]\n    );\n    assert_eq!(\n        bakers,\n        [\n            vec![baker_1.clone(), baker_2.clone()],\n            vec![baker_3.clone(), baker_4.clone()],\n            vec![]\n        ]\n    );\n\n    // test interlaced loader\n    let bakeries_sparse = vec![\n        Some(bakery_1.clone().into_ex()),\n        None,\n        Some(bakery_2.clone().into_ex()),\n        None,\n    ];\n    let bakers = bakeries_sparse\n        .as_slice()\n        .load_many_ex(baker::Entity, &ctx.db)?;\n    assert_eq!(\n        bakers,\n        [\n            vec![baker_1.clone(), baker_2.clone()],\n            vec![],\n            vec![baker_3.clone(), baker_4.clone()],\n            vec![],\n        ]\n    );\n\n    // load bakers again but with additional condition\n\n    let bakers = bakeries.load_many(\n        baker::Entity::find().filter(baker::Column::Name.like(\"Baker%\")),\n        &ctx.db,\n    )?;\n\n    assert_eq!(\n        bakers,\n        [\n            vec![baker_1.clone(), baker_2.clone()],\n            vec![baker_4.clone()],\n            vec![]\n        ]\n    );\n\n    // now, start from baker\n\n    let bakers = baker::Entity::find().all(&ctx.db)?;\n    let bakeries = bakers.load_one(bakery::Entity::find(), &ctx.db)?;\n\n    // note that two bakers share the same bakery\n    assert_eq!(bakers, [baker_1, baker_2, baker_3, baker_4]);\n    assert_eq!(\n        bakeries,\n        [\n            Some(bakery_1.clone()),\n            Some(bakery_1.clone()),\n            Some(bakery_2.clone()),\n            Some(bakery_2.clone())\n        ]\n    );\n\n    // following should be equivalent\n    let bakeries = bakers.load_many(bakery::Entity::find(), &ctx.db)?;\n\n    assert_eq!(\n        bakeries,\n        [\n            vec![bakery_1.clone()],\n            vec![bakery_1.clone()],\n            vec![bakery_2.clone()],\n            vec![bakery_2.clone()],\n        ]\n    );\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn loader_load_many_multi() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"loader_test_load_many_multi\");\n    create_tables(&ctx.db)?;\n\n    let bakery_1 = insert_bakery(&ctx.db, \"SeaSide Bakery\")?;\n    let bakery_2 = insert_bakery(&ctx.db, \"Offshore Bakery\")?;\n\n    let baker_1 = insert_baker(&ctx.db, \"John\", bakery_1.id)?;\n    let baker_2 = insert_baker(&ctx.db, \"Jane\", bakery_1.id)?;\n    let baker_3 = insert_baker(&ctx.db, \"Peter\", bakery_2.id)?;\n\n    let cake_1 = insert_cake(&ctx.db, \"Cheesecake\", Some(bakery_1.id))?;\n    let cake_2 = insert_cake(&ctx.db, \"Chocolate\", Some(bakery_2.id))?;\n    let cake_3 = insert_cake(&ctx.db, \"Chiffon\", Some(bakery_2.id))?;\n    let _cake_4 = insert_cake(&ctx.db, \"Apple Pie\", None)?; // no one makes apple pie\n\n    let bakeries = bakery::Entity::find().all(&ctx.db)?;\n    let bakers = bakeries.load_many(baker::Entity, &ctx.db)?;\n    let cakes = bakeries.load_many(cake::Entity, &ctx.db)?;\n\n    assert_eq!(bakeries, [bakery_1, bakery_2]);\n    assert_eq!(bakers, [vec![baker_1, baker_2], vec![baker_3]]);\n    assert_eq!(cakes, [vec![cake_1], vec![cake_2, cake_3]]);\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn loader_load_many_enum_pk_postgres() -> Result<(), DbErr> {\n    use crate::common::features::Tea;\n    use sea_orm::{ActiveValue::Set, ConnectionTrait, DbBackend, Schema};\n    use sea_query::{Alias, extension::postgres::Type};\n    use tea_inventory::{\n        ActiveModel as TeaInventoryActiveModel, Column as TeaInventoryColumn,\n        Entity as TeaInventoryEntity, Model as TeaInventoryModel,\n    };\n    use tea_order::{\n        ActiveModel as TeaOrderActiveModel, Column as TeaOrderColumn, Entity as TeaOrderEntity,\n        Model as TeaOrderModel,\n    };\n\n    let ctx = TestContext::new(\"loader_enum_pk_postgres\");\n    let db = &ctx.db;\n\n    if db.get_database_backend() != DbBackend::Postgres {\n        return Ok(());\n    }\n\n    let mut drop_type = Type::drop();\n    drop_type.if_exists().name(\"tea\").cascade();\n    db.execute(&drop_type)?;\n\n    db.get_schema_builder()\n        .register(TeaInventoryEntity)\n        .register(TeaOrderEntity)\n        .apply(db)?;\n\n    TeaInventoryActiveModel {\n        tea: Set(Tea::EverydayTea),\n        stock: Set(10),\n    }\n    .insert(db)?;\n    TeaInventoryActiveModel {\n        tea: Set(Tea::BreakfastTea),\n        stock: Set(4),\n    }\n    .insert(db)?;\n\n    TeaOrderActiveModel {\n        order_id: Set(1),\n        tea: Set(Tea::EverydayTea),\n        quantity: Set(2),\n    }\n    .insert(db)?;\n    TeaOrderActiveModel {\n        order_id: Set(2),\n        tea: Set(Tea::EverydayTea),\n        quantity: Set(5),\n    }\n    .insert(db)?;\n    TeaOrderActiveModel {\n        order_id: Set(1),\n        tea: Set(Tea::BreakfastTea),\n        quantity: Set(1),\n    }\n    .insert(db)?;\n\n    let teas = TeaInventoryEntity::find()\n        .order_by_asc(TeaInventoryColumn::Tea)\n        .all(db)?;\n    let loaded_orders = teas.load_many(\n        TeaOrderEntity::find().order_by_asc(TeaOrderColumn::OrderId),\n        db,\n    )?;\n\n    assert_eq!(teas.len(), 2);\n    assert_eq!(loaded_orders.len(), 2);\n\n    for (inventory, orders) in teas.iter().zip(&loaded_orders) {\n        match inventory.tea {\n            Tea::EverydayTea => {\n                assert_eq!(\n                    orders,\n                    &vec![\n                        TeaOrderModel {\n                            order_id: 1,\n                            tea: Tea::EverydayTea,\n                            quantity: 2,\n                        },\n                        TeaOrderModel {\n                            order_id: 2,\n                            tea: Tea::EverydayTea,\n                            quantity: 5,\n                        }\n                    ]\n                );\n            }\n            Tea::BreakfastTea => {\n                assert_eq!(\n                    orders,\n                    &vec![TeaOrderModel {\n                        order_id: 1,\n                        tea: Tea::BreakfastTea,\n                        quantity: 1,\n                    }]\n                );\n            }\n            Tea::AfternoonTea => {}\n        }\n    }\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn loader_load_many_to_many() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"loader_test_load_many_to_many\");\n    create_tables(&ctx.db)?;\n\n    let bakery_1 = insert_bakery(&ctx.db, \"SeaSide Bakery\")?;\n\n    let baker_1 = insert_baker(&ctx.db, \"Jane\", bakery_1.id)?;\n    let baker_2 = insert_baker(&ctx.db, \"Peter\", bakery_1.id)?;\n    let baker_3 = insert_baker(&ctx.db, \"Fred\", bakery_1.id)?; // does not make cake\n\n    let cake_1 = insert_cake(&ctx.db, \"Cheesecake\", None)?;\n    let cake_2 = insert_cake(&ctx.db, \"Coffee\", None)?;\n    let cake_3 = insert_cake(&ctx.db, \"Chiffon\", None)?;\n    let cake_4 = insert_cake(&ctx.db, \"Apple Pie\", None)?; // no one makes apple pie\n\n    insert_cake_baker(&ctx.db, baker_1.id, cake_1.id)?;\n    insert_cake_baker(&ctx.db, baker_1.id, cake_2.id)?;\n    insert_cake_baker(&ctx.db, baker_2.id, cake_2.id)?;\n    insert_cake_baker(&ctx.db, baker_2.id, cake_3.id)?;\n\n    let bakers = baker::Entity::find().all(&ctx.db)?;\n    let cakes = bakers.load_many_to_many(cake::Entity, cakes_bakers::Entity, &ctx.db)?;\n\n    assert_eq!(bakers, [baker_1.clone(), baker_2.clone(), baker_3.clone()]);\n    assert_eq!(\n        cakes,\n        [\n            vec![cake_1.clone(), cake_2.clone()],\n            vec![cake_2.clone(), cake_3.clone()],\n            vec![]\n        ]\n    );\n\n    // same, but apply restrictions on cakes\n\n    let cakes = bakers.load_many_to_many(\n        cake::Entity::find().filter(cake::Column::Name.like(\"Ch%\")),\n        cakes_bakers::Entity,\n        &ctx.db,\n    )?;\n    assert_eq!(cakes, [vec![cake_1.clone()], vec![cake_3.clone()], vec![]]);\n\n    // now, start again from cakes\n\n    let cakes = cake::Entity::find().all(&ctx.db)?;\n    let bakers = cakes.load_many_to_many(baker::Entity, cakes_bakers::Entity, &ctx.db)?;\n\n    assert_eq!(cakes, [cake_1, cake_2, cake_3, cake_4]);\n    assert_eq!(\n        bakers,\n        [\n            vec![baker_1.clone()],\n            vec![baker_1.clone(), baker_2.clone()],\n            vec![baker_2.clone()],\n            vec![]\n        ]\n    );\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn loader_load_many_to_many_dyn() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"loader_test_load_many_to_many_dyn\");\n    create_tables(&ctx.db)?;\n\n    let bakery_1 = insert_bakery(&ctx.db, \"SeaSide Bakery\")?;\n\n    let baker_1 = insert_baker(&ctx.db, \"Jane\", bakery_1.id)?;\n    let baker_2 = insert_baker(&ctx.db, \"Peter\", bakery_1.id)?;\n    let baker_3 = insert_baker(&ctx.db, \"Fred\", bakery_1.id)?; // does not make cake\n\n    let cake_1 = insert_cake(&ctx.db, \"Cheesecake\", None)?;\n    let cake_2 = insert_cake(&ctx.db, \"Coffee\", None)?;\n    let cake_3 = insert_cake(&ctx.db, \"Chiffon\", None)?;\n    let cake_4 = insert_cake(&ctx.db, \"Apple Pie\", None)?; // no one makes apple pie\n\n    insert_cake_baker(&ctx.db, baker_1.id, cake_1.id)?;\n    insert_cake_baker(&ctx.db, baker_1.id, cake_2.id)?;\n    insert_cake_baker(&ctx.db, baker_2.id, cake_2.id)?;\n    insert_cake_baker(&ctx.db, baker_2.id, cake_3.id)?;\n\n    let bakers = baker::Entity::find().all(&ctx.db)?;\n    let cakes = bakers.load_many(cake::Entity, &ctx.db)?;\n\n    assert_eq!(bakers, [baker_1.clone(), baker_2.clone(), baker_3.clone()]);\n    assert_eq!(\n        cakes,\n        [\n            vec![cake_1.clone(), cake_2.clone()],\n            vec![cake_2.clone(), cake_3.clone()],\n            vec![]\n        ]\n    );\n\n    // same, but apply restrictions on cakes\n\n    let cakes = bakers.load_many_to_many(\n        cake::Entity::find().filter(cake::Column::Name.like(\"Ch%\")),\n        cakes_bakers::Entity,\n        &ctx.db,\n    )?;\n    assert_eq!(cakes, [vec![cake_1.clone()], vec![cake_3.clone()], vec![]]);\n\n    // now, start again from cakes\n\n    let cakes = cake::Entity::find().all(&ctx.db)?;\n    let bakers = cakes.load_many(baker::Entity, &ctx.db)?;\n\n    assert_eq!(cakes, [cake_1, cake_2, cake_3, cake_4]);\n    assert_eq!(\n        bakers,\n        [\n            vec![baker_1.clone()],\n            vec![baker_1.clone(), baker_2.clone()],\n            vec![baker_2.clone()],\n            vec![]\n        ]\n    );\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn loader_self_join() -> Result<(), DbErr> {\n    use common::blogger::{user, user_follower};\n    use common::film_store::{staff, staff_compact};\n\n    let ctx = TestContext::new(\"test_loader_self_join\");\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(staff::Entity)\n        .register(user::Entity)\n        .register(user_follower::Entity)\n        .apply(db)?;\n\n    let alan = staff::ActiveModel {\n        name: Set(\"Alan\".into()),\n        reports_to_id: Set(None),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    staff::ActiveModel {\n        name: Set(\"Ben\".into()),\n        reports_to_id: Set(Some(alan.id)),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    staff::ActiveModel {\n        name: Set(\"Alice\".into()),\n        reports_to_id: Set(Some(alan.id)),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    staff::ActiveModel {\n        name: Set(\"Elle\".into()),\n        reports_to_id: Set(None),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    let staff = staff::Entity::find()\n        .order_by_asc(staff::Column::Id)\n        .all(db)?;\n\n    let reports_to = staff.load_self(staff::Entity, staff::Relation::ReportsTo, db)?;\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(reports_to[0], None);\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(reports_to[1].as_ref().unwrap().name, \"Alan\");\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(reports_to[2].as_ref().unwrap().name, \"Alan\");\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(reports_to[3], None);\n\n    let manages = staff.load_self_many(\n        staff::Entity::find().order_by_asc(staff::COLUMN.id),\n        staff::Relation::ReportsTo,\n        db,\n    )?;\n\n    assert_eq!(\n        manages,\n        staff.load_self_many(\n            staff::Entity::find().order_by_asc(staff::COLUMN.id),\n            staff::Relation::Manages,\n            db,\n        )?\n    );\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(manages[0].len(), 2);\n    assert_eq!(manages[0][0].name, \"Ben\");\n    assert_eq!(manages[0][1].name, \"Alice\");\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(manages[1].len(), 0);\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(manages[2].len(), 0);\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(manages[3].len(), 0);\n\n    // test self_ref on compact_model\n\n    let staff = staff_compact::Entity::find()\n        .order_by_asc(staff_compact::COLUMN.id)\n        .all(db)?;\n\n    let reports_to = staff.load_self(\n        staff_compact::Entity,\n        staff_compact::Relation::ReportsTo,\n        db,\n    )?;\n\n    let manages = staff.load_self_many(\n        staff_compact::Entity::find().order_by_asc(staff_compact::COLUMN.id),\n        staff_compact::Relation::ReportsTo,\n        db,\n    )?;\n\n    assert_eq!(\n        manages,\n        staff.load_self_many(\n            staff_compact::Entity::find().order_by_asc(staff_compact::COLUMN.id),\n            staff_compact::Relation::Manages,\n            db,\n        )?\n    );\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(reports_to[0], None);\n    assert_eq!(manages[0].len(), 2);\n    assert_eq!(manages[0][0].name, \"Ben\");\n    assert_eq!(manages[0][1].name, \"Alice\");\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(reports_to.get(1).unwrap().as_ref().unwrap().name, \"Alan\");\n    assert_eq!(manages[1].len(), 0);\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(reports_to.get(2).unwrap().as_ref().unwrap().name, \"Alan\");\n    assert_eq!(manages[2].len(), 0);\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(reports_to[3], None);\n    assert_eq!(manages[3].len(), 0);\n\n    // self_ref + via\n\n    let alice = user::ActiveModel {\n        name: Set(\"Alice\".into()),\n        email: Set(\"@1\".into()),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    let bob = user::ActiveModel {\n        name: Set(\"Bob\".into()),\n        email: Set(\"@2\".into()),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    let sam = user::ActiveModel {\n        name: Set(\"Sam\".into()),\n        email: Set(\"@3\".into()),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    user_follower::ActiveModel {\n        user_id: Set(alice.id),\n        follower_id: Set(bob.id),\n    }\n    .insert(db)?;\n\n    user_follower::ActiveModel {\n        user_id: Set(alice.id),\n        follower_id: Set(sam.id),\n    }\n    .insert(db)?;\n\n    user_follower::ActiveModel {\n        user_id: Set(bob.id),\n        follower_id: Set(sam.id),\n    }\n    .insert(db)?;\n\n    let users = user::Entity::find().all(db)?;\n    let followers = users.load_self_via(user_follower::Entity, db)?;\n    let following = users.load_self_via_rev(user_follower::Entity, db)?;\n\n    assert_eq!(users[0], alice);\n    assert_eq!(followers[0], [bob.clone(), sam.clone()]);\n    assert!(following[0].is_empty());\n\n    assert_eq!(users[1], bob);\n    assert_eq!(followers[1], [sam.clone()]);\n    assert_eq!(following[1], [alice.clone()]);\n\n    assert_eq!(users[2], sam);\n    assert!(followers[2].is_empty());\n    assert_eq!(following[2], [alice, bob]);\n\n    Ok(())\n}\n\npub fn insert_bakery(db: &DbConn, name: &str) -> Result<bakery::Model, DbErr> {\n    bakery::ActiveModel {\n        name: Set(name.to_owned()),\n        profit_margin: Set(1.0),\n        ..Default::default()\n    }\n    .insert(db)\n}\n\npub fn insert_baker(db: &DbConn, name: &str, bakery_id: i32) -> Result<baker::Model, DbErr> {\n    baker::ActiveModel {\n        name: Set(name.to_owned()),\n        contact_details: Set(serde_json::json!({})),\n        bakery_id: Set(Some(bakery_id)),\n        ..Default::default()\n    }\n    .insert(db)\n}\n\npub fn insert_cake(db: &DbConn, name: &str, bakery_id: Option<i32>) -> Result<cake::Model, DbErr> {\n    cake::ActiveModel {\n        name: Set(name.to_owned()),\n        price: Set(rust_decimal::Decimal::ONE),\n        gluten_free: Set(false),\n        bakery_id: Set(bakery_id),\n        ..Default::default()\n    }\n    .insert(db)\n}\n\npub fn insert_cake_baker(\n    db: &DbConn,\n    baker_id: i32,\n    cake_id: i32,\n) -> Result<cakes_bakers::Model, DbErr> {\n    cakes_bakers::ActiveModel {\n        cake_id: Set(cake_id),\n        baker_id: Set(baker_id),\n    }\n    .insert(db)\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/multi_select_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\nmod common;\n\nuse crate::common::TestContext;\nuse sea_orm::{\n    Database, DbConn, DbErr,\n    entity::*,\n    query::*,\n    sea_query::{Expr, Query},\n};\n\nmod one {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"one\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(has_one)]\n        pub two: Option<super::two::Entity>,\n        #[sea_orm(has_one)]\n        pub six: Option<super::six::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod two {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"two\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub one_id: i32,\n        pub three_id: i32,\n        #[sea_orm(belongs_to, from = \"one_id\", to = \"id\")]\n        pub one: Option<super::one::Entity>,\n        #[sea_orm(belongs_to, from = \"three_id\", to = \"id\")]\n        pub three: Option<super::three::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod three {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"three\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(has_one)]\n        pub four: Option<super::four::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod four {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"four\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub three_id: Option<i32>,\n        #[sea_orm(belongs_to, from = \"three_id\", to = \"id\")]\n        pub three: Option<super::three::Entity>,\n        #[sea_orm(has_one)]\n        pub five: Option<super::five::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod five {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"five\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub four_id: i32,\n        #[sea_orm(belongs_to, from = \"four_id\", to = \"id\")]\n        pub four: Option<super::four::Entity>,\n        #[sea_orm(has_one)]\n        pub six: Option<super::six::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod six {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"six\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub one_id: i32,\n        pub five_id: i32,\n        #[sea_orm(belongs_to, from = \"one_id\", to = \"id\")]\n        pub one: Option<super::one::Entity>,\n        #[sea_orm(belongs_to, from = \"five_id\", to = \"id\")]\n        pub five: Option<super::five::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod composite_a {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"composite_a\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique_key = \"pair\")]\n        pub left_id: i32,\n        #[sea_orm(unique_key = \"pair\")]\n        pub right_id: i32,\n        #[sea_orm(has_one)]\n        pub b: Option<super::composite_b::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod composite_b {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"composite_b\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub left_id: i32,\n        pub right_id: i32,\n        #[sea_orm(belongs_to, from = \"(left_id, right_id)\", to = \"(left_id, right_id)\")]\n        pub a: Option<super::composite_a::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod composite_b_without_index {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"composite_b\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub left_id: i32,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod composite_c {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"composite_c\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique_key = \"season_episode\")]\n        pub season_number: i32,\n        #[sea_orm(unique_key = \"season_episode\")]\n        pub episode_number: i32,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[sea_orm_macros::test]\nfn test_select_six() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"test_select_six\");\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(one::Entity)\n        .register(two::Entity)\n        .register(three::Entity) // topologically three ranks higher than two\n        .register(four::Entity)\n        .register(five::Entity)\n        .register(six::Entity)\n        .apply(db)?;\n\n    one::ActiveModel { id: Set(1) }.insert(db)?;\n    one::ActiveModel { id: Set(11) }.insert(db)?;\n\n    three::ActiveModel { id: Set(3) }.insert(db)?;\n    three::ActiveModel { id: Set(33) }.insert(db)?;\n\n    two::ActiveModel {\n        id: Set(2),\n        one_id: Set(1),\n        three_id: Set(3),\n    }\n    .insert(db)?;\n\n    four::ActiveModel {\n        id: Set(4),\n        three_id: Set(Some(3)),\n    }\n    .insert(db)?;\n\n    four::ActiveModel {\n        id: Set(44),\n        three_id: Set(None),\n    }\n    .insert(db)?;\n\n    five::ActiveModel {\n        id: Set(5),\n        four_id: Set(4),\n    }\n    .insert(db)?;\n\n    five::ActiveModel {\n        id: Set(55),\n        four_id: Set(44),\n    }\n    .insert(db)?;\n\n    six::ActiveModel {\n        id: Set(6),\n        one_id: Set(1),\n        five_id: Set(55),\n    }\n    .insert(db)?;\n\n    let one = one::Entity::find().order_by_id_asc().one(db)?.unwrap();\n    assert_eq!(one.id, 1);\n\n    let two = two::Entity::find().order_by_id_asc().one(db)?.unwrap();\n    assert_eq!(two.id, 2);\n\n    let three = three::Entity::find().order_by_id_asc().one(db)?.unwrap();\n    assert_eq!(three.id, 3);\n\n    let four = four::Entity::find().order_by_id_asc().one(db)?.unwrap();\n    assert_eq!(four.id, 4);\n\n    let five = five::Entity::find().order_by_id_asc().one(db)?.unwrap();\n    assert_eq!(five.id, 5);\n\n    let six = six::Entity::find().order_by_id_asc().one(db)?.unwrap();\n    assert_eq!(six.id, 6);\n\n    let (one, two) = one::Entity::find()\n        .find_also(one::Entity, two::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(one.id, 1);\n    assert_eq!(two.unwrap().id, 2);\n\n    let (one, two, three) = one::Entity::find()\n        .find_also(one::Entity, two::Entity)\n        .find_also(two::Entity, three::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(one.id, 1);\n    assert_eq!(two.unwrap().id, 2);\n    assert_eq!(three.unwrap().id, 3);\n\n    let (two, one, three) = two::Entity::find()\n        .find_also_related(one::Entity)\n        .find_also_related(three::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(one.unwrap().id, 1);\n    assert_eq!(two.id, 2);\n    assert_eq!(three.unwrap().id, 3);\n\n    let (one, two, three, four) = one::Entity::find()\n        .find_also(one::Entity, two::Entity)\n        .find_also(two::Entity, three::Entity)\n        .find_also(three::Entity, four::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(one.id, 1);\n    assert_eq!(two.unwrap().id, 2);\n    assert_eq!(three.unwrap().id, 3);\n    assert_eq!(four.unwrap().id, 4);\n\n    let (one, two, three, six) = one::Entity::find()\n        .find_also(one::Entity, two::Entity)\n        .find_also(two::Entity, three::Entity)\n        .find_also(one::Entity, six::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(one.id, 1);\n    assert_eq!(two.unwrap().id, 2);\n    assert_eq!(three.unwrap().id, 3);\n    assert_eq!(six.unwrap().id, 6);\n\n    let (one, two, three, four, five) = one::Entity::find()\n        .find_also(one::Entity, two::Entity)\n        .find_also(two::Entity, three::Entity)\n        .find_also(three::Entity, four::Entity)\n        .find_also(four::Entity, five::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(one.id, 1);\n    assert_eq!(two.unwrap().id, 2);\n    assert_eq!(three.unwrap().id, 3);\n    assert_eq!(four.unwrap().id, 4);\n    assert_eq!(five.unwrap().id, 5);\n\n    let (one, two, three, four, five, six) = one::Entity::find()\n        .find_also(one::Entity, two::Entity)\n        .find_also(two::Entity, three::Entity)\n        .find_also(three::Entity, four::Entity)\n        .find_also(four::Entity, five::Entity)\n        .find_also(one::Entity, six::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(one.id, 1);\n    assert_eq!(two.unwrap().id, 2);\n    assert_eq!(three.unwrap().id, 3);\n    assert_eq!(four.unwrap().id, 4);\n    assert_eq!(five.unwrap().id, 5);\n    assert_eq!(six.unwrap().id, 6);\n\n    let (six, five, four) = six::Entity::find_by_id(6)\n        .find_also_related(five::Entity)\n        .and_also_related(four::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(four.unwrap().id, 44);\n    assert_eq!(five.unwrap().id, 55);\n    assert_eq!(six.id, 6);\n\n    let (four, five, six) = four::Entity::find_by_id(44)\n        .find_also_related(five::Entity)\n        .and_also_related(six::Entity)\n        .one(db)?\n        .unwrap();\n    assert_eq!(four.id, 44);\n    assert_eq!(five.unwrap().id, 55);\n    assert_eq!(six.unwrap().id, 6);\n\n    // below is EntityLoader\n\n    let one_ex = one::Entity::load().one(db)?.unwrap();\n    assert_eq!(one_ex.id, 1);\n\n    let one_ex = one::Entity::load().with(two::Entity).one(db)?.unwrap();\n    assert_eq!(one_ex.id, 1);\n    assert_eq!(one_ex.two.unwrap().id, 2);\n\n    let one_ex = one::Entity::load()\n        .with((two::Entity, three::Entity))\n        .one(db)?\n        .unwrap();\n    assert_eq!(one_ex.id, 1);\n    let two = one_ex.two.unwrap();\n    assert_eq!(two.id, 2);\n    assert_eq!(two.three.unwrap().id, 3);\n\n    let one_ex = one::Entity::load()\n        .with(six::Entity)\n        .with((two::Entity, three::Entity))\n        .one(db)?\n        .unwrap();\n    assert_eq!(one_ex.id, 1);\n    let two = one_ex.two.unwrap();\n    assert_eq!(two.id, 2);\n    assert_eq!(two.three.unwrap().id, 3);\n    let six = one_ex.six.unwrap();\n    assert_eq!(six.id, 6);\n\n    let one_ex = one::Entity::load()\n        .with((six::Entity, five::Entity))\n        .with((two::Entity, three::Entity))\n        .one(db)?\n        .unwrap();\n    assert_eq!(one_ex.id, 1);\n    let two = one_ex.two.unwrap();\n    assert_eq!(two.id, 2);\n    assert_eq!(two.three.unwrap().id, 3);\n    let six = one_ex.six.unwrap();\n    assert_eq!(six.id, 6);\n    assert_eq!(six.five.unwrap().id, 55);\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn test_composite_foreign_key() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"test_composite_foreign_key\");\n    let db = &ctx.db;\n\n    #[cfg(not(feature = \"schema-sync\"))]\n    {\n        db.get_schema_builder()\n            .register(composite_b::Entity)\n            .register(composite_a::Entity) // should create a first\n            .apply(db)?;\n    }\n\n    #[cfg(feature = \"schema-sync\")]\n    {\n        // create 1 table only\n        db.get_schema_builder()\n            .register(composite_a::Entity)\n            .apply(db)?;\n\n        // this incrementally creates the 2nd table without index\n        if db.get_database_backend() != sea_orm::DbBackend::Sqlite {\n            db.get_schema_builder()\n                .register(composite_a::Entity)\n                .register(composite_b_without_index::Entity)\n                .sync(db)?;\n        }\n\n        // this creates the full 2nd table\n        db.get_schema_builder()\n            .register(composite_a::Entity)\n            .register(composite_b::Entity)\n            .register(composite_c::Entity)\n            .sync(db)?;\n\n        // sync again just to be sure\n        db.get_schema_builder()\n            .register(composite_a::Entity)\n            .register(composite_b::Entity)\n            .register(composite_c::Entity)\n            .sync(db)?;\n\n        #[cfg(feature = \"sqlx-postgres\")]\n        {\n            let has_index: bool = db\n                .query_one(\n                    Query::select()\n                        .expr(Expr::cust(\"COUNT(*) > 0\"))\n                        .from(\"pg_indexes\")\n                        .cond_where(\n                            Condition::all()\n                                .add(Expr::cust(\"schemaname = CURRENT_SCHEMA()\"))\n                                .add(Expr::col(\"tablename\").eq(\"composite_c\"))\n                                .add(Expr::col(\"indexname\").eq(\"idx-composite_c-season_episode\")),\n                        ),\n                )?\n                .unwrap()\n                .try_get_by_index(0)\n                .unwrap();\n\n            assert!(has_index, \"Should have index on `composite_c`\");\n        }\n    }\n\n    composite_a::ActiveModel {\n        id: Set(100),\n        left_id: Set(1),\n        right_id: Set(2),\n    }\n    .insert(db)?;\n    composite_a::ActiveModel {\n        id: Set(101),\n        left_id: Set(1),\n        right_id: Set(3),\n    }\n    .insert(db)?;\n    composite_a::ActiveModel {\n        id: Set(102),\n        left_id: Set(2),\n        right_id: Set(3),\n    }\n    .insert(db)?;\n    composite_b::ActiveModel {\n        id: Set(200),\n        left_id: Set(1),\n        right_id: Set(2),\n    }\n    .insert(db)?;\n    composite_b::ActiveModel {\n        id: Set(202),\n        left_id: Set(2),\n        right_id: Set(3),\n    }\n    .insert(db)?;\n\n    let a = composite_a::Entity::find_by_id(100).one(db)?.unwrap();\n    assert_eq!(a.left_id, 1);\n    assert_eq!(a.right_id, 2);\n    #[rustfmt::skip]\n    assert_eq!(composite_a::Entity::find_by_pair((1, 3)).one(db)?.unwrap().id, 101);\n    #[rustfmt::skip]\n    assert_eq!(composite_a::Entity::load().filter_by_pair((1, 3)).one(db)?.unwrap().id, 101);\n\n    let Some((a, Some(b))) = composite_a::Entity::find_by_id(100)\n        .find_also_related(composite_b::Entity)\n        .one(db)?\n    else {\n        panic!(\"query error\")\n    };\n    assert_eq!(a.left_id, 1);\n    assert_eq!(a.right_id, 2);\n    assert_eq!(b.id, 200);\n    assert_eq!(b.left_id, 1);\n    assert_eq!(b.right_id, 2);\n\n    let a = composite_a::Entity::load()\n        .filter_by_id(101)\n        .with(composite_b::Entity)\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(a.id, 101);\n    assert!(a.b.is_not_found());\n\n    let a = composite_a::Entity::load()\n        .filter_by_id(102)\n        .with(composite_b::Entity)\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(a.id, 102);\n    assert_eq!(a.left_id, 2);\n    assert_eq!(a.right_id, 3);\n    assert_eq!(a.b.unwrap().id, 202);\n\n    assert_eq!(\n        composite_b::Entity::delete_by_id(202)\n            .exec(db)?\n            .rows_affected,\n        1\n    );\n\n    assert_eq!(\n        composite_a::Entity::delete_by_pair((2, 3))\n            .exec(db)?\n            .rows_affected,\n        1\n    );\n\n    assert!(composite_a::Entity::find_by_id(102).one(db)?.is_none());\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/paginator_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{PaginatorTrait, QueryOrder, Set, entity::prelude::*};\n\n#[sea_orm_macros::test]\nfn paginator_tests() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"paginator_tests\");\n    create_insert_default_table(&ctx.db)?;\n    create_insert_default(&ctx.db)?;\n    paginator_num_items(&ctx.db)?;\n    paginator_num_pages(&ctx.db)?;\n    paginator_num_items_and_pages(&ctx.db)?;\n    paginator_fetch_page(&ctx.db)?;\n    paginator_count(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    for _ in 0..10 {\n        ActiveModel {\n            ..Default::default()\n        }\n        .insert(db)?;\n    }\n\n    assert_eq!(\n        Entity::find().all(db)?,\n        [\n            Model { id: 1 },\n            Model { id: 2 },\n            Model { id: 3 },\n            Model { id: 4 },\n            Model { id: 5 },\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    Ok(())\n}\n\npub fn paginator_num_items(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 3);\n    assert_eq!(paginator.num_items()?, 10);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 5);\n    assert_eq!(paginator.num_items()?, 10);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 10);\n    assert_eq!(paginator.num_items()?, 10);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 100);\n    assert_eq!(paginator.num_items()?, 10);\n\n    Ok(())\n}\n\npub fn paginator_num_pages(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 3);\n    assert_eq!(paginator.num_pages()?, 4);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 5);\n    assert_eq!(paginator.num_pages()?, 2);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 10);\n    assert_eq!(paginator.num_pages()?, 1);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 7);\n    assert_eq!(paginator.num_pages()?, 2);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 100);\n    assert_eq!(paginator.num_pages()?, 1);\n\n    Ok(())\n}\n\npub fn paginator_num_items_and_pages(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 3);\n\n    let result = paginator.num_items_and_pages()?;\n    assert_eq!(result.number_of_items, 10);\n    assert_eq!(result.number_of_pages, 4);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 5);\n\n    let result = paginator.num_items_and_pages()?;\n    assert_eq!(result.number_of_items, 10);\n    assert_eq!(result.number_of_pages, 2);\n\n    Ok(())\n}\n\npub fn paginator_fetch_page(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 3);\n\n    assert_eq!(\n        paginator.fetch_page(0)?,\n        vec![Model { id: 1 }, Model { id: 2 }, Model { id: 3 }]\n    );\n\n    assert_eq!(\n        paginator.fetch_page(1)?,\n        vec![Model { id: 4 }, Model { id: 5 }, Model { id: 6 }]\n    );\n\n    assert_eq!(\n        paginator.fetch_page(2)?,\n        vec![Model { id: 7 }, Model { id: 8 }, Model { id: 9 }]\n    );\n\n    assert_eq!(paginator.fetch_page(3)?, vec![Model { id: 10 }]);\n\n    assert!(paginator.fetch_page(4)?.is_empty());\n\n    Ok(())\n}\n\npub fn paginator_count(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    assert_eq!(Entity::find().count(db)?, 10);\n\n    assert_eq!(Entity::find().filter(Column::Id.gt(5)).count(db)?, 5);\n\n    assert_eq!(Entity::find().filter(Column::Id.lte(3)).count(db)?, 3);\n\n    assert_eq!(Entity::find().filter(Column::Id.gt(100)).count(db)?, 0);\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/parallel_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, IntoActiveModel, Set, entity::prelude::*};\n\n#[sea_orm_macros::test]\n#[cfg(not(feature = \"sync\"))]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"features_parallel_tests\");\n    create_metadata_table(&ctx.db)?;\n    crud_in_parallel(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\n#[cfg(not(feature = \"sync\"))]\npub fn crud_in_parallel(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let metadata = [\n        metadata::Model {\n            uuid: Uuid::new_v4(),\n            ty: \"Type\".to_owned(),\n            key: \"markup\".to_owned(),\n            value: \"1.18\".to_owned(),\n            bytes: vec![1, 2, 3],\n            date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()),\n            time: Some(Time::from_hms_opt(11, 32, 55).unwrap()),\n        },\n        metadata::Model {\n            uuid: Uuid::new_v4(),\n            ty: \"Type\".to_owned(),\n            key: \"exchange_rate\".to_owned(),\n            value: \"0.78\".to_owned(),\n            bytes: vec![1, 2, 3],\n            date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()),\n            time: Some(Time::from_hms_opt(11, 32, 55).unwrap()),\n        },\n        metadata::Model {\n            uuid: Uuid::new_v4(),\n            ty: \"Type\".to_owned(),\n            key: \"service_charge\".to_owned(),\n            value: \"1.1\".to_owned(),\n            bytes: vec![1, 2, 3],\n            date: None,\n            time: None,\n        },\n    ];\n\n    let _insert_res = futures_util::future::try_join_all([\n        metadata[0].clone().into_active_model().insert(db),\n        metadata[1].clone().into_active_model().insert(db),\n        metadata[2].clone().into_active_model().insert(db),\n    ])?;\n\n    let find_res = futures_util::future::try_join_all([\n        Metadata::find_by_id(metadata[0].uuid).one(db),\n        Metadata::find_by_id(metadata[1].uuid).one(db),\n        Metadata::find_by_id(metadata[2].uuid).one(db),\n    ])?;\n\n    assert_eq!(\n        metadata,\n        [\n            find_res[0].clone().unwrap(),\n            find_res[1].clone().unwrap(),\n            find_res[2].clone().unwrap(),\n        ]\n    );\n\n    let mut active_models = (\n        find_res[0].clone().unwrap().into_active_model(),\n        find_res[1].clone().unwrap().into_active_model(),\n        find_res[2].clone().unwrap().into_active_model(),\n    );\n\n    active_models.0.bytes = Set(vec![0]);\n    active_models.1.bytes = Set(vec![1]);\n    active_models.2.bytes = Set(vec![2]);\n\n    let _update_res = futures_util::future::try_join_all([\n        active_models.0.clone().update(db),\n        active_models.1.clone().update(db),\n        active_models.2.clone().update(db),\n    ])?;\n\n    let find_res = futures_util::future::try_join_all([\n        Metadata::find_by_id(metadata[0].uuid).one(db),\n        Metadata::find_by_id(metadata[1].uuid).one(db),\n        Metadata::find_by_id(metadata[2].uuid).one(db),\n    ])?;\n\n    assert_eq!(\n        [\n            active_models.0.bytes.clone().unwrap(),\n            active_models.1.bytes.clone().unwrap(),\n            active_models.2.bytes.clone().unwrap(),\n        ],\n        [\n            find_res[0].clone().unwrap().bytes,\n            find_res[1].clone().unwrap().bytes,\n            find_res[2].clone().unwrap().bytes,\n        ]\n    );\n\n    let _delete_res = futures_util::future::try_join_all([\n        active_models.0.delete(db),\n        active_models.1.delete(db),\n        active_models.2.delete(db),\n    ])?;\n\n    assert_eq!(Metadata::find().all(db)?, []);\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/partial_model_nested/local/mod.rs",
    "content": "mod model;\n\npub use model::*;\n\npub use model::schema::create_tables;\n"
  },
  {
    "path": "sea-orm-sync/tests/partial_model_nested/local/model/bakery.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bakery\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub profit_margin: f64,\n    pub manager_id: i32,\n    pub cashier_id: i32,\n    #[sea_orm(belongs_to, relation_enum = \"Manager\", from = \"manager_id\", to = \"id\")]\n    pub manager: HasOne<super::worker::Entity>,\n    #[sea_orm(belongs_to, relation_enum = \"Cashier\", from = \"cashier_id\", to = \"id\")]\n    pub cashier: HasOne<super::worker::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/partial_model_nested/local/model/mod.rs",
    "content": "pub mod bakery;\npub mod schema;\npub mod worker;\n"
  },
  {
    "path": "sea-orm-sync/tests/partial_model_nested/local/model/schema.rs",
    "content": "use crate::common::setup::create_table;\nuse crate::local::{bakery, worker};\nuse sea_orm::{DatabaseConnection, DbConn, ExecResult, error::*, sea_query};\nuse sea_query::{ColumnDef, ForeignKey, ForeignKeyAction, Index, Table};\n\npub fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> {\n    create_worker_table(db)?;\n    create_bakery_table(db)?;\n    Ok(())\n}\n\npub fn create_bakery_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(bakery::Entity)\n        .col(\n            ColumnDef::new(bakery::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(bakery::Column::Name).string().not_null())\n        .col(\n            ColumnDef::new(bakery::Column::ProfitMargin)\n                .double()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(bakery::Column::ManagerId)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(bakery::Column::CashierId)\n                .integer()\n                .not_null(),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-bakery-manager_id\")\n                .from(bakery::Entity, bakery::Column::ManagerId)\n                .to(worker::Entity, worker::Column::Id),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-bakery-cashier_id\")\n                .from(bakery::Entity, bakery::Column::CashierId)\n                .to(worker::Entity, worker::Column::Id),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, bakery::Entity)\n}\n\npub fn create_worker_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(worker::Entity)\n        .col(\n            ColumnDef::new(worker::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(worker::Column::Name).string().not_null())\n        .to_owned();\n\n    create_table(db, &stmt, worker::Entity)\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/partial_model_nested/local/model/worker.rs",
    "content": "use sea_orm::{ActiveValue, entity::prelude::*};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"worker\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(has_many, relation_enum = \"BakeryManager\", via_rel = \"Manager\")]\n    pub manager_of: HasMany<super::bakery::Entity>,\n    #[sea_orm(has_many, relation_enum = \"BakeryCashier\", via_rel = \"Cashier\")]\n    pub cashier_of: HasMany<super::bakery::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "sea-orm-sync/tests/partial_model_nested/main.rs",
    "content": "mod local;\nmod nested_alias;\n\n#[path = \"../common/mod.rs\"]\n#[allow(unused)]\nmod common;\n"
  },
  {
    "path": "sea-orm-sync/tests/partial_model_nested/nested_alias.rs",
    "content": "use crate::common::TestContext;\nuse crate::local::{bakery, create_tables, worker};\nuse sea_orm::{\n    DbBackend, DerivePartialModel, IntoActiveModel, JoinType, NotSet, QueryOrder, QuerySelect,\n    QueryTrait, Set, prelude::*, sea_query::Alias,\n};\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"worker::Entity\")]\nstruct Worker {\n    id: i32,\n    name: String,\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"bakery::Entity\")]\nstruct BakeryWorker {\n    id: i32,\n    name: String,\n    profit_margin: f64,\n    #[sea_orm(nested, alias = \"manager\")]\n    manager: Worker,\n    #[sea_orm(nested, alias = \"cashier\")]\n    cashier: worker::Model,\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"worker::Entity\")]\nstruct ManagerOfBakery {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: bakery::Model,\n}\n\n#[sea_orm_macros::test]\nfn partial_model_nested_alias() {\n    let ctx = TestContext::new(\"partial_model_nested\");\n    create_tables(&ctx.db).expect(\"unable to create tables\");\n\n    // TODO: init utils\n\n    worker::Entity::insert(worker::ActiveModel {\n        id: Set(1),\n        name: Set(\"Tom\".to_owned()),\n        ..Default::default()\n    })\n    .exec(&ctx.db)\n    .expect(\"insert succeeds\");\n\n    worker::Entity::insert(worker::ActiveModel {\n        id: Set(2),\n        name: Set(\"Jerry\".to_owned()),\n        ..Default::default()\n    })\n    .exec(&ctx.db)\n    .expect(\"insert succeeds\");\n\n    bakery::Entity::insert(bakery::ActiveModel {\n        id: Set(42),\n        name: Set(\"Master Bakery\".to_string()),\n        profit_margin: Set(4.1),\n        manager_id: Set(1),\n        cashier_id: Set(2),\n    })\n    .exec(&ctx.db)\n    .expect(\"insert succeeds\");\n\n    let selector = bakery::Entity::find()\n        .join_as(\n            sea_orm::JoinType::LeftJoin,\n            bakery::Relation::Manager.def(),\n            \"manager\",\n        )\n        .join_as(\n            sea_orm::JoinType::LeftJoin,\n            bakery::Relation::Cashier.def(),\n            \"cashier\",\n        );\n\n    assert_eq!(\n        selector.build(DbBackend::MySql).to_string(),\n        \"SELECT `bakery`.`id`, `bakery`.`name`, `bakery`.`profit_margin`, `bakery`.`manager_id`, `bakery`.`cashier_id` FROM `bakery` LEFT JOIN `worker` AS `manager` ON `bakery`.`manager_id` = `manager`.`id` LEFT JOIN `worker` AS `cashier` ON `bakery`.`cashier_id` = `cashier`.`id`\"\n    );\n\n    let bakery: BakeryWorker = selector\n        .into_partial_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.manager.name, \"Tom\");\n    assert_eq!(bakery.cashier.name, \"Jerry\");\n\n    let selector = worker::Entity::find().join(\n        sea_orm::JoinType::LeftJoin,\n        worker::Relation::BakeryManager.def(),\n    );\n\n    assert_eq!(\n        selector.build(DbBackend::MySql).to_string(),\n        \"SELECT `worker`.`id`, `worker`.`name` FROM `worker` LEFT JOIN `bakery` ON `worker`.`id` = `bakery`.`manager_id`\"\n    );\n\n    let manager: ManagerOfBakery = selector\n        .into_partial_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(manager.name, \"Tom\");\n    assert_eq!(manager.bakery.name, \"Master Bakery\");\n\n    ctx.delete();\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/partial_model_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\nuse entity::{Column, Entity};\nuse sea_orm::{\n    DerivePartialModel, IntoActiveModel, JoinType, NotSet, QueryOrder, QuerySelect, Set,\n    prelude::*, sea_query::Alias,\n};\nuse sea_query::ExprTrait;\n\nuse crate::common::TestContext;\nuse common::bakery_chain::*;\n\nmod common;\n\nmod entity {\n    use sea_orm::prelude::*;\n\n    #[derive(Debug, Clone, DeriveEntityModel)]\n    #[sea_orm(table_name = \"foo_table\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        id: i32,\n        foo: i32,\n        bar: String,\n        foo2: bool,\n        bar2: f64,\n    }\n\n    #[derive(Debug, DeriveRelation, EnumIter)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"Entity\")]\nstruct SimpleTest {\n    foo: i32,\n    bar: String,\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"<entity::Model as ModelTrait>::Entity\")]\nstruct EntityNameNotAIdent {\n    #[sea_orm(from_col = \"foo2\")]\n    foo: i32,\n    #[sea_orm(from_col = \"bar2\")]\n    bar: String,\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"Entity\")]\nstruct FieldFromDiffNameColumnTest {\n    #[sea_orm(from_col = \"foo2\")]\n    foo: i32,\n    #[sea_orm(from_col = \"bar2\")]\n    bar: String,\n}\n\n#[derive(DerivePartialModel)]\nstruct FieldFromExpr {\n    #[sea_orm(from_expr = \"Column::Bar2.sum()\")]\n    foo: f64,\n    #[sea_orm(from_expr = \"Expr::col(Column::Id).equals(Column::Foo)\")]\n    bar: bool,\n}\n\n#[derive(DerivePartialModel)]\nstruct Nest {\n    #[sea_orm(nested)]\n    foo: SimpleTest,\n}\n\n#[derive(DerivePartialModel)]\nstruct NestOption {\n    #[sea_orm(nested)]\n    foo: Option<SimpleTest>,\n}\n\n#[derive(Debug, DerivePartialModel)]\n#[sea_orm(entity = \"bakery::Entity\")]\nstruct Bakery {\n    id: i32,\n    #[sea_orm(from_col = \"Name\")]\n    title: String,\n}\n\n#[derive(Debug, DerivePartialModel)]\n#[sea_orm(entity = \"cake::Entity\", into_active_model)]\nstruct Cake {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<Bakery>,\n    #[sea_orm(skip)]\n    ignore: Ignore,\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"bakery::Entity\")]\nstruct BakeryDetails {\n    #[sea_orm(nested)]\n    basics: Bakery,\n    #[sea_orm(from_expr = \"bakery::Column::ProfitMargin\")]\n    profit: f64,\n}\n\n#[derive(Debug, Default, PartialEq, Eq)]\nstruct Ignore {}\n\n#[sea_orm_macros::test]\nfn partial_model_left_join_does_not_exist() {\n    let ctx = TestContext::new(\"partial_model_left_join_does_not_exist\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, false);\n\n    let cake: Cake = cake::Entity::find()\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert!(cake.bakery.is_none());\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn partial_model_left_join_exists() {\n    let ctx = TestContext::new(\"partial_model_left_join_exists\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    let cake: Cake = cake::Entity::find()\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert!(matches!(cake.bakery, Some(Bakery { id: 42, .. })));\n    assert_eq!(cake.bakery.as_ref().unwrap().title, \"cool little bakery\");\n\n    #[derive(Debug, DerivePartialModel)]\n    #[sea_orm(entity = \"cake::Entity\", into_active_model)]\n    struct Cake2 {\n        id: i32,\n        name: String,\n        #[sea_orm(nested, alias = \"r0\")]\n        bakery: Option<Bakery>,\n        #[sea_orm(skip)]\n        ignore: Ignore,\n    }\n\n    let cake2: Cake2 = cake::Entity::find()\n        .left_join_linked(cake::ToBakery)\n        .order_by_asc(cake::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(\n        format!(\"{cake:?}\").trim_start_matches(\"Cake \"),\n        format!(\"{cake2:?}\").trim_start_matches(\"Cake2 \")\n    );\n\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"cake::Entity\")]\n    struct Cake3 {\n        id: i32,\n        name: String,\n        #[sea_orm(nested)]\n        bakery: Option<bakery::Model>,\n    }\n\n    let cake: Cake3 = cake::Entity::find()\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert_eq!(\n        cake.bakery.unwrap(),\n        bakery::Model {\n            id: 42,\n            name: \"cool little bakery\".to_string(),\n            profit_margin: 4.1,\n        }\n    );\n\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"cake::Entity\")]\n    struct Cake4 {\n        id: i32,\n        price: Decimal,\n        #[sea_orm(from_expr = \"cake::COLUMN.price.add(\\\"0.2\\\".parse::<Decimal>().unwrap())\")]\n        price_vat: Decimal,\n    }\n\n    let cake: Cake4 = cake::Entity::find()\n        .order_by_asc(cake::COLUMN.id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.price, \"2\".parse().unwrap());\n    assert_eq!(cake.price_vat, \"2.2\".parse().unwrap());\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn model_as_partial_model() {\n    let ctx = TestContext::new(\"model_as_partial_model\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, false);\n\n    let bakery: bakery::Model = bakery::Entity::find()\n        .order_by_asc(bakery::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(\n        bakery,\n        bakery::Model {\n            id: 42,\n            name: \"cool little bakery\".to_string(),\n            profit_margin: 4.1,\n        }\n    );\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn partial_model_left_join_alias() {\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"bakery::Entity\")]\n    struct Factory {\n        id: i32,\n        #[sea_orm(from_col = \"name\")]\n        plant: String,\n    }\n\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"cake::Entity\")]\n    struct CakeFactory {\n        id: i32,\n        name: String,\n        #[sea_orm(nested, alias = \"factory\")]\n        bakery: Option<Factory>,\n    }\n\n    // SELECT \"cake\".\"id\" AS \"id\", \"cake\".\"name\" AS \"name\", \"factory\".\"id\" AS \"bakery_id\", \"factory\".\"name\" AS \"bakery_plant\" FROM \"cake\" LEFT JOIN \"bakery\" AS \"factory\" ON \"cake\".\"bakery_id\" = \"factory\".\"id\" LIMIT 1\n    let ctx = TestContext::new(\"partial_model_left_join_alias\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    let cake: CakeFactory = cake::Entity::find()\n        .join_as(JoinType::LeftJoin, cake::Relation::Bakery.def(), \"factory\")\n        .order_by_asc(cake::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert!(matches!(cake.bakery, Some(Factory { id: 42, .. })));\n    assert_eq!(cake.bakery.unwrap().plant, \"cool little bakery\");\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn partial_model_left_join_alias_old() {\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"bakery::Entity\", alias = \"factory\")]\n    struct Factory {\n        id: i32,\n        #[sea_orm(from_col = \"name\")]\n        plant: String,\n    }\n\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"cake::Entity\")]\n    struct CakeFactory {\n        id: i32,\n        name: String,\n        #[sea_orm(nested)]\n        bakery: Option<Factory>,\n    }\n\n    let ctx = TestContext::new(\"partial_model_left_join_alias_old\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    let cake: CakeFactory = cake::Entity::find()\n        .join_as(JoinType::LeftJoin, cake::Relation::Bakery.def(), \"factory\")\n        .order_by_asc(cake::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert!(matches!(cake.bakery, Some(Factory { id: 42, .. })));\n    assert_eq!(cake.bakery.unwrap().plant, \"cool little bakery\");\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn partial_model_flat() {\n    let ctx = TestContext::new(\"partial_model_flat\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    let bakery: Bakery = bakery::Entity::find()\n        .into_partial_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.title, \"cool little bakery\");\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn partial_model_nested() {\n    // SELECT \"bakery\".\"id\" AS \"basics_id\", \"bakery\".\"name\" AS \"basics_title\", \"bakery\".\"profit_margin\" AS \"profit\" FROM \"bakery\" LIMIT 1\n    let ctx = TestContext::new(\"partial_model_nested\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    let bakery: BakeryDetails = bakery::Entity::find()\n        .into_partial_model()\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.basics.id, 42);\n    assert_eq!(bakery.basics.title, \"cool little bakery\");\n    assert_eq!(bakery.profit, 4.1);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn partial_model_join_three() {\n    let ctx = TestContext::new(\"partial_model_join_three\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"order::Entity\")]\n    struct OrderItem {\n        id: i32,\n        total: Decimal,\n        #[sea_orm(nested)]\n        customer: Customer,\n        #[sea_orm(nested)]\n        line: LineItem,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"customer::Entity\")]\n    struct Customer {\n        name: String,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"lineitem::Entity\")]\n    struct LineItem {\n        price: Decimal,\n        quantity: i32,\n        #[sea_orm(nested)]\n        cake: Cake,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"cake::Entity\")]\n    struct Cake {\n        name: String,\n    }\n\n    let items: Vec<OrderItem> = order::Entity::find()\n        .left_join(customer::Entity)\n        .left_join(lineitem::Entity)\n        .join(JoinType::LeftJoin, lineitem::Relation::Cake.def())\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .into_partial_model()\n        .all(&ctx.db)\n        .unwrap();\n\n    assert_eq!(\n        items,\n        [\n            OrderItem {\n                id: 101,\n                total: Decimal::from(10),\n                customer: Customer {\n                    name: \"Bob\".to_owned()\n                },\n                line: LineItem {\n                    cake: Cake {\n                        name: \"Cheesecake\".to_owned()\n                    },\n                    price: Decimal::from(2),\n                    quantity: 2,\n                }\n            },\n            OrderItem {\n                id: 101,\n                total: Decimal::from(10),\n                customer: Customer {\n                    name: \"Bob\".to_owned()\n                },\n                line: LineItem {\n                    cake: Cake {\n                        name: \"Chocolate\".to_owned()\n                    },\n                    price: Decimal::from(3),\n                    quantity: 2,\n                }\n            }\n        ]\n    );\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn partial_model_join_three_flat() {\n    let ctx = TestContext::new(\"partial_model_join_three_flat\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"order::Entity\")]\n    struct OrderItem {\n        #[sea_orm(nested)]\n        order: Order,\n        #[sea_orm(nested)]\n        customer: Customer,\n        #[sea_orm(nested)]\n        line: LineItem,\n        #[sea_orm(nested)]\n        cake: Cake,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"order::Entity\")]\n    struct Order {\n        #[sea_orm(from_col = \"id\")]\n        order_id: i32,\n        total: Decimal,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"customer::Entity\")]\n    struct Customer {\n        name: String,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"lineitem::Entity\")]\n    struct LineItem {\n        price: Decimal,\n        quantity: i32,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"cake::Entity\")]\n    struct Cake {\n        name: String,\n    }\n\n    let items: Vec<OrderItem> = order::Entity::find()\n        .left_join(customer::Entity)\n        .left_join(lineitem::Entity)\n        .join(JoinType::LeftJoin, lineitem::Relation::Cake.def())\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .into_partial_model()\n        .all(&ctx.db)\n        .unwrap();\n\n    assert_eq!(\n        items,\n        [\n            OrderItem {\n                order: Order {\n                    order_id: 101,\n                    total: Decimal::from(10),\n                },\n                customer: Customer {\n                    name: \"Bob\".to_owned()\n                },\n                line: LineItem {\n                    price: Decimal::from(2),\n                    quantity: 2,\n                },\n                cake: Cake {\n                    name: \"Cheesecake\".to_owned()\n                },\n            },\n            OrderItem {\n                order: Order {\n                    order_id: 101,\n                    total: Decimal::from(10),\n                },\n                customer: Customer {\n                    name: \"Bob\".to_owned()\n                },\n                line: LineItem {\n                    price: Decimal::from(3),\n                    quantity: 2,\n                },\n                cake: Cake {\n                    name: \"Chocolate\".to_owned()\n                },\n            }\n        ]\n    );\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn partial_model_join_two_linked() {\n    let ctx = TestContext::new(\"partial_model_join_two_linked\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"order::Entity\")]\n    struct OrderItem {\n        #[sea_orm(nested)]\n        order: Order,\n        #[sea_orm(nested, alias = \"r0\")]\n        customer: Customer,\n        #[sea_orm(nested, alias = \"r1\")]\n        line: LineItem,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"order::Entity\")]\n    struct Order {\n        #[sea_orm(from_col = \"id\")]\n        order_id: i32,\n        total: Decimal,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"customer::Entity\")]\n    struct Customer {\n        name: String,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"lineitem::Entity\")]\n    struct LineItem {\n        price: Decimal,\n        quantity: i32,\n    }\n\n    let items: Vec<OrderItem> = order::Entity::find()\n        .left_join_linked(order::ToCustomer)\n        .left_join_linked(order::ToLineitem)\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(Expr::col((\"r1\", lineitem::Column::Id)))\n        .into_partial_model()\n        .all(&ctx.db)\n        .unwrap();\n\n    assert_eq!(\n        items,\n        [\n            OrderItem {\n                order: Order {\n                    order_id: 101,\n                    total: Decimal::from(10),\n                },\n                customer: Customer {\n                    name: \"Bob\".to_owned()\n                },\n                line: LineItem {\n                    price: Decimal::from(2),\n                    quantity: 2,\n                },\n            },\n            OrderItem {\n                order: Order {\n                    order_id: 101,\n                    total: Decimal::from(10),\n                },\n                customer: Customer {\n                    name: \"Bob\".to_owned()\n                },\n                line: LineItem {\n                    price: Decimal::from(3),\n                    quantity: 2,\n                },\n            }\n        ]\n    );\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\nfn partial_model_into_active_model() {\n    let mut cake = Cake {\n        id: 12,\n        name: \"Lemon Drizzle\".to_owned(),\n        bakery: None,\n        ignore: Ignore {},\n    }\n    .into_active_model();\n    cake.serial = NotSet;\n\n    assert_eq!(\n        cake,\n        cake::ActiveModel {\n            id: Set(12),\n            name: Set(\"Lemon Drizzle\".to_owned()),\n            serial: NotSet,\n            ..Default::default()\n        }\n    );\n\n    assert_eq!(\n        cake::ActiveModel {\n            ..cake.into_active_model()\n        },\n        cake::ActiveModel {\n            id: Set(12),\n            name: Set(\"Lemon Drizzle\".to_owned()),\n            serial: NotSet,\n            ..Default::default()\n        }\n    );\n}\n\n#[derive(Debug, DerivePartialModel)]\n#[sea_orm(entity = \"bakery::Entity\")]\nstruct WrongBakery {\n    id: String,\n    #[sea_orm(from_col = \"Name\")]\n    title: String,\n}\n\n#[derive(Debug, DerivePartialModel)]\n#[sea_orm(entity = \"cake::Entity\")]\nstruct WrongCake {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<WrongBakery>,\n}\n\n#[sea_orm_macros::test]\n#[ignore = \"This currently does not work, as sqlx does not perform type checking when a column is absent..\"]\nfn partial_model_optional_field_but_type_error() {\n    let ctx = TestContext::new(\"partial_model_nested\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, false);\n\n    let _: DbErr = cake::Entity::find()\n        .left_join(bakery::Entity)\n        .into_partial_model::<WrongCake>()\n        .one(&ctx.db)\n        .expect_err(\"should error instead of returning an empty Option\");\n\n    ctx.delete();\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/pi_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\nuse std::str::FromStr;\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"with-bigdecimal\")]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"pi_tests\");\n    create_pi_table(&ctx.db)?;\n    create_and_update_pi(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\n#[cfg(feature = \"with-bigdecimal\")]\npub fn create_and_update_pi(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use pi::Entity as Pi;\n\n    fn trunc_dec_scale(mut model: pi::Model) -> pi::Model {\n        model.decimal = model.decimal.trunc_with_scale(3);\n        model.big_decimal = model.big_decimal.with_scale(3);\n        model.decimal_opt = model.decimal_opt.map(|decimal| decimal.trunc_with_scale(3));\n        model.big_decimal_opt = model\n            .big_decimal_opt\n            .map(|big_decimal| big_decimal.with_scale(3));\n        model\n    }\n\n    let pi = trunc_dec_scale(pi::Model {\n        id: 1,\n        decimal: rust_dec(3.1415926536),\n        big_decimal: BigDecimal::from_str(\"3.1415926536\").unwrap(),\n        decimal_opt: None,\n        big_decimal_opt: None,\n    });\n\n    let res = trunc_dec_scale(pi.clone().into_active_model().insert(db)?);\n\n    let model = trunc_dec_scale(Pi::find().one(db)?.unwrap());\n    assert_eq!(model, res);\n    assert_eq!(model, pi.clone());\n\n    let res = trunc_dec_scale(\n        pi::ActiveModel {\n            decimal_opt: Set(Some(rust_dec(3.1415926536))),\n            big_decimal_opt: Set(Some(BigDecimal::from_str(\"3.1415926536\").unwrap())),\n            ..pi.clone().into_active_model()\n        }\n        .update(db)?,\n    );\n\n    let model = trunc_dec_scale(Pi::find().one(db)?.unwrap());\n    assert_eq!(model, res);\n    assert_eq!(\n        model,\n        trunc_dec_scale(pi::Model {\n            id: 1,\n            decimal: rust_dec(3.1415926536),\n            big_decimal: BigDecimal::from_str(\"3.1415926536\").unwrap(),\n            decimal_opt: Some(rust_dec(3.1415926536)),\n            big_decimal_opt: Some(BigDecimal::from_str(\"3.1415926536\").unwrap()),\n        })\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/query_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, bakery_dense, setup::*};\npub use sea_orm::entity::*;\npub use sea_orm::{ConnectionTrait, QueryFilter, QuerySelect};\n\n// Run the test locally:\n// DATABASE_URL=\"mysql://root:@localhost\" cargo test --features sqlx-mysql,runtime-async-std --test query_tests\n#[sea_orm_macros::test]\npub fn find_one_with_no_result() {\n    let ctx = TestContext::new(\"find_one_with_no_result\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let bakery = Bakery::find().one(&ctx.db).unwrap();\n    assert_eq!(bakery, None);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn find_one_with_result() {\n    let ctx = TestContext::new(\"find_one_with_result\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let result = Bakery::find().one(&ctx.db).unwrap().unwrap();\n\n    assert_eq!(result.id, bakery.id.unwrap());\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn find_by_id_with_no_result() {\n    let ctx = TestContext::new(\"find_by_id_with_no_result\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let bakery = Bakery::find_by_id(999).one(&ctx.db).unwrap();\n    assert_eq!(bakery, None);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn find_by_id_with_result() {\n    let ctx = TestContext::new(\"find_by_id_with_result\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let result = Bakery::find_by_id(bakery.id.clone().unwrap())\n        .one(&ctx.db)\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(result.id, bakery.id.unwrap());\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn find_all_with_no_result() {\n    let ctx = TestContext::new(\"find_all_with_no_result\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let bakeries = Bakery::find().all(&ctx.db).unwrap();\n    assert_eq!(bakeries.len(), 0);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn find_all_with_result() {\n    let ctx = TestContext::new(\"find_all_with_result\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let _ = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let _ = bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let bakeries = Bakery::find().all(&ctx.db).unwrap();\n\n    assert_eq!(bakeries.len(), 2);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn find_all_filter_no_result() {\n    let ctx = TestContext::new(\"find_all_filter_no_result\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let _ = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let _ = bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let bakeries = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Good\"))\n        .all(&ctx.db)\n        .unwrap();\n\n    assert_eq!(bakeries.len(), 0);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn find_all_filter_with_results() {\n    let ctx = TestContext::new(\"find_all_filter_with_results\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let _ = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let _ = bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let bakeries = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Bakery\"))\n        .all(&ctx.db)\n        .unwrap();\n\n    assert_eq!(bakeries.len(), 2);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn select_only_exclude_option_fields() {\n    let ctx = TestContext::new(\"select_only_exclude_option_fields\");\n    create_customer_table(&ctx.db).unwrap();\n\n    let _ = customer::ActiveModel {\n        name: Set(\"Alice\".to_owned()),\n        notes: Set(Some(\"Want to communicate with Bob\".to_owned())),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert customer\");\n\n    let _ = customer::ActiveModel {\n        name: Set(\"Bob\".to_owned()),\n        notes: Set(Some(\"Just listening\".to_owned())),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .expect(\"could not insert customer\");\n\n    let _ = customer::ActiveModel {\n        name: Set(\"Sam\".to_owned()),\n        notes: Set(None),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert customer\");\n\n    let customers = Customer::find()\n        .select_only()\n        .column(customer::Column::Id)\n        .column(customer::Column::Name)\n        .all(&ctx.db)\n        .unwrap();\n\n    assert_eq!(customers.len(), 3);\n    assert_eq!(customers[0].notes, None);\n    assert_eq!(customers[1].notes, None);\n    assert_eq!(customers[2].notes, None);\n\n    let sam = bakery_dense::customer::Entity::find()\n        .filter(bakery_dense::customer::COLUMN.name.eq(\"Sam\"))\n        .one(&ctx.db)\n        .unwrap()\n        .unwrap();\n\n    let _: sea_orm::StringColumnNullable<bakery_dense::customer::Entity> =\n        bakery_dense::customer::COLUMN.notes;\n\n    assert_eq!(\n        sam,\n        bakery_dense::customer::Entity::find()\n            .filter(\n                bakery_dense::customer::COLUMN\n                    .notes\n                    .eq(Option::<String>::None)\n            )\n            .one(&ctx.db)\n            .unwrap()\n            .unwrap()\n    );\n\n    ctx.delete();\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/raw_sql_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\nuse sea_orm::{FromQueryResult, prelude::*, raw_sql};\n\nuse crate::common::TestContext;\nuse common::bakery_chain::*;\nuse serde_json::json;\n\nmod common;\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"rusqlite\")]\nfn raw_sql_test_simple_select() {\n    #[derive(FromQueryResult)]\n    struct BakerySimple {\n        id: i32,\n        brand: String,\n    }\n\n    #[derive(FromQueryResult)]\n    struct BakeryFlat {\n        id: i32,\n        name: String,\n        #[sea_orm(alias = \"profit_margin\")]\n        profit: f64,\n    }\n\n    let ctx = TestContext::new(\"raw_sql_test_simple_select\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, false);\n\n    let id = 42;\n\n    let bakery: bakery::Model = bakery::Entity::find()\n        .from_raw_sql(raw_sql!(\n            Sqlite,\n            r#\"SELECT \"id\", \"name\", \"profit_margin\" FROM \"bakery\" WHERE id = {id}\"#\n        ))\n        .one(&ctx.db)\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.name, \"cool little bakery\");\n    assert_eq!(bakery.profit_margin, 4.1);\n\n    let bakery = BakeryFlat::find_by_statement(raw_sql!(\n        Sqlite,\n        r#\"SELECT \"id\", \"name\", \"profit_margin\" FROM \"bakery\" WHERE id = {id}\"#\n    ))\n    .one(&ctx.db)\n    .expect(\"succeeds to get the result\")\n    .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.name, \"cool little bakery\");\n    assert_eq!(bakery.profit, 4.1);\n\n    let bakery = BakerySimple::find_by_statement(raw_sql!(\n        Sqlite,\n        r#\"SELECT \"id\", \"name\" as \"brand\" FROM \"bakery\" WHERE id = {id}\"#\n    ))\n    .one(&ctx.db)\n    .expect(\"succeeds to get the result\")\n    .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.brand, \"cool little bakery\");\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"rusqlite\")]\nfn raw_sql_test_nested_select() {\n    #[derive(FromQueryResult)]\n    struct Cake {\n        id: i32,\n        name: String,\n        #[sea_orm(nested)]\n        bakery: Option<Bakery>,\n    }\n\n    #[derive(FromQueryResult)]\n    struct Bakery {\n        #[sea_orm(alias = \"bakery_id\")]\n        id: i32,\n        #[sea_orm(alias = \"bakery_name\")]\n        name: String,\n    }\n\n    let ctx = TestContext::new(\"raw_sql_test_nested_select\");\n    create_tables(&ctx.db).unwrap();\n\n    seed_data::init_1(&ctx, true);\n\n    let bakery_id = 42;\n    let cake_ids = [10, 12, 15];\n\n    let cake: Option<Cake> = Cake::find_by_statement(raw_sql!(\n        Sqlite,\n        r#\"SELECT\n                \"cake\".\"id\",\n                \"cake\".\"name\",\n                \"bakery\".\"id\" AS \"bakery_id\",\n                \"bakery\".\"name\" AS \"bakery_name\"\n            FROM \"cake\"\n            LEFT JOIN \"bakery\" ON \"cake\".\"bakery_id\" = \"bakery\".\"id\"\n            WHERE\n                \"bakery\".\"id\" = {bakery_id}\n                AND \"cake\".\"id\" IN ({..cake_ids})\n            ORDER BY \"cake\".\"id\" ASC LIMIT 1\"#\n    ))\n    .one(&ctx.db)\n    .expect(\"succeeds to get the result\");\n\n    let cake = cake.unwrap();\n    assert_eq!(cake.id, 15);\n    assert_eq!(cake.name, \"Chocolate\");\n    let bakery = cake.bakery.unwrap();\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.name, \"cool little bakery\");\n\n    ctx.delete();\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/rbac_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\nuse sea_orm::{\n    ColumnTrait, ConnectionTrait, DbConn, DbErr, EntityName, EntityTrait, IntoActiveModel, NotSet,\n    QueryFilter, Set, TransactionTrait, entity::prelude::ChronoUtc,\n};\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"rbac\")]\nfn main() {\n    let ctx = TestContext::new(\"bakery_chain_rbac_tests\");\n    create_tables(&ctx.db).unwrap();\n    sea_orm::rbac::schema::create_tables(&ctx.db, Default::default()).unwrap();\n    rbac_setup(&ctx.db).unwrap();\n    crud_tests(&ctx.db).unwrap();\n    ctx.delete();\n}\n\n#[cfg(feature = \"rbac\")]\nfn rbac_setup(db: &DbConn) -> Result<(), DbErr> {\n    use sea_orm::rbac::{RbacAddRoleHierarchy, RbacContext};\n\n    let mut context = RbacContext::load(db)?;\n\n    let tables = [\n        baker::Entity.table_name(),\n        bakery::Entity.table_name(),\n        cake::Entity.table_name(),\n        cakes_bakers::Entity.table_name(),\n        customer::Entity.table_name(),\n        lineitem::Entity.table_name(),\n        order::Entity.table_name(),\n        \"*\", // WILDCARD\n    ];\n\n    context.add_tables(db, &tables)?;\n\n    context.add_crud_permissions(db)?;\n\n    context.add_roles(db, &[\"admin\", \"manager\", \"public\"])?;\n\n    context.assign_user_role(db, &[(1, \"admin\"), (2, \"manager\"), (3, \"public\")])?;\n\n    // public can select everything\n    context.add_role_permissions(db, \"public\", &[\"select\"], &[\"*\"])?;\n\n    // manager can create / update everything except bakery\n    context.add_role_permissions(\n        db,\n        \"manager\",\n        &[\"insert\", \"update\"],\n        &tables\n            .iter()\n            .cloned()\n            .filter(|t| !matches!(*t, \"bakery\" | \"*\"))\n            .collect::<Vec<_>>(),\n    )?;\n\n    // manager can delete order\n    context.add_role_permissions(db, \"manager\", &[\"delete\"], &[\"order\", \"lineitem\"])?;\n\n    // admin can do anything, in addition to public / manager\n    context.add_role_permissions(db, \"admin\", &[\"delete\"], &[\"*\"])?;\n\n    // add permissions to bakery which manager doesn't have\n    context.add_role_permissions(db, \"admin\", &[\"insert\", \"update\"], &[\"bakery\"])?;\n\n    context.add_role_hierarchy(\n        db,\n        &[\n            RbacAddRoleHierarchy {\n                super_role: \"admin\",\n                role: \"manager\",\n            },\n            RbacAddRoleHierarchy {\n                super_role: \"manager\",\n                role: \"public\",\n            },\n        ],\n    )?;\n\n    Ok(())\n}\n\n#[cfg(feature = \"rbac\")]\nfn crud_tests(db: &DbConn) -> Result<(), DbErr> {\n    use sea_orm::{RestrictedConnection, RestrictedTransaction, rbac::RbacUserId};\n\n    db.load_rbac()?;\n\n    let admin = RbacUserId(1);\n    let manager = RbacUserId(2);\n    let public = RbacUserId(3);\n\n    fn admin_create_bakery(db: RestrictedConnection) -> Result<(), DbErr> {\n        // only admin can create bakery\n        let seaside_bakery = bakery::ActiveModel {\n            name: Set(\"SeaSide Bakery\".to_owned()),\n            profit_margin: Set(10.2),\n            ..Default::default()\n        };\n        let res = Bakery::insert(seaside_bakery).exec(&db)?;\n        let bakery: Option<bakery::Model> = Bakery::find_by_id(res.last_insert_id).one(&db)?;\n\n        assert_eq!(bakery.unwrap().name, \"SeaSide Bakery\");\n        Ok(())\n    }\n\n    admin_create_bakery(db.restricted_for(admin)?)?;\n\n    // manager / public can't create bakery\n    for user in [manager, public] {\n        assert!(matches!(\n            Bakery::insert(bakery::ActiveModel::default()).exec(&db.restricted_for(user)?),\n            Err(DbErr::AccessDenied { .. })\n        ));\n        let txn = db.restricted_for(user)?.begin()?;\n        assert!(matches!(\n            Bakery::insert(bakery::ActiveModel::default()).exec(&txn),\n            Err(DbErr::AccessDenied { .. })\n        ));\n    }\n\n    // anyone can read bakery\n    for user_id in [1, 2, 3] {\n        let db = db.restricted_for(RbacUserId(user_id))?;\n\n        let bakery = Bakery::find().one(&db)?.unwrap();\n        assert_eq!(bakery.name, \"SeaSide Bakery\");\n    }\n\n    // manager can create cake / baker\n    {\n        let db = db.restricted_for(manager)?;\n\n        cake::Entity::insert(cake::ActiveModel {\n            name: Set(\"Cheesecake\".to_owned()),\n            price: Set(2.into()),\n            bakery_id: Set(Some(1)),\n            gluten_free: Set(false),\n            ..Default::default()\n        })\n        .exec(&db)\n        .expect(\"insert succeeds\");\n\n        db.transaction::<_, _, DbErr>(|txn| {\n            ({\n                cake::Entity::insert(cake::ActiveModel {\n                    name: Set(\"Chocolate\".to_owned()),\n                    price: Set(3.into()),\n                    bakery_id: Set(Some(1)),\n                    gluten_free: Set(true),\n                    ..Default::default()\n                })\n                .exec(txn)?;\n\n                Ok(())\n            })\n        })\n        .expect(\"insert succeeds\");\n\n        let txn: RestrictedTransaction = db.begin()?;\n\n        baker::Entity::insert(baker::ActiveModel {\n            name: Set(\"Master Baker\".to_owned()),\n            contact_details: Set(Default::default()),\n            bakery_id: Set(Some(1)),\n            ..Default::default()\n        })\n        .exec(&txn)\n        .expect(\"insert succeeds\");\n\n        txn.commit()?;\n    }\n\n    assert_eq!(cake::Entity::find().all(db)?.len(), 2);\n\n    // anyone can read cake\n    for user_id in [1, 2, 3] {\n        let db = db.restricted_for(RbacUserId(user_id))?;\n\n        let cake = cake::Entity::find().one(&db)?.unwrap();\n        assert_eq!(cake.name, \"Cheesecake\");\n    }\n\n    // admin can create customer\n    {\n        let db = db.restricted_for(admin)?;\n\n        customer::Entity::insert(customer::ActiveModel {\n            id: Set(11),\n            name: Set(\"Alice\".to_owned()),\n            notes: Set(None),\n        })\n        .exec(&db)?;\n\n        customer::Entity::insert(customer::ActiveModel {\n            id: Set(12),\n            name: Set(\"Bob\".to_owned()),\n            notes: Set(None),\n        })\n        .exec(&db)?;\n    }\n\n    // manager can create / delete order\n    {\n        let public_db = db.restricted_for(public)?;\n        let db = db.restricted_for(manager)?;\n\n        order::Entity::insert(order::ActiveModel {\n            id: Set(101),\n            total: Set(10.into()),\n            bakery_id: Set(1),\n            customer_id: Set(11),\n            placed_at: Set(ChronoUtc::now()),\n        })\n        .exec(&db)?;\n\n        lineitem::Entity::insert(lineitem::ActiveModel {\n            id: NotSet,\n            price: Set(2.into()),\n            quantity: Set(2),\n            order_id: Set(101),\n            cake_id: Set(1),\n        })\n        .exec(&db)?;\n\n        let to_insert = lineitem::ActiveModel {\n            id: NotSet,\n            price: Set(3.into()),\n            quantity: Set(3),\n            order_id: Set(101),\n            cake_id: Set(2),\n        };\n        let lineitem_id = if db.support_returning() {\n            lineitem::Entity::insert(to_insert)\n                .exec_with_returning(&db)?\n                .id\n        } else {\n            lineitem::Entity::insert(to_insert)\n                .exec(&db)?\n                .last_insert_id\n        };\n\n        let order_with_items = order::Entity::find()\n            .find_with_related(lineitem::Entity)\n            .all(&public_db)?;\n        assert_eq!(order_with_items[0].1.len(), 2);\n\n        lineitem::Entity::delete_many()\n            .filter(lineitem::Column::Id.eq(lineitem_id))\n            .exec(&db)?;\n\n        // reject; of course\n        assert!(matches!(\n            lineitem::Entity::delete_many()\n                .filter(lineitem::Column::Id.eq(lineitem_id))\n                .exec(&public_db),\n            Err(DbErr::AccessDenied { .. })\n        ));\n\n        // only 1 line item left\n        let order_with_items = order::Entity::find()\n            .find_with_related(lineitem::Entity)\n            .all(&public_db)?;\n        assert_eq!(order_with_items[0].1.len(), 1);\n    }\n\n    // manager can update order\n    {\n        use sea_orm::ActiveModelTrait;\n\n        let db = db.restricted_for(manager)?;\n\n        let lineitem = lineitem::Entity::find_by_id(1).one(&db)?.unwrap();\n        assert_eq!(lineitem.quantity, 2);\n        let mut lineitem = lineitem.into_active_model();\n        lineitem.quantity = Set(3);\n        let lineitem = lineitem.save(&db)?;\n        assert_eq!(lineitem.quantity.unwrap(), 3);\n    }\n\n    // only admin can delete customer\n    {\n        use sea_orm::ModelTrait;\n\n        let db = db.restricted_for(admin)?;\n\n        let bob = customer::Entity::find_by_id(12).one(&db)?.unwrap();\n        assert_eq!(bob.name, \"Bob\");\n\n        bob.delete(&db)?;\n        assert!(customer::Entity::find_by_id(12).one(&db)?.is_none());\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/relational_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::sea_query::{Expr, Func, SimpleExpr};\nuse sea_orm::{\n    DbBackend, DbErr, DerivePartialModel, FromQueryResult,\n    entity::*,\n    prelude::{ChronoUtc, DateTimeUtc, Decimal, Uuid},\n    query::*,\n};\n\n// Run the test locally:\n// DATABASE_URL=\"mysql://root:@localhost\" cargo test --features sqlx-mysql,runtime-async-std-native-tls --test relational_tests\n#[sea_orm_macros::test]\npub fn left_join() {\n    let ctx = TestContext::new(\"test_left_join\");\n    create_tables(&ctx.db).unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let _baker_1 = baker::ActiveModel {\n        name: Set(\"Baker 1\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(bakery.id)),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert baker\");\n\n    let _baker_2 = baker::ActiveModel {\n        name: Set(\"Baker 2\".to_owned()),\n        contact_details: Set(serde_json::json!({})),\n        bakery_id: Set(None),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert baker\");\n\n    #[derive(Debug, FromQueryResult)]\n    struct SelectResult {\n        name: String,\n        bakery_name: Option<String>,\n    }\n\n    let select = baker::Entity::find()\n        .left_join(bakery::Entity)\n        .select_only()\n        .column(baker::Column::Name)\n        .column_as(bakery::Column::Name, \"bakery_name\")\n        .filter(baker::Column::Name.contains(\"Baker 1\"));\n\n    let result = select\n        .clone()\n        .into_model::<SelectResult>()\n        .one(&ctx.db)\n        .unwrap()\n        .unwrap();\n    assert_eq!(result.name.as_str(), \"Baker 1\");\n    assert_eq!(result.bakery_name, Some(\"SeaSide Bakery\".to_string()));\n\n    #[derive(DerivePartialModel, Debug, PartialEq)]\n    #[sea_orm(entity = \"Baker\")]\n    struct PartialSelectResult {\n        name: String,\n        #[sea_orm(from_expr = \"Expr::col((bakery::Entity, bakery::Column::Name))\")]\n        bakery_name: Option<String>,\n        #[sea_orm(\n            from_expr = r#\"SimpleExpr::FunctionCall(Func::upper(Expr::col((bakery::Entity, bakery::Column::Name))))\"#\n        )]\n        bakery_name_upper: Option<String>,\n    }\n\n    let result = select\n        .into_partial_model::<PartialSelectResult>()\n        .one(&ctx.db)\n        .unwrap()\n        .unwrap();\n    assert_eq!(result.name.as_str(), \"Baker 1\");\n    assert_eq!(result.bakery_name, Some(\"SeaSide Bakery\".to_string()));\n    assert_eq!(result.bakery_name_upper, Some(\"SEASIDE BAKERY\".to_string()));\n\n    let select = baker::Entity::find()\n        .left_join(bakery::Entity)\n        .select_only()\n        .column(baker::Column::Name)\n        .column_as(bakery::Column::Name, \"bakery_name\")\n        .filter(baker::Column::Name.contains(\"Baker 2\"));\n\n    let result = select\n        .into_model::<SelectResult>()\n        .one(&ctx.db)\n        .unwrap()\n        .unwrap();\n    assert_eq!(result.bakery_name, None);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\n#[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-postgres\"))]\npub fn right_join() {\n    let ctx = TestContext::new(\"test_right_join\");\n    create_tables(&ctx.db).unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert customer\");\n\n    let _customer_jim = customer::ActiveModel {\n        name: Set(\"Jim\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert customer\");\n\n    let _order = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(15.10)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert order\");\n\n    #[derive(FromQueryResult)]\n    #[allow(dead_code)]\n    struct SelectResult {\n        name: String,\n        order_total: Option<Decimal>,\n    }\n\n    let select = order::Entity::find()\n        .right_join(customer::Entity)\n        .select_only()\n        .column(customer::Column::Name)\n        .column_as(order::Column::Total, \"order_total\")\n        .filter(customer::Column::Name.contains(\"Kate\"));\n\n    let result = select\n        .into_model::<SelectResult>()\n        .one(&ctx.db)\n        .unwrap()\n        .unwrap();\n    assert_eq!(result.order_total, Some(rust_dec(15.10)));\n\n    let select = order::Entity::find()\n        .right_join(customer::Entity)\n        .select_only()\n        .column(customer::Column::Name)\n        .column_as(order::Column::Total, \"order_total\")\n        .filter(customer::Column::Name.contains(\"Jim\"));\n\n    let result = select\n        .into_model::<SelectResult>()\n        .one(&ctx.db)\n        .unwrap()\n        .unwrap();\n    assert_eq!(result.order_total, None);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn inner_join() {\n    let ctx = TestContext::new(\"test_inner_join\");\n    create_tables(&ctx.db).unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert customer\");\n\n    let _customer_jim = customer::ActiveModel {\n        name: Set(\"Jim\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert customer\");\n\n    let kate_order_1 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(15.10)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert order\");\n\n    let kate_order_2 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(100.00)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert order\");\n\n    #[derive(Debug, FromQueryResult)]\n    struct SelectResult {\n        name: String,\n        order_total: Option<Decimal>,\n    }\n\n    let select = order::Entity::find()\n        .inner_join(customer::Entity)\n        .select_only()\n        .column(customer::Column::Name)\n        .column_as(order::Column::Total, \"order_total\");\n\n    let results = select.into_model::<SelectResult>().all(&ctx.db).unwrap();\n\n    assert_eq!(results.len(), 2);\n    assert!(\n        results\n            .iter()\n            .any(|result| result.name == customer_kate.name.clone()\n                && result.order_total == Some(kate_order_1.total))\n    );\n    assert!(\n        results\n            .iter()\n            .any(|result| result.name == customer_kate.name.clone()\n                && result.order_total == Some(kate_order_2.total))\n    );\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn group_by() {\n    let ctx = TestContext::new(\"test_group_by\");\n    create_tables(&ctx.db).unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert customer\");\n\n    let customer_sam = customer::ActiveModel {\n        name: Set(\"Sam\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert customer\");\n\n    let kate_order_1 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(99.95)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert order\");\n\n    let kate_order_2 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(200.00)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert order\");\n\n    let sam_order = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_sam.id),\n        total: Set(rust_dec(28.24)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert order\");\n\n    type Count = i64;\n\n    #[derive(Debug, FromQueryResult)]\n    struct SelectResult {\n        name: String,\n        number_orders: Count,\n        total_spent: Decimal,\n        min_spent: Decimal,\n        max_spent: Decimal,\n    }\n\n    let select = customer::Entity::find()\n        .left_join(order::Entity)\n        .select_only()\n        .column(customer::Column::Name)\n        .column_as(order::Column::Total.count(), \"number_orders\")\n        .column_as(order::Column::Total.sum(), \"total_spent\")\n        .column_as(order::Column::Total.min(), \"min_spent\")\n        .column_as(order::Column::Total.max(), \"max_spent\")\n        .order_by_asc(customer::Column::Name)\n        .group_by(customer::Column::Name);\n\n    let result = select\n        .into_model::<SelectResult>()\n        .one(&ctx.db)\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(result.name, \"Kate\");\n    assert_eq!(result.number_orders, 2);\n    assert_eq!(result.total_spent, kate_order_1.total + kate_order_2.total);\n    assert_eq!(result.min_spent, kate_order_1.total.min(kate_order_2.total));\n    assert_eq!(result.max_spent, kate_order_1.total.max(kate_order_2.total));\n\n    let (customer, total_spent): (String, Decimal) = customer::Entity::find()\n        .left_join(order::Entity)\n        .select_only()\n        .column(customer::Column::Name)\n        .column_as(order::Column::Total.sum(), \"sum\")\n        .group_by(customer::Column::Name)\n        .into_tuple()\n        .one(&ctx.db)\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(customer, \"Kate\");\n    assert_eq!(total_spent, result.total_spent);\n\n    let sum_order_value: Decimal = order::Entity::find()\n        .select_only()\n        .column_as(order::Column::Total.sum(), \"sum\")\n        .into_tuple()\n        .one(&ctx.db)\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(\n        sum_order_value,\n        kate_order_1.total + kate_order_2.total + sam_order.total\n    );\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn having() {\n    // customers with orders with total equal to $90\n    let ctx = TestContext::new(\"test_having\");\n    create_tables(&ctx.db).unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert bakery\");\n\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert customer\");\n\n    let kate_order_1 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(100.00)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert order\");\n\n    let _kate_order_2 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(12.00)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert order\");\n\n    let customer_bob = customer::ActiveModel {\n        name: Set(\"Bob\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert customer\");\n\n    let _bob_order_1 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_bob.id),\n        total: Set(rust_dec(50.0)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert order\");\n\n    let _bob_order_2 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_bob.id),\n        total: Set(rust_dec(50.0)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .expect(\"could not insert order\");\n\n    #[derive(Debug, FromQueryResult)]\n    struct SelectResult {\n        name: String,\n        order_total: Option<Decimal>,\n    }\n\n    let results = customer::Entity::find()\n        .inner_join(order::Entity)\n        .select_only()\n        .column(customer::Column::Name)\n        .column_as(order::Column::Total, \"order_total\")\n        .group_by(customer::Column::Name)\n        .group_by(order::Column::Total)\n        .having(order::Column::Total.gt(rust_dec(90.00)))\n        .into_model::<SelectResult>()\n        .all(&ctx.db)\n        .unwrap();\n\n    assert_eq!(results.len(), 1);\n    assert_eq!(results[0].name, customer_kate.name.clone());\n    assert_eq!(results[0].order_total, Some(kate_order_1.total));\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn related() -> Result<(), DbErr> {\n    use sea_orm::{SelectA, SelectB};\n\n    let ctx = TestContext::new(\"test_related\");\n    create_tables(&ctx.db)?;\n\n    // SeaSide Bakery\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let seaside_bakery_res = Bakery::insert(seaside_bakery).exec(&ctx.db)?;\n\n    // Bob's Baker\n    let baker_bob = baker::ActiveModel {\n        name: Set(\"Baker Bob\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    }\n    .insert(&ctx.db)?;\n\n    // Bobby's Baker\n    let baker_bobby = baker::ActiveModel {\n        name: Set(\"Baker Bobby\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+85212345678\",\n        })),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let _baker_bobby_res = Baker::insert(baker_bobby).exec(&ctx.db)?;\n\n    // Terres Bakery\n    let terres_bakery = bakery::ActiveModel {\n        name: Set(\"Terres Bakery\".to_owned()),\n        profit_margin: Set(13.5),\n        ..Default::default()\n    };\n    let terres_bakery_res = Bakery::insert(terres_bakery).exec(&ctx.db)?;\n\n    // Ada's Baker\n    let baker_ada = baker::ActiveModel {\n        name: Set(\"Baker Ada\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(terres_bakery_res.last_insert_id)),\n        ..Default::default()\n    }\n    .insert(&ctx.db)?;\n\n    // Stone Bakery, with no baker\n    let stone_bakery = bakery::ActiveModel {\n        name: Set(\"Stone Bakery\".to_owned()),\n        profit_margin: Set(13.5),\n        ..Default::default()\n    };\n    let _stone_bakery_res = Bakery::insert(stone_bakery).exec(&ctx.db)?;\n\n    let cake = cake::ActiveModel {\n        name: Set(\"Chocolate\".to_owned()),\n        price: Set(\"1.2\".parse().unwrap()),\n        gluten_free: Set(false),\n        bakery_id: Set(None),\n        ..Default::default()\n    }\n    .insert(&ctx.db)?;\n\n    cakes_bakers::ActiveModel {\n        cake_id: Set(cake.id),\n        baker_id: Set(baker_bob.id),\n    }\n    .insert(&ctx.db)?;\n\n    cakes_bakers::ActiveModel {\n        cake_id: Set(cake.id),\n        baker_id: Set(baker_ada.id),\n    }\n    .insert(&ctx.db)?;\n\n    #[derive(Debug, FromQueryResult, PartialEq)]\n    struct BakerLite {\n        name: String,\n    }\n\n    #[derive(Debug, FromQueryResult, PartialEq)]\n    struct BakeryLite {\n        name: String,\n    }\n\n    // get all bakery and baker's name and put them into tuples\n    let bakers_in_bakery: Vec<(BakeryLite, Option<BakerLite>)> = Bakery::find()\n        .find_also_related(Baker)\n        .select_only()\n        .column_as(bakery::Column::Name, (SelectA, bakery::Column::Name))\n        .column_as(baker::Column::Name, (SelectB, baker::Column::Name))\n        .order_by_asc(bakery::Column::Id)\n        .order_by_asc(baker::Column::Id)\n        .into_model()\n        .all(&ctx.db)?;\n\n    assert_eq!(\n        bakers_in_bakery,\n        [\n            (\n                BakeryLite {\n                    name: \"SeaSide Bakery\".to_owned(),\n                },\n                Some(BakerLite {\n                    name: \"Baker Bob\".to_owned(),\n                })\n            ),\n            (\n                BakeryLite {\n                    name: \"SeaSide Bakery\".to_owned(),\n                },\n                Some(BakerLite {\n                    name: \"Baker Bobby\".to_owned(),\n                })\n            ),\n            (\n                BakeryLite {\n                    name: \"Terres Bakery\".to_owned(),\n                },\n                Some(BakerLite {\n                    name: \"Baker Ada\".to_owned(),\n                })\n            ),\n            (\n                BakeryLite {\n                    name: \"Stone Bakery\".to_owned(),\n                },\n                None,\n            ),\n        ]\n    );\n\n    let seaside_bakery = Bakery::find()\n        .filter(bakery::Column::Id.eq(1))\n        .one(&ctx.db)?\n        .unwrap();\n\n    let bakers = seaside_bakery.find_related(Baker).all(&ctx.db)?;\n\n    assert_eq!(\n        bakers,\n        [\n            baker::Model {\n                id: 1,\n                name: \"Baker Bob\".to_owned(),\n                contact_details: serde_json::json!({\n                    \"mobile\": \"+61424000000\",\n                    \"home\": \"0395555555\",\n                    \"address\": \"12 Test St, Testville, Vic, Australia\"\n                }),\n                bakery_id: Some(1),\n            },\n            baker::Model {\n                id: 2,\n                name: \"Baker Bobby\".to_owned(),\n                contact_details: serde_json::json!({\n                    \"mobile\": \"+85212345678\",\n                }),\n                bakery_id: Some(1),\n            }\n        ]\n    );\n\n    let select_bakery_with_baker = Bakery::find()\n        .find_with_related(Baker)\n        .order_by_asc(baker::Column::Id);\n\n    assert_eq!(\n        select_bakery_with_baker\n            .build(sea_orm::DatabaseBackend::MySql)\n            .to_string(),\n        [\n            \"SELECT `bakery`.`id` AS `A_id`,\",\n            \"`bakery`.`name` AS `A_name`,\",\n            \"`bakery`.`profit_margin` AS `A_profit_margin`,\",\n            \"`baker`.`id` AS `B_id`,\",\n            \"`baker`.`name` AS `B_name`,\",\n            \"`baker`.`contact_details` AS `B_contact_details`,\",\n            \"`baker`.`bakery_id` AS `B_bakery_id`\",\n            \"FROM `bakery`\",\n            \"LEFT JOIN `baker` ON `bakery`.`id` = `baker`.`bakery_id`\",\n            \"ORDER BY `bakery`.`id` ASC, `baker`.`id` ASC\"\n        ]\n        .join(\" \")\n    );\n\n    let select_bakery_with_baker_result = select_bakery_with_baker.all(&ctx.db)?;\n\n    assert_eq!(\n        select_bakery_with_baker_result,\n        [\n            (\n                bakery::Model {\n                    id: 1,\n                    name: \"SeaSide Bakery\".to_owned(),\n                    profit_margin: 10.4,\n                },\n                vec![\n                    baker::Model {\n                        id: 1,\n                        name: \"Baker Bob\".to_owned(),\n                        contact_details: serde_json::json!({\n                            \"mobile\": \"+61424000000\",\n                            \"home\": \"0395555555\",\n                            \"address\": \"12 Test St, Testville, Vic, Australia\"\n                        }),\n                        bakery_id: Some(seaside_bakery_res.last_insert_id),\n                    },\n                    baker::Model {\n                        id: 2,\n                        name: \"Baker Bobby\".to_owned(),\n                        contact_details: serde_json::json!({\n                            \"mobile\": \"+85212345678\",\n                        }),\n                        bakery_id: Some(seaside_bakery_res.last_insert_id),\n                    }\n                ]\n            ),\n            (\n                bakery::Model {\n                    id: 2,\n                    name: \"Terres Bakery\".to_owned(),\n                    profit_margin: 13.5,\n                },\n                vec![baker::Model {\n                    id: 3,\n                    name: \"Baker Ada\".to_owned(),\n                    contact_details: serde_json::json!({\n                        \"mobile\": \"+61424000000\",\n                        \"home\": \"0395555555\",\n                        \"address\": \"12 Test St, Testville, Vic, Australia\"\n                    }),\n                    bakery_id: Some(terres_bakery_res.last_insert_id),\n                }]\n            ),\n            (\n                bakery::Model {\n                    id: 3,\n                    name: \"Stone Bakery\".to_owned(),\n                    profit_margin: 13.5,\n                },\n                vec![]\n            ),\n        ]\n    );\n\n    assert_eq!(\n        select_bakery_with_baker_result,\n        Bakery::find()\n            .find_with_linked(bakery::ToBaker)\n            .order_by_asc(bakery::Column::Id)\n            .order_by_asc(Expr::col((\"r0\", baker::Column::Id)))\n            .all(&ctx.db)?\n    );\n\n    let select_cake_with_baker = Cake::find().find_with_related(Baker);\n\n    assert_eq!(\n        select_cake_with_baker\n            .build(sea_orm::DatabaseBackend::MySql)\n            .to_string(),\n        [\n            \"SELECT\",\n            \"`cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`, `cake`.`price` AS `A_price`,\",\n            \"`cake`.`bakery_id` AS `A_bakery_id`, `cake`.`gluten_free` AS `A_gluten_free`,\",\n            \"`cake`.`serial` AS `A_serial`, `baker`.`id` AS `B_id`, `baker`.`name` AS `B_name`,\",\n            \"`baker`.`contact_details` AS `B_contact_details`, `baker`.`bakery_id` AS `B_bakery_id`\",\n            \"FROM `cake` LEFT JOIN `cakes_bakers` ON `cake`.`id` = `cakes_bakers`.`cake_id`\",\n            \"LEFT JOIN `baker` ON `cakes_bakers`.`baker_id` = `baker`.`id`\",\n            \"ORDER BY `cake`.`id` ASC\"\n        ].join(\" \")\n    );\n\n    assert_eq!(\n        select_cake_with_baker.all(&ctx.db)?,\n        [(cake.try_into_model().unwrap(), vec![baker_bob, baker_ada])]\n    );\n\n    ctx.delete();\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub fn linked() -> Result<(), DbErr> {\n    use common::bakery_chain::Order;\n    use sea_orm::{SelectA, SelectB};\n    use sea_query::{Alias, Expr};\n\n    let ctx = TestContext::new(\"test_linked\");\n    create_tables(&ctx.db)?;\n\n    // SeaSide Bakery\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let seaside_bakery_res = Bakery::insert(seaside_bakery).exec(&ctx.db)?;\n\n    // Bob's Baker, Cake & Cake Baker\n    let baker_bob = baker::ActiveModel {\n        name: Set(\"Baker Bob\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let baker_bob_res = Baker::insert(baker_bob).exec(&ctx.db)?;\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let mud_cake_res = Cake::insert(mud_cake).exec(&ctx.db)?;\n    let bob_cakes_bakers = cakes_bakers::ActiveModel {\n        cake_id: Set(mud_cake_res.last_insert_id),\n        baker_id: Set(baker_bob_res.last_insert_id),\n    };\n    CakesBakers::insert(bob_cakes_bakers).exec(&ctx.db)?;\n\n    // Bobby's Baker, Cake & Cake Baker\n    let baker_bobby = baker::ActiveModel {\n        name: Set(\"Baker Bobby\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+85212345678\",\n        })),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let baker_bobby_res = Baker::insert(baker_bobby).exec(&ctx.db)?;\n    let cheese_cake = cake::ActiveModel {\n        name: Set(\"Cheese Cake\".to_owned()),\n        price: Set(rust_dec(20.5)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let cheese_cake_res = Cake::insert(cheese_cake).exec(&ctx.db)?;\n    let bobby_cakes_bakers = cakes_bakers::ActiveModel {\n        cake_id: Set(cheese_cake_res.last_insert_id),\n        baker_id: Set(baker_bobby_res.last_insert_id),\n    };\n    CakesBakers::insert(bobby_cakes_bakers).exec(&ctx.db)?;\n    let chocolate_cake = cake::ActiveModel {\n        name: Set(\"Chocolate Cake\".to_owned()),\n        price: Set(rust_dec(30.15)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let chocolate_cake_res = Cake::insert(chocolate_cake).exec(&ctx.db)?;\n    let bobby_cakes_bakers = cakes_bakers::ActiveModel {\n        cake_id: Set(chocolate_cake_res.last_insert_id),\n        baker_id: Set(baker_bobby_res.last_insert_id),\n    };\n    CakesBakers::insert(bobby_cakes_bakers).exec(&ctx.db)?;\n\n    // Freerider's Baker, no cake baked\n    let baker_freerider = baker::ActiveModel {\n        name: Set(\"Freerider\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+85298765432\",\n        })),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let _baker_freerider_res = Baker::insert(baker_freerider).exec(&ctx.db)?;\n\n    // Kate's Customer, Order & Line Item\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        notes: Set(Some(\"Loves cheese cake\".to_owned())),\n        ..Default::default()\n    };\n    let customer_kate_res = Customer::insert(customer_kate).exec(&ctx.db)?;\n    let kate_order_1 = order::ActiveModel {\n        bakery_id: Set(seaside_bakery_res.last_insert_id),\n        customer_id: Set(customer_kate_res.last_insert_id),\n        total: Set(rust_dec(15.10)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    };\n    let kate_order_1_res = Order::insert(kate_order_1).exec(&ctx.db)?;\n    lineitem::ActiveModel {\n        cake_id: Set(cheese_cake_res.last_insert_id),\n        order_id: Set(kate_order_1_res.last_insert_id),\n        price: Set(rust_dec(7.55)),\n        quantity: Set(2),\n        ..Default::default()\n    }\n    .save(&ctx.db)?;\n    let kate_order_2 = order::ActiveModel {\n        bakery_id: Set(seaside_bakery_res.last_insert_id),\n        customer_id: Set(customer_kate_res.last_insert_id),\n        total: Set(rust_dec(29.7)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    };\n    let kate_order_2_res = Order::insert(kate_order_2).exec(&ctx.db)?;\n    lineitem::ActiveModel {\n        cake_id: Set(chocolate_cake_res.last_insert_id),\n        order_id: Set(kate_order_2_res.last_insert_id),\n        price: Set(rust_dec(9.9)),\n        quantity: Set(3),\n        ..Default::default()\n    }\n    .save(&ctx.db)?;\n\n    // Kara's Customer, Order & Line Item\n    let customer_kara = customer::ActiveModel {\n        name: Set(\"Kara\".to_owned()),\n        notes: Set(Some(\"Loves all cakes\".to_owned())),\n        ..Default::default()\n    };\n    let customer_kara_res = Customer::insert(customer_kara).exec(&ctx.db)?;\n    let kara_order_1 = order::ActiveModel {\n        bakery_id: Set(seaside_bakery_res.last_insert_id),\n        customer_id: Set(customer_kara_res.last_insert_id),\n        total: Set(rust_dec(15.10)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    };\n    let kara_order_1_res = Order::insert(kara_order_1).exec(&ctx.db)?;\n    lineitem::ActiveModel {\n        cake_id: Set(mud_cake_res.last_insert_id),\n        order_id: Set(kara_order_1_res.last_insert_id),\n        price: Set(rust_dec(7.55)),\n        quantity: Set(2),\n        ..Default::default()\n    }\n    .save(&ctx.db)?;\n    let kara_order_2 = order::ActiveModel {\n        bakery_id: Set(seaside_bakery_res.last_insert_id),\n        customer_id: Set(customer_kara_res.last_insert_id),\n        total: Set(rust_dec(29.7)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    };\n    let kara_order_2_res = Order::insert(kara_order_2).exec(&ctx.db)?;\n    lineitem::ActiveModel {\n        cake_id: Set(cheese_cake_res.last_insert_id),\n        order_id: Set(kara_order_2_res.last_insert_id),\n        price: Set(rust_dec(9.9)),\n        quantity: Set(3),\n        ..Default::default()\n    }\n    .save(&ctx.db)?;\n\n    #[derive(Debug, FromQueryResult, PartialEq)]\n    struct BakerLite {\n        name: String,\n    }\n\n    #[derive(Debug, FromQueryResult, PartialEq)]\n    struct CustomerLite {\n        name: String,\n    }\n\n    // filtered find\n    let baked_for_customers: Vec<(BakerLite, Option<CustomerLite>)> = Baker::find()\n        .find_also_linked(baker::BakedForCustomer)\n        .select_only()\n        .column_as(baker::Column::Name, (SelectA, baker::Column::Name))\n        .column_as(\n            Expr::col((\"r4\", customer::Column::Name)),\n            (SelectB, customer::Column::Name),\n        )\n        .group_by(baker::Column::Id)\n        .group_by(Expr::col((\"r4\", customer::Column::Id)))\n        .group_by(baker::Column::Name)\n        .group_by(Expr::col((\"r4\", customer::Column::Name)))\n        .order_by_asc(baker::Column::Id)\n        .order_by_asc(Expr::col((\"r4\", customer::Column::Id)))\n        .into_model()\n        .all(&ctx.db)?;\n\n    assert_eq!(\n        baked_for_customers,\n        [\n            (\n                BakerLite {\n                    name: \"Baker Bob\".to_owned(),\n                },\n                Some(CustomerLite {\n                    name: \"Kara\".to_owned(),\n                })\n            ),\n            (\n                BakerLite {\n                    name: \"Baker Bobby\".to_owned(),\n                },\n                Some(CustomerLite {\n                    name: \"Kate\".to_owned(),\n                })\n            ),\n            (\n                BakerLite {\n                    name: \"Baker Bobby\".to_owned(),\n                },\n                Some(CustomerLite {\n                    name: \"Kara\".to_owned(),\n                })\n            ),\n            (\n                BakerLite {\n                    name: \"Freerider\".to_owned(),\n                },\n                None,\n            ),\n        ]\n    );\n\n    // try to use find_linked instead\n    let baker_bob = Baker::find()\n        .filter(baker::Column::Id.eq(1))\n        .one(&ctx.db)?\n        .unwrap();\n\n    let baker_bob_customers = baker_bob\n        .find_linked(baker::BakedForCustomer)\n        .all(&ctx.db)?;\n\n    assert_eq!(\n        baker_bob_customers,\n        [customer::Model {\n            id: 2,\n            name: \"Kara\".to_owned(),\n            notes: Some(\"Loves all cakes\".to_owned()),\n        }]\n    );\n\n    // find full model using with_linked\n    let select_baker_with_customer = Baker::find()\n        .find_with_linked(baker::BakedForCustomer)\n        .order_by_asc(baker::Column::Id)\n        .order_by_asc(Expr::col((\"r4\", customer::Column::Id)));\n\n    assert_eq!(\n        select_baker_with_customer\n            .build(sea_orm::DatabaseBackend::MySql)\n            .to_string(),\n        [\n            \"SELECT `baker`.`id` AS `A_id`,\",\n            \"`baker`.`name` AS `A_name`,\",\n            \"`baker`.`contact_details` AS `A_contact_details`,\",\n            \"`baker`.`bakery_id` AS `A_bakery_id`,\",\n            \"`r4`.`id` AS `B_id`,\",\n            \"`r4`.`name` AS `B_name`,\",\n            \"`r4`.`notes` AS `B_notes`\",\n            \"FROM `baker`\",\n            \"LEFT JOIN `cakes_bakers` AS `r0` ON `baker`.`id` = `r0`.`baker_id`\",\n            \"LEFT JOIN `cake` AS `r1` ON `r0`.`cake_id` = `r1`.`id`\",\n            \"LEFT JOIN `lineitem` AS `r2` ON `r1`.`id` = `r2`.`cake_id`\",\n            \"LEFT JOIN `order` AS `r3` ON `r2`.`order_id` = `r3`.`id`\",\n            \"LEFT JOIN `customer` AS `r4` ON `r3`.`customer_id` = `r4`.`id`\",\n            \"ORDER BY `baker`.`id` ASC, `r4`.`id` ASC\"\n        ]\n        .join(\" \")\n    );\n\n    assert_eq!(\n        select_baker_with_customer.all(&ctx.db)?,\n        [\n            (\n                baker::Model {\n                    id: 1,\n                    name: \"Baker Bob\".into(),\n                    contact_details: serde_json::json!({\n                        \"mobile\": \"+61424000000\",\n                        \"home\": \"0395555555\",\n                        \"address\": \"12 Test St, Testville, Vic, Australia\",\n                    }),\n                    bakery_id: Some(1),\n                },\n                vec![customer::Model {\n                    id: 2,\n                    name: \"Kara\".into(),\n                    notes: Some(\"Loves all cakes\".into()),\n                }]\n            ),\n            (\n                baker::Model {\n                    id: 2,\n                    name: \"Baker Bobby\".into(),\n                    contact_details: serde_json::json!({\n                        \"mobile\": \"+85212345678\",\n                    }),\n                    bakery_id: Some(1),\n                },\n                vec![\n                    customer::Model {\n                        id: 1,\n                        name: \"Kate\".into(),\n                        notes: Some(\"Loves cheese cake\".into()),\n                    },\n                    customer::Model {\n                        id: 1,\n                        name: \"Kate\".into(),\n                        notes: Some(\"Loves cheese cake\".into()),\n                    },\n                    customer::Model {\n                        id: 2,\n                        name: \"Kara\".into(),\n                        notes: Some(\"Loves all cakes\".into()),\n                    },\n                ]\n            ),\n            (\n                baker::Model {\n                    id: 3,\n                    name: \"Freerider\".into(),\n                    contact_details: serde_json::json!({\n                        \"mobile\": \"+85298765432\",\n                    }),\n                    bakery_id: Some(1),\n                },\n                vec![]\n            ),\n        ]\n    );\n\n    ctx.delete();\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub fn select_three() -> Result<(), DbErr> {\n    use common::bakery_chain::*;\n\n    let ctx = TestContext::new(\"test_select_three\");\n    create_tables(&ctx.db)?;\n\n    seed_data::init_1(&ctx, true);\n\n    let items: Vec<(order::Model, Option<customer::Model>)> = order::Entity::find()\n        .find_also_related(customer::Entity)\n        .order_by_asc(order::Column::Id)\n        .all(&ctx.db)\n        .unwrap();\n\n    let order = order::Model {\n        id: 101,\n        total: Decimal::from(10),\n        bakery_id: 42,\n        customer_id: 11,\n        placed_at: \"2020-01-01T00:00:00Z\".parse().unwrap(),\n    };\n\n    let customer = customer::Model {\n        id: 11,\n        name: \"Bob\".to_owned(),\n        notes: Some(\"Sweet tooth\".to_owned()),\n    };\n\n    assert_eq!(items.len(), 1);\n    assert_eq!(items[0].0, order);\n    assert_eq!(items[0].1.as_ref().unwrap(), &customer);\n\n    let line_1 = lineitem::Model {\n        id: 1,\n        price: 2.into(),\n        quantity: 2,\n        order_id: 101,\n        cake_id: 13,\n    };\n\n    let line_2 = lineitem::Model {\n        id: 2,\n        price: 3.into(),\n        quantity: 2,\n        order_id: 101,\n        cake_id: 15,\n    };\n\n    let cake_1 = cake::Entity::find_by_id(13).one(&ctx.db).unwrap().unwrap();\n\n    let cake_2 = cake::Entity::find_by_id(15).one(&ctx.db).unwrap().unwrap();\n\n    let items: Vec<(\n        order::Model,\n        Option<customer::Model>,\n        Option<lineitem::Model>,\n    )> = order::Entity::find()\n        .find_also_related(customer::Entity)\n        .find_also_related(lineitem::Entity)\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .all(&ctx.db)\n        .unwrap();\n\n    assert_eq!(\n        items,\n        vec![\n            (order.clone(), Some(customer.clone()), Some(line_1.clone())),\n            (order.clone(), Some(customer.clone()), Some(line_2.clone())),\n        ]\n    );\n\n    // same, just different API\n    let items: Vec<(\n        order::Model,\n        Option<customer::Model>,\n        Option<lineitem::Model>,\n    )> = order::Entity::find()\n        .find_also(order::Entity, customer::Entity)\n        .find_also(order::Entity, lineitem::Entity)\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .all(&ctx.db)\n        .unwrap();\n\n    assert_eq!(\n        items,\n        vec![\n            (order.clone(), Some(customer.clone()), Some(line_1.clone())),\n            (order.clone(), Some(customer.clone()), Some(line_2.clone())),\n        ]\n    );\n\n    let items: Vec<(order::Model, Vec<customer::Model>, Vec<lineitem::Model>)> =\n        order::Entity::find()\n            .find_also_related(customer::Entity)\n            .find_also_related(lineitem::Entity)\n            .order_by_asc(order::Column::Id)\n            .order_by_asc(lineitem::Column::Id)\n            .consolidate()\n            .all(&ctx.db)\n            .unwrap();\n\n    assert_eq!(\n        items,\n        vec![(\n            order.clone(),\n            vec![customer.clone()],\n            vec![line_1.clone(), line_2.clone()]\n        )]\n    );\n\n    let items: Vec<(order::Model, Option<lineitem::Model>, Option<cake::Model>)> =\n        order::Entity::find()\n            .find_also_related(lineitem::Entity)\n            .and_also_related(cake::Entity)\n            .order_by_asc(order::Column::Id)\n            .order_by_asc(lineitem::Column::Id)\n            .all(&ctx.db)\n            .unwrap();\n\n    assert_eq!(\n        items,\n        vec![\n            (order.clone(), Some(line_1.clone()), Some(cake_1.clone())),\n            (order.clone(), Some(line_2.clone()), Some(cake_2.clone())),\n        ]\n    );\n\n    let items: Vec<(order::Model, Vec<(lineitem::Model, Vec<cake::Model>)>)> =\n        order::Entity::find()\n            .find_also_related(lineitem::Entity)\n            .and_also_related(cake::Entity)\n            .order_by_asc(order::Column::Id)\n            .order_by_asc(lineitem::Column::Id)\n            .consolidate()\n            .all(&ctx.db)\n            .unwrap();\n\n    assert_eq!(\n        items,\n        vec![(\n            order.clone(),\n            vec![(line_1, vec![cake_1]), (line_2, vec![cake_2])]\n        )]\n    );\n\n    ctx.delete();\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub fn select_has_related() -> Result<(), DbErr> {\n    use common::bakery_chain::*;\n\n    let ctx = TestContext::new(\"test_select_has_related\");\n    create_tables(&ctx.db)?;\n    let db = &ctx.db;\n    seed_data::init_2(&ctx)?;\n\n    let bakery: Vec<bakery::Model> = bakery::Entity::find()\n        .has_related(cake::Entity, cake::Column::Name.contains(\"Chocolate\"))\n        .all(db)?;\n\n    assert_eq!(bakery.len(), 1);\n    assert_eq!(bakery[0].name, \"SeaSide Bakery\");\n\n    let bakery: Vec<bakery::Model> = bakery::Entity::find()\n        .has_related(cake::Entity, cake::Column::Name.contains(\"Lemon\"))\n        .order_by_asc(bakery::Column::Id)\n        .all(db)?;\n\n    assert_eq!(bakery.len(), 2);\n    assert_eq!(bakery[0].name, \"SeaSide Bakery\");\n    assert_eq!(bakery[1].name, \"LakeSide Bakery\");\n\n    let cake: Option<cake::Model> = cake::Entity::find()\n        .has_related(bakery::Entity, bakery::Column::Name.eq(\"SeaSide Bakery\"))\n        .order_by_asc(cake::Column::Name)\n        .one(db)?;\n\n    assert_eq!(\n        cake::Entity::find()\n            .has_related(bakery::Entity, bakery::Column::Name.eq(\"SeaSide Bakery\"))\n            .build(DbBackend::Sqlite)\n            .to_string(),\n        [\n            r#\"SELECT \"cake\".\"id\", \"cake\".\"name\", \"cake\".\"price\", \"cake\".\"bakery_id\", \"cake\".\"gluten_free\", \"cake\".\"serial\" FROM \"cake\"\"#,\n            r#\"WHERE EXISTS(SELECT 1 FROM \"bakery\"\"#,\n            r#\"WHERE \"bakery\".\"name\" = 'SeaSide Bakery'\"#,\n            r#\"AND \"cake\".\"bakery_id\" = \"bakery\".\"id\")\"#,\n        ]\n        .join(\" \")\n    );\n\n    assert_eq!(cake.unwrap().name, \"Chocolate Cake\");\n\n    let baker: Vec<baker::Model> = baker::Entity::find()\n        .has_related(cake::Entity, cake::Column::Name.contains(\"Chocolate\"))\n        .all(db)?;\n\n    assert_eq!(baker.len(), 1);\n    assert_eq!(baker[0].name, \"Alice\");\n\n    let baker: Vec<baker::Model> = baker::Entity::find()\n        .has_related(cake::Entity, cake::Column::Name.contains(\"Strawberry\"))\n        .all(db)?;\n\n    assert_eq!(baker.len(), 1);\n    assert_eq!(baker[0].name, \"Bob\");\n\n    let baker: Vec<baker::Model> = baker::Entity::find()\n        .has_related(cake::Entity, cake::Column::Name.contains(\"Lemon\"))\n        .order_by_asc(baker::Column::Id)\n        .all(db)?;\n\n    assert_eq!(baker.len(), 2);\n    assert_eq!(baker[0].name, \"Alice\");\n    assert_eq!(baker[1].name, \"Bob\");\n\n    let cake: Option<cake::Model> = cake::Entity::find()\n        .has_related(baker::Entity, baker::Column::Name.eq(\"Alice\"))\n        .order_by_asc(cake::Column::Name)\n        .one(db)?;\n\n    assert_eq!(cake.unwrap().name, \"Chocolate Cake\");\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/returning_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse common::{TestContext, bakery_chain, setup::*};\nuse sea_orm::{IntoActiveModel, NotSet, Set, entity::prelude::*};\nuse sea_query::{Expr, Query};\nuse serde_json::json;\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    use bakery_chain::bakery::*;\n\n    let ctx = TestContext::new(\"returning_tests\");\n    let db = &ctx.db;\n    let builder = db.get_database_backend();\n\n    let mut insert = Query::insert();\n    insert\n        .into_table(Entity)\n        .columns([Column::Name, Column::ProfitMargin])\n        .values_panic([\"Bakery Shop\".into(), 0.5.into()]);\n\n    let mut update = Query::update();\n    update\n        .table(Entity)\n        .values([\n            (Column::Name, \"Bakery 2\".into()),\n            (Column::ProfitMargin, 0.8.into()),\n        ])\n        .and_where(Column::Id.eq(1));\n\n    let columns = [Column::Id, Column::Name, Column::ProfitMargin];\n    let returning =\n        Query::returning().exprs(columns.into_iter().map(|c| c.into_returning_expr(builder)));\n\n    bakery_chain::create_bakery_table(db)?;\n\n    if db.support_returning() {\n        insert.returning(returning.clone());\n        let insert_res = db\n            .query_one(&insert)?\n            .expect(\"Insert failed with query_one\");\n        let id: i32 = insert_res.try_get(\"\", \"id\")?;\n        assert_eq!(id, 1);\n        let name: String = insert_res.try_get(\"\", \"name\")?;\n        assert_eq!(name, \"Bakery Shop\");\n        let profit_margin: f64 = insert_res.try_get(\"\", \"profit_margin\")?;\n        assert_eq!(profit_margin, 0.5);\n\n        update.returning(returning.clone());\n        let update_res = db.query_one(&update)?.expect(\"Update filed with query_one\");\n        let id: i32 = update_res.try_get(\"\", \"id\")?;\n        assert_eq!(id, 1);\n        let name: String = update_res.try_get(\"\", \"name\")?;\n        assert_eq!(name, \"Bakery 2\");\n        let profit_margin: f64 = update_res.try_get(\"\", \"profit_margin\")?;\n        assert_eq!(profit_margin, 0.8);\n    } else {\n        let insert_res = db.execute(&insert)?;\n        assert!(insert_res.rows_affected() > 0);\n\n        let update_res = db.execute(&update)?;\n        assert!(update_res.rows_affected() > 0);\n    }\n\n    ctx.delete();\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn insert_many() {\n    pub use common::{TestContext, features::*};\n    use edit_log::*;\n\n    let ctx = TestContext::new(\"returning_tests_insert_many\");\n    let db = &ctx.db;\n\n    create_edit_log_table(db).unwrap();\n\n    Entity::insert(ActiveModel {\n        id: NotSet,\n        action: Set(\"one\".into()),\n        values: Set(json!({ \"id\": \"unique-id-001\" })),\n    })\n    .exec(db)\n    .unwrap();\n\n    assert_eq!(\n        Entity::find().all(db).unwrap(),\n        [Model {\n            id: 1,\n            action: \"one\".into(),\n            values: json!({ \"id\": \"unique-id-001\" }),\n        },]\n    );\n\n    assert!(\n        Entity::insert_many::<ActiveModel, _>([])\n            .exec_with_returning(db)\n            .unwrap()\n            .is_empty()\n    );\n\n    let result = Entity::insert_many([\n        ActiveModel {\n            id: NotSet,\n            action: Set(\"two\".into()),\n            values: Set(json!({ \"id\": \"unique-id-002\" })),\n        },\n        ActiveModel {\n            id: NotSet,\n            action: Set(\"three\".into()),\n            values: Set(json!({ \"id\": \"unique-id-003\" })),\n        },\n    ])\n    .exec_with_returning(db);\n\n    if db.support_returning() {\n        assert_eq!(\n            result.unwrap(),\n            [\n                Model {\n                    id: 2,\n                    action: \"two\".into(),\n                    values: json!({ \"id\": \"unique-id-002\" }),\n                },\n                Model {\n                    id: 3,\n                    action: \"three\".into(),\n                    values: json!({ \"id\": \"unique-id-003\" }),\n                },\n            ]\n        );\n    } else {\n        assert!(matches!(result, Err(DbErr::BackendNotSupported { .. })));\n    }\n\n    assert!(\n        Entity::insert_many::<ActiveModel, _>([])\n            .exec_with_returning_keys(db)\n            .unwrap()\n            .is_empty()\n    );\n\n    let result = Entity::insert_many([\n        ActiveModel {\n            id: NotSet,\n            action: Set(\"four\".into()),\n            values: Set(json!({ \"id\": \"unique-id-004\" })),\n        },\n        ActiveModel {\n            id: NotSet,\n            action: Set(\"five\".into()),\n            values: Set(json!({ \"id\": \"unique-id-005\" })),\n        },\n    ])\n    .exec_with_returning_keys(db);\n\n    if db.support_returning() {\n        assert_eq!(result.unwrap(), [4, 5]);\n    } else {\n        assert!(matches!(result, Err(DbErr::BackendNotSupported { .. })));\n    }\n}\n\n#[sea_orm_macros::test]\nfn insert_many_composite_key() {\n    use bakery_chain::{baker, cake, cakes_bakers};\n    pub use common::{TestContext, features::*};\n\n    let ctx = TestContext::new(\"returning_tests_insert_many_composite_key\");\n    let db = &ctx.db;\n\n    bakery_chain::create_bakery_table(db).unwrap();\n    bakery_chain::create_baker_table(db).unwrap();\n    bakery_chain::create_cake_table(db).unwrap();\n    bakery_chain::create_cakes_bakers_table(db).unwrap();\n\n    baker::Entity::insert_many([\n        baker::ActiveModel {\n            id: NotSet,\n            name: Set(\"Baker 1\".to_owned()),\n            contact_details: Set(json!(null)),\n            bakery_id: Set(None),\n        },\n        baker::ActiveModel {\n            id: NotSet,\n            name: Set(\"Baker 2\".to_owned()),\n            contact_details: Set(json!(null)),\n            bakery_id: Set(None),\n        },\n    ])\n    .exec(db)\n    .unwrap();\n\n    cake::Entity::insert_many([\n        cake::ActiveModel {\n            id: NotSet,\n            name: Set(\"Cake 1\".to_owned()),\n            price: Set(Default::default()),\n            bakery_id: Set(None),\n            gluten_free: Set(false),\n            serial: Set(Default::default()),\n        },\n        cake::ActiveModel {\n            id: NotSet,\n            name: Set(\"Cake 2\".to_owned()),\n            price: Set(Default::default()),\n            bakery_id: Set(None),\n            gluten_free: Set(false),\n            serial: Set(Default::default()),\n        },\n    ])\n    .exec(db)\n    .unwrap();\n\n    let result = cakes_bakers::Entity::insert_many([\n        cakes_bakers::ActiveModel {\n            cake_id: Set(1),\n            baker_id: Set(2),\n        },\n        cakes_bakers::ActiveModel {\n            cake_id: Set(2),\n            baker_id: Set(1),\n        },\n    ])\n    .exec_with_returning_keys(db);\n\n    if db.support_returning() {\n        assert_eq!(result.unwrap(), [(1, 2), (2, 1)]);\n    } else {\n        assert!(matches!(result, Err(DbErr::BackendNotSupported { .. })));\n    }\n}\n\n#[sea_orm_macros::test]\nfn update_many() -> Result<(), DbErr> {\n    pub use common::{TestContext, features::*};\n    use edit_log::*;\n\n    let ctx = TestContext::new(\"returning_tests_update_many\");\n    let db = &ctx.db;\n\n    create_edit_log_table(db)?;\n\n    Entity::insert(\n        Model {\n            id: 1,\n            action: \"before_save\".into(),\n            values: json!({ \"id\": \"unique-id-001\" }),\n        }\n        .into_active_model(),\n    )\n    .exec(db)?;\n\n    Entity::insert(\n        Model {\n            id: 2,\n            action: \"before_save\".into(),\n            values: json!({ \"id\": \"unique-id-002\" }),\n        }\n        .into_active_model(),\n    )\n    .exec(db)?;\n\n    Entity::insert(\n        Model {\n            id: 3,\n            action: \"before_save\".into(),\n            values: json!({ \"id\": \"unique-id-003\" }),\n        }\n        .into_active_model(),\n    )\n    .exec(db)?;\n\n    assert_eq!(\n        Entity::find().all(db)?,\n        [\n            Model {\n                id: 1,\n                action: \"before_save\".into(),\n                values: json!({ \"id\": \"unique-id-001\" }),\n            },\n            Model {\n                id: 2,\n                action: \"before_save\".into(),\n                values: json!({ \"id\": \"unique-id-002\" }),\n            },\n            Model {\n                id: 3,\n                action: \"before_save\".into(),\n                values: json!({ \"id\": \"unique-id-003\" }),\n            },\n        ]\n    );\n\n    // Update many with returning\n    let result = Entity::update_many()\n        .col_expr(\n            Column::Values,\n            Expr::value(json!({ \"remarks\": \"save log\" })),\n        )\n        .filter(Column::Action.eq(\"before_save\"))\n        .exec_with_returning(db);\n\n    if db.support_returning() {\n        assert_eq!(\n            result.unwrap(),\n            [\n                Model {\n                    id: 1,\n                    action: \"before_save\".into(),\n                    values: json!({ \"remarks\": \"save log\" }),\n                },\n                Model {\n                    id: 2,\n                    action: \"before_save\".into(),\n                    values: json!({ \"remarks\": \"save log\" }),\n                },\n                Model {\n                    id: 3,\n                    action: \"before_save\".into(),\n                    values: json!({ \"remarks\": \"save log\" }),\n                },\n            ]\n        );\n    } else {\n        assert!(matches!(result, Err(DbErr::BackendNotSupported { .. })));\n    }\n\n    // No-op\n    assert_eq!(\n        Entity::update_many()\n            .filter(Column::Action.eq(\"before_save\"))\n            .exec_with_returning(db)?,\n        []\n    );\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nfn delete_many() -> Result<(), DbErr> {\n    pub use common::{TestContext, features::*};\n    use edit_log::*;\n\n    let ctx = TestContext::new(\"returning_tests_delete_many\");\n    let db = &ctx.db;\n\n    create_edit_log_table(db)?;\n\n    let inserted_models = [\n        Model {\n            id: 1,\n            action: \"before_save\".to_string(),\n            values: json!({ \"id\": \"unique-id-001\" }),\n        },\n        Model {\n            id: 2,\n            action: \"before_save\".to_string(),\n            values: json!({ \"id\": \"unique-id-002\" }),\n        },\n    ];\n\n    if db.support_returning() {\n        assert_eq!(\n            Entity::insert_many(vec![\n                ActiveModel {\n                    id: NotSet,\n                    action: Set(\"before_save\".to_string()),\n                    values: Set(json!({ \"id\": \"unique-id-001\" })),\n                },\n                ActiveModel {\n                    id: NotSet,\n                    action: Set(\"before_save\".to_string()),\n                    values: Set(json!({ \"id\": \"unique-id-002\" })),\n                },\n            ])\n            .exec_with_returning(db)\n            .unwrap(),\n            inserted_models\n        );\n    } else {\n        Entity::insert_many(vec![\n            ActiveModel {\n                id: NotSet,\n                action: Set(\"before_save\".to_string()),\n                values: Set(json!({ \"id\": \"unique-id-001\" })),\n            },\n            ActiveModel {\n                id: NotSet,\n                action: Set(\"before_save\".to_string()),\n                values: Set(json!({ \"id\": \"unique-id-002\" })),\n            },\n        ])\n        .exec(db)\n        .unwrap();\n    }\n\n    if db.support_returning() {\n        assert_eq!(\n            Entity::delete_many()\n                .filter(Column::Action.eq(\"before_save\"))\n                .exec_with_returning(db)\n                .unwrap(),\n            inserted_models\n        );\n    } else {\n        assert_eq!(Entity::delete_many().exec(db).unwrap().rows_affected, 2);\n    }\n\n    let inserted_model_3 = Model {\n        id: 3,\n        action: \"before_save\".to_string(),\n        values: json!({ \"id\": \"unique-id-003\" }),\n    };\n\n    Entity::insert(ActiveModel {\n        id: NotSet,\n        action: Set(\"before_save\".to_string()),\n        values: Set(json!({ \"id\": \"unique-id-003\" })),\n    })\n    .exec(db)?;\n\n    // Delete one\n    if db.support_returning() {\n        assert_eq!(\n            Entity::delete(ActiveModel {\n                id: Set(3),\n                ..Default::default()\n            })\n            .exec_with_returning(db)\n            .unwrap(),\n            Some(inserted_model_3)\n        );\n    } else {\n        assert_eq!(\n            Entity::delete(ActiveModel {\n                id: Set(3),\n                ..Default::default()\n            })\n            .exec(db)\n            .unwrap()\n            .rows_affected,\n            1\n        );\n    }\n\n    // No-op\n    if db.support_returning() {\n        assert_eq!(Entity::delete_many().exec_with_returning(db).unwrap(), []);\n    } else {\n        assert_eq!(Entity::delete_many().exec(db).unwrap().rows_affected, 0);\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/schema_sync_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse crate::common::TestContext;\nuse sea_orm::{\n    DatabaseConnection, DbErr,\n    entity::*,\n    query::*,\n    sea_query::{Condition, Expr, Query},\n};\n\n// Scenario 1: table is first synced with a `#[sea_orm(unique)]` column already\n// present. Repeated syncs must not drop the column-level unique constraint.\nmod item_v1 {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sync_item\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub name: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// Scenario 2a: initial version of the table — no unique column yet.\nmod product_v1 {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sync_product\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// Scenario 2b: updated version — a unique column is added.\nmod product_v2 {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sync_product\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub sku: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// Scenario 3a: initial version — column exists without UNIQUE.\nmod user_v1 {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sync_user\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub email: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// Scenario 3b: updated version — the existing column is made unique.\nmod user_v2 {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sync_user\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub email: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n/// Regression test for <https://github.com/SeaQL/sea-orm/issues/2970>.\n///\n/// A table with a `#[sea_orm(unique)]` column is created on the first sync.\n/// The subsequent sync must not attempt to drop the column-level unique index.\n#[sea_orm_macros::test]\nfn test_sync_unique_column_no_drop() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"test_sync_unique_column_no_drop\");\n    let db = &ctx.db;\n\n    #[cfg(feature = \"schema-sync\")]\n    {\n        // First sync: creates the table with the unique column\n        db.get_schema_builder().register(item_v1::Entity).sync(db)?;\n\n        // Second sync: must not try to drop the column-level unique index\n        db.get_schema_builder().register(item_v1::Entity).sync(db)?;\n\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert!(\n            pg_index_exists(db, \"sync_item\", \"sync_item_name_key\")?,\n            \"unique index on `sync_item.name` should still exist after repeated sync\"\n        );\n    }\n\n    Ok(())\n}\n\n/// Regression test for <https://github.com/SeaQL/sea-orm/issues/2970>.\n///\n/// A unique column is added to an existing table via sync (ALTER TABLE ADD\n/// COLUMN … UNIQUE), which creates a column-level unique index. A subsequent\n/// sync must not attempt to drop that index.\n#[sea_orm_macros::test]\n#[cfg(not(any(feature = \"sqlx-sqlite\", feature = \"rusqlite\")))]\nfn test_sync_add_unique_column_no_drop() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"test_sync_add_unique_column_no_drop\");\n    let db = &ctx.db;\n\n    #[cfg(feature = \"schema-sync\")]\n    {\n        // First sync: creates the table without the unique column\n        db.get_schema_builder()\n            .register(product_v1::Entity)\n            .sync(db)?;\n\n        // Second sync: adds the unique column via ALTER TABLE ADD COLUMN … UNIQUE\n        db.get_schema_builder()\n            .register(product_v2::Entity)\n            .sync(db)?;\n\n        // Third sync: must not try to drop the unique index created above\n        db.get_schema_builder()\n            .register(product_v2::Entity)\n            .sync(db)?;\n\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert!(\n            pg_index_exists(db, \"sync_product\", \"sync_product_sku_key\")?,\n            \"unique index on `sync_product.sku` should still exist after repeated sync\"\n        );\n    }\n\n    Ok(())\n}\n\n/// Scenario 3: an existing column is made unique in a later sync.\n///\n/// When a column that already exists in the DB is annotated with\n/// `#[sea_orm(unique)]`, the sync must create a unique index for it.\n#[sea_orm_macros::test]\nfn test_sync_make_existing_column_unique() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"test_sync_make_existing_column_unique\");\n    let db = &ctx.db;\n\n    #[cfg(feature = \"schema-sync\")]\n    {\n        // First sync: creates the table with a plain (non-unique) email column\n        db.get_schema_builder().register(user_v1::Entity).sync(db)?;\n\n        // Second sync: email is now marked unique — should create the unique index\n        db.get_schema_builder().register(user_v2::Entity).sync(db)?;\n\n        // Third sync: must not try to drop or re-create the index\n        db.get_schema_builder().register(user_v2::Entity).sync(db)?;\n\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert!(\n            pg_index_exists(db, \"sync_user\", \"idx-sync_user-email\")?,\n            \"unique index on `sync_user.email` should be created when column is made unique\"\n        );\n    }\n\n    Ok(())\n}\n\n#[cfg(feature = \"sqlx-postgres\")]\nfn pg_index_exists(db: &DatabaseConnection, table: &str, index: &str) -> Result<bool, DbErr> {\n    db.query_one(\n        Query::select()\n            .expr(Expr::cust(\"COUNT(*) > 0\"))\n            .from(\"pg_indexes\")\n            .cond_where(\n                Condition::all()\n                    .add(Expr::cust(\"schemaname = CURRENT_SCHEMA()\"))\n                    .add(Expr::col(\"tablename\").eq(table))\n                    .add(Expr::col(\"indexname\").eq(index)),\n            ),\n    )?\n    .unwrap()\n    .try_get_by_index(0)\n    .map_err(DbErr::from)\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/self_join_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DbBackend, IntoActiveModel, QueryOrder, entity::prelude::*, query::*};\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"self_join_tests\");\n    create_self_join_table(&ctx.db)?;\n    create_metadata(&ctx.db)?;\n    ctx.delete();\n    find_linked_001();\n    find_also_linked_001();\n\n    Ok(())\n}\n\npub fn create_metadata(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let model = self_join::Model {\n        uuid: Uuid::new_v4(),\n        uuid_ref: None,\n        time: Some(Time::from_hms_opt(1, 00, 00).unwrap()),\n    };\n\n    model.clone().into_active_model().insert(db)?;\n\n    let linked_model = self_join::Model {\n        uuid: Uuid::new_v4(),\n        uuid_ref: Some(model.clone().uuid),\n        time: Some(Time::from_hms_opt(2, 00, 00).unwrap()),\n    };\n\n    linked_model.clone().into_active_model().insert(db)?;\n\n    let not_linked_model = self_join::Model {\n        uuid: Uuid::new_v4(),\n        uuid_ref: None,\n        time: Some(Time::from_hms_opt(3, 00, 00).unwrap()),\n    };\n\n    not_linked_model.clone().into_active_model().insert(db)?;\n\n    assert_eq!(\n        model.find_linked(self_join::SelfReferencingLink).all(db)?,\n        Vec::<self_join::Model>::new()\n    );\n\n    assert_eq!(\n        linked_model\n            .find_linked(self_join::SelfReferencingLink)\n            .all(db)?,\n        [model.clone()]\n    );\n\n    assert_eq!(\n        not_linked_model\n            .find_linked(self_join::SelfReferencingLink)\n            .all(db)?,\n        Vec::<self_join::Model>::new()\n    );\n\n    assert_eq!(\n        self_join::Entity::find()\n            .find_also_linked(self_join::SelfReferencingLink)\n            .order_by_asc(self_join::Column::Time)\n            .all(db)?,\n        [\n            (model.clone(), None),\n            (linked_model, Some(model)),\n            (not_linked_model, None),\n        ]\n    );\n\n    Ok(())\n}\n\nfn find_linked_001() {\n    use self_join::*;\n\n    let self_join_model = Model {\n        uuid: Uuid::default(),\n        uuid_ref: None,\n        time: None,\n    };\n\n    assert_eq!(\n        self_join_model\n            .find_linked(SelfReferencingLink)\n            .build(DbBackend::MySql)\n            .to_string(),\n        [\n            r\"SELECT `self_join`.`uuid`, `self_join`.`uuid_ref`, `self_join`.`time`\",\n            r\"FROM `self_join`\",\n            r\"INNER JOIN `self_join` AS `r0` ON `r0`.`uuid_ref` = `self_join`.`uuid`\",\n            r\"WHERE `r0`.`uuid` = '00000000-0000-0000-0000-000000000000'\",\n        ]\n        .join(\" \")\n    );\n}\n\nfn find_also_linked_001() {\n    use self_join::*;\n\n    assert_eq!(\n        Entity::find()\n            .find_also_linked(SelfReferencingLink)\n            .build(DbBackend::MySql)\n            .to_string(),\n        [\n            r\"SELECT `self_join`.`uuid` AS `A_uuid`, `self_join`.`uuid_ref` AS `A_uuid_ref`, `self_join`.`time` AS `A_time`,\",\n            r\"`r0`.`uuid` AS `B_uuid`, `r0`.`uuid_ref` AS `B_uuid_ref`, `r0`.`time` AS `B_time`\",\n            r\"FROM `self_join`\",\n            r\"LEFT JOIN `self_join` AS `r0` ON `self_join`.`uuid_ref` = `r0`.`uuid`\",\n        ]\n        .join(\" \")\n    );\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/sequential_op_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse common::{TestContext, bakery_chain::*, setup::*};\nuse rust_decimal::prelude::*;\nuse sea_orm::{DatabaseConnection, FromQueryResult, entity::*, prelude::ChronoUtc, query::*};\nuse uuid::Uuid;\n\n// Run the test locally:\n// DATABASE_URL=\"mysql://root:@localhost\" cargo test --features sqlx-mysql,runtime-async-std --test sequential_op_tests\n#[sea_orm_macros::test]\n#[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-postgres\"))]\npub fn test_multiple_operations() {\n    let ctx = TestContext::new(\"multiple_sequential_operations\");\n\n    create_tables(&ctx.db).unwrap();\n    seed_data(&ctx.db);\n    let baker_least_sales = find_baker_least_sales(&ctx.db).unwrap();\n    assert_eq!(baker_least_sales.name, \"Baker 2\");\n\n    let new_cake = create_cake(&ctx.db, baker_least_sales).unwrap();\n    create_order(&ctx.db, new_cake);\n\n    let baker_least_sales = find_baker_least_sales(&ctx.db).unwrap();\n    assert_eq!(baker_least_sales.name, \"Baker 1\");\n\n    ctx.delete();\n}\n\nfn seed_data(db: &DatabaseConnection) {\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert bakery\");\n\n    let baker_1 = baker::ActiveModel {\n        name: Set(\"Baker 1\".to_owned()),\n        contact_details: Set(serde_json::json!({})),\n        bakery_id: Set(Some(bakery.id.clone().unwrap())),\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert baker\");\n\n    let _baker_2 = baker::ActiveModel {\n        name: Set(\"Baker 2\".to_owned()),\n        contact_details: Set(serde_json::json!({})),\n        bakery_id: Set(Some(bakery.id.clone().unwrap())),\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert baker\");\n\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(bakery.id.clone().unwrap())),\n        ..Default::default()\n    };\n\n    let mud_cake = Cake::insert(mud_cake)\n        .exec(db)\n        .expect(\"could not insert cake\");\n\n    let choc_cake = cake::ActiveModel {\n        name: Set(\"Choc Cake\".to_owned()),\n        price: Set(rust_dec(9.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(bakery.id.clone().unwrap())),\n        ..Default::default()\n    };\n\n    let choc_cake = Cake::insert(choc_cake)\n        .exec(db)\n        .expect(\"could not insert cake\");\n\n    let cake_baker = cakes_bakers::ActiveModel {\n        cake_id: Set(mud_cake.last_insert_id),\n        baker_id: Set(baker_1.id.clone().unwrap()),\n    };\n\n    let cake_baker_res = CakesBakers::insert(cake_baker.clone())\n        .exec(db)\n        .expect(\"could not insert cake_baker\");\n    assert_eq!(\n        cake_baker_res.last_insert_id,\n        (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())\n    );\n\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert customer\");\n\n    let kate_order_1 = order::ActiveModel {\n        bakery_id: Set(bakery.id.clone().unwrap()),\n        customer_id: Set(customer_kate.id.clone().unwrap()),\n        total: Set(rust_dec(99.95)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert order\");\n\n    let _lineitem = lineitem::ActiveModel {\n        cake_id: Set(mud_cake.last_insert_id),\n        price: Set(rust_dec(10.00)),\n        quantity: Set(12),\n        order_id: Set(kate_order_1.id.clone().unwrap()),\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert order\");\n\n    let _lineitem2 = lineitem::ActiveModel {\n        cake_id: Set(choc_cake.last_insert_id),\n        price: Set(rust_dec(50.00)),\n        quantity: Set(2),\n        order_id: Set(kate_order_1.id.clone().unwrap()),\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert order\");\n\n    assert!(\n        lineitem::ActiveModel {\n            cake_id: Set(choc_cake.last_insert_id),\n            price: Set(rust_dec(50.00)),\n            quantity: Set(2),\n            order_id: Set(kate_order_1.id.clone().unwrap()),\n            ..Default::default()\n        }\n        .save(db)\n        .is_err()\n    ); // violates unique key\n}\n\nfn find_baker_least_sales(db: &DatabaseConnection) -> Option<baker::Model> {\n    #[cfg(any(feature = \"sqlx-postgres\"))]\n    type Type = i64;\n    #[cfg(not(any(feature = \"sqlx-postgres\")))]\n    type Type = Decimal;\n\n    #[derive(Debug, FromQueryResult)]\n    struct SelectResult {\n        id: i32,\n        cakes_sold_opt: Option<Type>,\n    }\n\n    #[derive(Debug)]\n    struct LeastSalesBakerResult {\n        id: i32,\n        cakes_sold: Decimal,\n    }\n\n    let rel: RelationDef = cakes_bakers::Entity::belongs_to(baker::Entity)\n        .from(cakes_bakers::Column::BakerId)\n        .to(baker::Column::Id)\n        .into();\n\n    let rel2: RelationDef = cakes_bakers::Entity::belongs_to(cake::Entity)\n        .from(cakes_bakers::Column::CakeId)\n        .to(cake::Column::Id)\n        .into();\n\n    let rel3: RelationDef = cake::Entity::has_many(lineitem::Entity)\n        .from(cake::Column::Id)\n        .to(lineitem::Column::CakeId)\n        .into();\n\n    let select = cakes_bakers::Entity::find()\n        .join(JoinType::RightJoin, rel)\n        .join(JoinType::LeftJoin, rel2)\n        .join(JoinType::LeftJoin, rel3)\n        .select_only()\n        .column(baker::Column::Id)\n        .column_as(lineitem::Column::Quantity.sum(), \"cakes_sold_opt\")\n        .group_by(baker::Column::Id);\n\n    let mut results: Vec<LeastSalesBakerResult> = select\n        .into_model::<SelectResult>()\n        .all(db)\n        .unwrap()\n        .into_iter()\n        .map(|b| LeastSalesBakerResult {\n            id: b.id,\n            cakes_sold: b.cakes_sold_opt.unwrap_or_default().into(),\n        })\n        .collect();\n\n    results.sort_by(|a, b| b.cakes_sold.cmp(&a.cakes_sold));\n\n    Baker::find_by_id(results.last().unwrap().id)\n        .one(db)\n        .unwrap()\n}\n\nfn create_cake(db: &DatabaseConnection, baker: baker::Model) -> Option<cake::Model> {\n    let new_cake = cake::ActiveModel {\n        name: Set(\"New Cake\".to_owned()),\n        price: Set(rust_dec(8.00)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(baker.bakery_id.unwrap())),\n        ..Default::default()\n    };\n\n    let cake_insert_res = Cake::insert(new_cake)\n        .exec(db)\n        .expect(\"could not insert cake\");\n\n    let cake_baker = cakes_bakers::ActiveModel {\n        cake_id: Set(cake_insert_res.last_insert_id),\n        baker_id: Set(baker.id),\n    };\n\n    let cake_baker_res = CakesBakers::insert(cake_baker.clone())\n        .exec(db)\n        .expect(\"could not insert cake_baker\");\n    assert_eq!(\n        cake_baker_res.last_insert_id,\n        (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())\n    );\n\n    Cake::find_by_id(cake_insert_res.last_insert_id)\n        .one(db)\n        .unwrap()\n}\n\nfn create_order(db: &DatabaseConnection, cake: cake::Model) {\n    let another_customer = customer::ActiveModel {\n        name: Set(\"John\".to_owned()),\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert customer\");\n\n    let order = order::ActiveModel {\n        bakery_id: Set(cake.bakery_id.unwrap()),\n        customer_id: Set(another_customer.id.clone().unwrap()),\n        total: Set(rust_dec(200.00)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert order\");\n\n    let _lineitem = lineitem::ActiveModel {\n        cake_id: Set(cake.id),\n        price: Set(rust_dec(10.00)),\n        quantity: Set(300),\n        order_id: Set(order.id.clone().unwrap()),\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert order\");\n}\n\npub fn test_delete_bakery(db: &DatabaseConnection) {\n    let initial_bakeries = Bakery::find().all(db).unwrap().len();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(db)\n    .expect(\"could not insert bakery\");\n\n    assert_eq!(Bakery::find().all(db).unwrap().len(), initial_bakeries + 1);\n\n    let _result = bakery.delete(db).expect(\"failed to delete bakery\");\n\n    assert_eq!(Bakery::find().all(db).unwrap().len(), initial_bakeries);\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/sql_err_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\npub use common::{TestContext, bakery_chain::*, setup::*};\npub use sea_orm::{\n    ConnectionTrait, DatabaseConnection, DbBackend, EntityName, ExecResult, entity::*,\n    error::DbErr, error::SqlErr, tests_cfg,\n};\nuse uuid::Uuid;\n\n#[sea_orm_macros::test]\nfn main() {\n    let ctx = TestContext::new(\"bakery_chain_sql_err_tests\");\n    create_bakery_table(&ctx.db).unwrap();\n    create_cake_table(&ctx.db).unwrap();\n    test_error(&ctx.db);\n    ctx.delete();\n}\n\npub fn test_error(db: &DatabaseConnection) {\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Moldy Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(None),\n        ..Default::default()\n    };\n\n    let cake = mud_cake.save(db).expect(\"could not insert cake\");\n\n    // if compiling without sqlx, this assignment will complain,\n    // but the whole test is useless in that case anyway.\n    #[allow(unused_variables)]\n    let error: DbErr = cake\n        .into_active_model()\n        .insert(db)\n        .expect_err(\"inserting should fail due to duplicate primary key\");\n\n    assert!(matches!(\n        error.sql_err(),\n        Some(SqlErr::UniqueConstraintViolation(_))\n    ));\n\n    let fk_cake = cake::ActiveModel {\n        name: Set(\"fk error Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(1000)),\n        ..Default::default()\n    };\n\n    let fk_error = fk_cake\n        .insert(db)\n        .expect_err(\"create foreign key should fail with non-primary key\");\n\n    assert!(matches!(\n        fk_error.sql_err(),\n        Some(SqlErr::ForeignKeyConstraintViolation(_))\n    ));\n\n    let invalid_error = DbErr::Custom(\"random error\".to_string());\n    assert_eq!(invalid_error.sql_err(), None)\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/stream_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\npub use sea_orm::entity::*;\npub use sea_orm::{ConnectionTrait, DbErr, QueryFilter};\n\n#[sea_orm_macros::test]\npub fn stream() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"stream\");\n    create_bakery_table(&ctx.db)?;\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)?;\n\n    let result = Bakery::find_by_id(bakery.id.clone().unwrap())\n        .stream(&ctx.db)?\n        .next()\n        .unwrap()?;\n\n    assert_eq!(result.id, bakery.id.unwrap());\n\n    ctx.delete();\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/string_primary_key_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, TryInsertResult, entity::prelude::*, entity::*};\nuse serde_json::json;\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"features_schema_string_primary_key_tests\");\n    create_repository_table(&ctx.db)?;\n    create_edit_log_table(&ctx.db)?;\n    create_and_update_repository(&ctx.db)?;\n    insert_and_delete_repository(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn insert_and_delete_repository(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let repository = repository::Model {\n        id: \"unique-id-001\".to_owned(),\n        owner: \"GC\".to_owned(),\n        name: \"G.C.\".to_owned(),\n        description: None,\n    }\n    .into_active_model();\n\n    let result = repository.clone().insert(db)?;\n\n    assert_eq!(\n        result,\n        repository::Model {\n            id: \"unique-id-001\".to_owned(),\n            owner: \"GC\".to_owned(),\n            name: \"G.C.\".to_owned(),\n            description: None,\n        }\n    );\n\n    #[cfg(any(feature = \"sqlx-sqlite\", feature = \"sqlx-postgres\"))]\n    {\n        use sea_orm::sea_query::OnConflict;\n\n        let err = Repository::insert(repository.clone())\n            // MySQL does not support DO NOTHING, we might workaround that later\n            .on_conflict(OnConflict::new().do_nothing().to_owned())\n            .exec(db);\n\n        assert_eq!(err.err(), Some(DbErr::RecordNotInserted));\n    }\n\n    result.delete(db)?;\n\n    assert_eq!(\n        edit_log::Entity::find().all(db)?,\n        [\n            edit_log::Model {\n                id: 1,\n                action: \"before_save\".into(),\n                values: json!({\n                    \"description\": null,\n                    \"id\": \"unique-id-001\",\n                    \"name\": \"G.C.\",\n                    \"owner\": \"GC\",\n                }),\n            },\n            edit_log::Model {\n                id: 2,\n                action: \"after_save\".into(),\n                values: json!({\n                    \"description\": null,\n                    \"id\": \"unique-id-001\",\n                    \"name\": \"G.C.\",\n                    \"owner\": \"GC\",\n                }),\n            },\n            edit_log::Model {\n                id: 3,\n                action: \"before_delete\".into(),\n                values: json!({\n                    \"description\": null,\n                    \"id\": \"unique-id-001\",\n                    \"name\": \"G.C.\",\n                    \"owner\": \"GC\",\n                }),\n            },\n            edit_log::Model {\n                id: 4,\n                action: \"after_delete\".into(),\n                values: json!({\n                    \"description\": null,\n                    \"id\": \"unique-id-001\",\n                    \"name\": \"G.C.\",\n                    \"owner\": \"GC\",\n                }),\n            },\n        ]\n    );\n\n    #[cfg(any(feature = \"sqlx-sqlite\", feature = \"sqlx-postgres\"))]\n    {\n        let result = Repository::insert_many([\n            repository::Model {\n                id: \"unique-id-002\".to_owned(), // conflict\n                owner: \"GC\".to_owned(),\n                name: \"G.C.\".to_owned(),\n                description: None,\n            }\n            .into_active_model(),\n            repository::Model {\n                id: \"unique-id-003\".to_owned(), // insert succeed\n                owner: \"GC\".to_owned(),\n                name: \"G.C.\".to_owned(),\n                description: None,\n            }\n            .into_active_model(),\n        ])\n        .on_conflict_do_nothing()\n        .exec_with_returning_many(db)?;\n\n        match result {\n            TryInsertResult::Inserted(inserted) => {\n                assert_eq!(inserted.len(), 1);\n                assert_eq!(inserted[0].id, \"unique-id-003\");\n            }\n            _ => panic!(\"{result:?}\"),\n        }\n    }\n\n    Ok(())\n}\n\npub fn create_and_update_repository(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let repository = repository::Model {\n        id: \"unique-id-002\".to_owned(),\n        owner: \"GC\".to_owned(),\n        name: \"G.C.\".to_owned(),\n        description: None,\n    };\n\n    let res = Repository::insert(repository.clone().into_active_model()).exec(db)?;\n\n    assert_eq!(Repository::find().one(db)?, Some(repository.clone()));\n\n    assert_eq!(res.last_insert_id, repository.id);\n\n    let updated_active_model = repository::ActiveModel {\n        description: Set(Some(\"description...\".to_owned())),\n        ..repository.clone().into_active_model()\n    };\n\n    let update_res = Repository::update(updated_active_model.clone())\n        .validate()?\n        .filter(repository::Column::Id.eq(\"not-exists-id\".to_owned()))\n        .exec(db);\n\n    assert_eq!(update_res, Err(DbErr::RecordNotUpdated));\n\n    let update_res = Repository::update(updated_active_model)\n        .validate()?\n        .filter(repository::Column::Id.eq(\"unique-id-002\".to_owned()))\n        .exec(db)?;\n\n    assert_eq!(\n        update_res,\n        repository::Model {\n            id: \"unique-id-002\".to_owned(),\n            owner: \"GC\".to_owned(),\n            name: \"G.C.\".to_owned(),\n            description: Some(\"description...\".to_owned()),\n        }\n    );\n\n    let updated_active_model = repository::ActiveModel {\n        description: Set(None),\n        ..repository.clone().into_active_model()\n    };\n\n    let update_res = Repository::update(updated_active_model.clone())\n        .validate()?\n        .filter(repository::Column::Id.eq(\"unique-id-002\".to_owned()))\n        .exec(db)?;\n\n    assert_eq!(\n        update_res,\n        repository::Model {\n            id: \"unique-id-002\".to_owned(),\n            owner: \"GC\".to_owned(),\n            name: \"G.C.\".to_owned(),\n            description: None,\n        }\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/text_uuid_tests.rs",
    "content": "pub mod common;\nuse common::{TestContext, features::*, setup::*};\nuse sea_orm::{DatabaseConnection, IntoActiveModel, NotSet, Set, entity::prelude::*};\nuse uuid::Uuid;\n\nmod sample {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sample\")]\n    pub struct Model {\n        #[sea_orm(primary_key, auto_increment = false)]\n        pub id: TextUuid,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[sea_orm_macros::test]\nfn text_uuid_test() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"text_uuid_test\");\n    let db = &ctx.db;\n\n    let uuid = Uuid::new_v4();\n\n    db.get_schema_builder().register(sample::Entity).apply(db)?;\n\n    let entry = sample::ActiveModel {\n        id: Set(uuid.into()),\n    }\n    .insert(db)?;\n\n    assert_eq!(*entry.id, uuid);\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/time_crate_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, IntoActiveModel, entity::prelude::*};\nuse serde_json::json;\nuse time::macros::{date, time};\n\n#[sea_orm_macros::test]\nfn main() {\n    let ctx = TestContext::new(\"time_crate_tests\");\n    create_transaction_log_table(&ctx.db).unwrap();\n    create_transaction_log(&ctx.db).unwrap();\n\n    ctx.delete();\n}\n\npub fn create_transaction_log(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let transaction_log = transaction_log::Model {\n        id: 1,\n        date: date!(2022 - 03 - 13),\n        time: time!(16:24:00),\n        date_time: date!(2022 - 03 - 13).with_time(time!(16:24:00)),\n        date_time_tz: date!(2022 - 03 - 13)\n            .with_time(time!(16:24:00))\n            .assume_utc(),\n    };\n\n    let res = TransactionLog::insert(transaction_log.clone().into_active_model()).exec(db)?;\n\n    assert_eq!(transaction_log.id, res.last_insert_id);\n    assert_eq!(\n        TransactionLog::find().one(db)?,\n        Some(transaction_log.clone())\n    );\n\n    let json = TransactionLog::find().into_json().one(db)?.unwrap();\n\n    #[cfg(feature = \"sqlx-postgres\")]\n    assert_eq!(\n        json,\n        json!({\n            \"id\": 1,\n            \"date\": \"2022-03-13\",\n            \"time\": \"16:24:00\",\n            \"date_time\": \"2022-03-13T16:24:00\",\n            \"date_time_tz\": \"2022-03-13T16:24:00Z\",\n        })\n    );\n\n    #[cfg(feature = \"sqlx-mysql\")]\n    assert_eq!(\n        json,\n        json!({\n            \"id\": 1,\n            \"date\": \"2022-03-13\",\n            \"time\": \"16:24:00\",\n            \"date_time\": \"2022-03-13T16:24:00\",\n            \"date_time_tz\": \"2022-03-13T16:24:00Z\",\n        })\n    );\n\n    #[cfg(all(not(feature = \"sync\"), feature = \"sqlx-sqlite\"))]\n    assert_eq!(\n        json,\n        json!({\n            \"id\": 1,\n            \"date\": \"2022-03-13\",\n            \"time\": \"16:24:00.0\",\n            \"date_time\": \"2022-03-13 16:24:00.0\",\n            \"date_time_tz\": \"2022-03-13T16:24:00Z\",\n        })\n    );\n\n    #[cfg(feature = \"rusqlite\")]\n    assert_eq!(\n        json,\n        json!({\n            \"id\": 1,\n            \"date\": \"2022-03-13\",\n            \"time\": \"16:24:00.0\",\n            \"date_time\": \"2022-03-13 16:24:00.0\",\n            \"date_time_tz\": \"2022-03-13 16:24:00.0+00:00\",\n        })\n    );\n\n    assert_ne!(json, \"\");\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/timestamp_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, IntoActiveModel, NotSet, Set, entity::prelude::*};\n\n#[sea_orm_macros::test]\nfn bakery_chain_schema_timestamp_tests() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"bakery_chain_schema_timestamp_tests\");\n    create_log_table(&ctx.db)?;\n    create_satellites_table(&ctx.db)?;\n    create_applog(&ctx.db)?;\n    create_satellites_log(&ctx.db)?;\n\n    ctx.delete();\n\n    Ok(())\n}\n\nmod access_log {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"access_log\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub ts: ChronoUnixTimestamp,\n        pub ms: ChronoUnixTimestampMillis,\n        pub tts: TimeUnixTimestamp,\n        pub tms: TimeUnixTimestampMillis,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[sea_orm_macros::test]\nfn entity_timestamp_test() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"entity_timestamp_test\");\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(access_log::Entity)\n        .apply(db)?;\n\n    let now = sea_orm::prelude::ChronoUtc::now();\n    let time_now = sea_orm::prelude::TimeDateTimeWithTimeZone::from_unix_timestamp_nanos(\n        now.timestamp_nanos_opt().unwrap() as i128,\n    )\n    .unwrap();\n\n    let log = access_log::ActiveModel {\n        id: NotSet,\n        ts: Set(now.into()),\n        ms: Set(ChronoUnixTimestampMillis(now)),\n        tts: Set(TimeUnixTimestamp(time_now)),\n        tms: Set(time_now.into()),\n    }\n    .insert(db)?;\n\n    assert_eq!(log.ts.timestamp(), now.timestamp());\n    assert_eq!(log.ms.timestamp_millis(), now.timestamp_millis());\n\n    assert_eq!(log.tts.unix_timestamp(), now.timestamp());\n    assert_eq!(\n        log.tms.unix_timestamp_nanos() / 1_000_000,\n        now.timestamp_millis() as i128\n    );\n\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"access_log::Entity\")]\n    struct AccessLog {\n        ts: i64,\n        ms: i64,\n        tts: i64,\n        tms: i64,\n    }\n\n    let log: AccessLog = access_log::Entity::find()\n        .into_partial_model()\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(log.ts, now.timestamp());\n    assert_eq!(log.ms, now.timestamp_millis());\n    assert_eq!(log.tts, now.timestamp());\n    assert_eq!(log.tms, now.timestamp_millis());\n\n    Ok(())\n}\n\npub fn create_applog(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let log = applog::Model {\n        id: 1,\n        action: \"Testing\".to_owned(),\n        json: Json::String(\"HI\".to_owned()),\n        created_at: \"2021-09-17T17:50:20+08:00\".parse().unwrap(),\n    };\n\n    let res = Applog::insert(log.clone().into_active_model()).exec(db)?;\n\n    assert_eq!(log.id, res.last_insert_id);\n    assert_eq!(Applog::find().one(db)?, Some(log.clone()));\n\n    #[cfg(all(not(feature = \"sync\"), feature = \"sqlx-sqlite\"))]\n    assert_eq!(\n        Applog::find().into_json().one(db)?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"action\": \"Testing\",\n            \"json\": r#\"\"HI\"\"#,\n            \"created_at\": \"2021-09-17T17:50:20+08:00\",\n        }))\n    );\n    #[cfg(feature = \"rusqlite\")]\n    assert_eq!(\n        Applog::find().into_json().one(db)?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"action\": \"Testing\",\n            \"json\": r#\"\"HI\"\"#,\n            \"created_at\": \"2021-09-17 17:50:20+08:00\",\n        }))\n    );\n    #[cfg(feature = \"sqlx-mysql\")]\n    assert_eq!(\n        Applog::find().into_json().one(db)?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"action\": \"Testing\",\n            \"json\": \"HI\",\n            \"created_at\": \"2021-09-17T09:50:20Z\",\n        }))\n    );\n    #[cfg(feature = \"sqlx-postgres\")]\n    assert_eq!(\n        Applog::find().into_json().one(db)?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"action\": \"Testing\",\n            \"json\": \"HI\",\n            \"created_at\": \"2021-09-17T09:50:20Z\",\n        }))\n    );\n\n    Ok(())\n}\n\npub fn create_satellites_log(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let archive = satellite::Model {\n        id: 1,\n        satellite_name: \"Sea-00001-2022\".to_owned(),\n        launch_date: \"2022-01-07T12:11:23Z\".parse().unwrap(),\n        deployment_date: \"2022-01-07T12:11:23Z\".parse().unwrap(),\n    };\n\n    let res = Satellite::insert(archive.clone().into_active_model()).exec(db)?;\n\n    assert_eq!(archive.id, res.last_insert_id);\n    assert_eq!(Satellite::find().one(db)?, Some(archive.clone()));\n\n    #[cfg(all(not(feature = \"sync\"), feature = \"sqlx-sqlite\"))]\n    assert_eq!(\n        Satellite::find().into_json().one(db)?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"satellite_name\": \"Sea-00001-2022\",\n            \"launch_date\": \"2022-01-07T12:11:23+00:00\",\n            \"deployment_date\": \"2022-01-07T12:11:23Z\".parse::<DateTimeLocal>().unwrap().to_rfc3339(),\n        }))\n    );\n    #[cfg(feature = \"rusqlite\")]\n    assert_eq!(\n        Satellite::find().into_json().one(db)?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"satellite_name\": \"Sea-00001-2022\",\n            \"launch_date\": \"2022-01-07 12:11:23+00:00\",\n            \"deployment_date\": \"2022-01-07 12:11:23+00:00\"\n        }))\n    );\n    #[cfg(feature = \"sqlx-mysql\")]\n    assert_eq!(\n        Satellite::find().into_json().one(db)?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"satellite_name\": \"Sea-00001-2022\",\n            \"launch_date\": \"2022-01-07T12:11:23Z\",\n            \"deployment_date\": \"2022-01-07T12:11:23Z\",\n        }))\n    );\n    #[cfg(feature = \"sqlx-postgres\")]\n    assert_eq!(\n        Satellite::find().into_json().one(db)?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"satellite_name\": \"Sea-00001-2022\",\n            \"launch_date\": \"2022-01-07T12:11:23Z\",\n            \"deployment_date\": \"2022-01-07T12:11:23Z\",\n        }))\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/transaction_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{\n    AccessMode, DatabaseTransaction, IsolationLevel, Set, SqliteTransactionMode,\n    TransactionOptions, TransactionTrait, prelude::*,\n};\n\n#[cfg(not(feature = \"sync\"))]\ntype FutureResult<'a> =\n    std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), DbErr>> + Send + 'a>>;\n#[cfg(feature = \"sync\")]\ntype FutureResult<'a> = Result<(), DbErr>;\n\nfn seaside_bakery() -> bakery::ActiveModel {\n    bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n}\n\nfn top_bakery() -> bakery::ActiveModel {\n    bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n}\n\n#[sea_orm_macros::test]\npub fn transaction() {\n    let ctx = TestContext::new(\"transaction_test\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    ctx.db\n        .transaction::<_, _, DbErr>(|txn| {\n            ({\n                let _ = seaside_bakery().save(txn)?;\n                let _ = top_bakery().save(txn)?;\n\n                let bakeries = Bakery::find()\n                    .filter(bakery::Column::Name.contains(\"Bakery\"))\n                    .all(txn)?;\n\n                assert_eq!(bakeries.len(), 2);\n\n                Ok(())\n            })\n        })\n        .unwrap();\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"rbac\")]\npub fn rbac_transaction() {\n    use sea_orm::rbac::{RbacEngine, RbacSnapshot, RbacUserId};\n\n    let ctx = TestContext::new(\"rbac_transaction_test\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    ctx.db.replace_rbac(RbacEngine::from_snapshot(\n        RbacSnapshot::danger_unrestricted(),\n    ));\n    let db = ctx.db.restricted_for(RbacUserId(0)).unwrap();\n\n    db.transaction::<_, _, DbErr>(|txn| {\n        ({\n            let _ = seaside_bakery().save(txn)?;\n            let _ = top_bakery().save(txn)?;\n\n            let bakeries = Bakery::find()\n                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                .all(txn)?;\n\n            assert_eq!(bakeries.len(), 2);\n\n            Ok(())\n        })\n    })\n    .unwrap();\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn transaction_with_reference() {\n    let ctx = TestContext::new(\"transaction_with_reference_test\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let name1 = \"SeaSide Bakery\";\n    let name2 = \"Top Bakery\";\n    let search_name = \"Bakery\";\n    ctx.db\n        .transaction(|txn| _transaction_with_reference(txn, name1, name2, search_name))\n        .unwrap();\n\n    ctx.delete();\n}\n\nfn _transaction_with_reference<'a>(\n    txn: &'a DatabaseTransaction,\n    name1: &'a str,\n    name2: &'a str,\n    search_name: &'a str,\n) -> FutureResult<'a> {\n    ({\n        let _ = bakery::ActiveModel {\n            name: Set(name1.to_owned()),\n            profit_margin: Set(10.4),\n            ..Default::default()\n        }\n        .save(txn)?;\n\n        let _ = bakery::ActiveModel {\n            name: Set(name2.to_owned()),\n            profit_margin: Set(15.0),\n            ..Default::default()\n        }\n        .save(txn)?;\n\n        let bakeries = Bakery::find()\n            .filter(bakery::Column::Name.contains(search_name))\n            .all(txn)?;\n\n        assert_eq!(bakeries.len(), 2);\n\n        Ok(())\n    })\n}\n\n#[sea_orm_macros::test]\npub fn transaction_begin_out_of_scope() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_begin_out_of_scope_test\");\n    create_bakery_table(&ctx.db)?;\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db)?.len(), 0);\n\n    {\n        // Transaction begin in this scope\n        let txn = ctx.db.begin()?;\n\n        seaside_bakery().save(&txn)?;\n\n        assert_eq!(bakery::Entity::find().all(&txn)?.len(), 1);\n\n        top_bakery().save(&txn)?;\n\n        assert_eq!(bakery::Entity::find().all(&txn)?.len(), 2);\n\n        // The scope ended and transaction is dropped without commit\n    }\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db)?.len(), 0);\n\n    ctx.delete();\n    Ok(())\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"rbac\")]\npub fn rbac_transaction_begin_out_of_scope() -> Result<(), DbErr> {\n    use sea_orm::rbac::{RbacEngine, RbacSnapshot, RbacUserId};\n\n    let ctx = TestContext::new(\"rbac_transaction_begin_out_of_scope_test\");\n    create_bakery_table(&ctx.db)?;\n\n    ctx.db.replace_rbac(RbacEngine::from_snapshot(\n        RbacSnapshot::danger_unrestricted(),\n    ));\n    let db = ctx.db.restricted_for(RbacUserId(0)).unwrap();\n\n    assert_eq!(bakery::Entity::find().all(&db)?.len(), 0);\n\n    {\n        // Transaction begin in this scope\n        let txn = db.begin()?;\n\n        seaside_bakery().save(&txn)?;\n\n        assert_eq!(bakery::Entity::find().all(&txn)?.len(), 1);\n\n        top_bakery().save(&txn)?;\n\n        assert_eq!(bakery::Entity::find().all(&txn)?.len(), 2);\n\n        // The scope ended and transaction is dropped without commit\n    }\n\n    assert_eq!(bakery::Entity::find().all(&db)?.len(), 0);\n\n    ctx.delete();\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub fn transaction_begin_commit() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_begin_commit_test\");\n    create_bakery_table(&ctx.db)?;\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db)?.len(), 0);\n\n    {\n        // Transaction begin in this scope\n        let txn = ctx.db.begin()?;\n\n        seaside_bakery().save(&txn)?;\n\n        assert_eq!(bakery::Entity::find().all(&txn)?.len(), 1);\n\n        top_bakery().save(&txn)?;\n\n        assert_eq!(bakery::Entity::find().all(&txn)?.len(), 2);\n\n        // Commit changes before the end of scope\n        txn.commit()?;\n    }\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db)?.len(), 2);\n\n    ctx.delete();\n    Ok(())\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"rbac\")]\npub fn rbac_transaction_begin_commit() -> Result<(), DbErr> {\n    use sea_orm::rbac::{RbacEngine, RbacSnapshot, RbacUserId};\n\n    let ctx = TestContext::new(\"rbac_transaction_begin_commit_test\");\n    create_bakery_table(&ctx.db)?;\n\n    ctx.db.replace_rbac(RbacEngine::from_snapshot(\n        RbacSnapshot::danger_unrestricted(),\n    ));\n    let db = ctx.db.restricted_for(RbacUserId(0)).unwrap();\n\n    assert_eq!(bakery::Entity::find().all(&db)?.len(), 0);\n\n    {\n        // Transaction begin in this scope\n        let txn = db.begin()?;\n\n        seaside_bakery().save(&txn)?;\n\n        assert_eq!(bakery::Entity::find().all(&txn)?.len(), 1);\n\n        top_bakery().save(&txn)?;\n\n        assert_eq!(bakery::Entity::find().all(&txn)?.len(), 2);\n\n        // Commit changes before the end of scope\n        txn.commit()?;\n    }\n\n    assert_eq!(bakery::Entity::find().all(&db)?.len(), 2);\n\n    ctx.delete();\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub fn transaction_begin_rollback() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_begin_rollback_test\");\n    create_bakery_table(&ctx.db)?;\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db)?.len(), 0);\n\n    {\n        // Transaction begin in this scope\n        let txn = ctx.db.begin()?;\n\n        seaside_bakery().save(&txn)?;\n\n        assert_eq!(bakery::Entity::find().all(&txn)?.len(), 1);\n\n        top_bakery().save(&txn)?;\n\n        assert_eq!(bakery::Entity::find().all(&txn)?.len(), 2);\n\n        // Rollback changes before the end of scope\n        txn.rollback()?;\n    }\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db)?.len(), 0);\n\n    ctx.delete();\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub fn transaction_closure_commit() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_closure_commit_test\");\n    create_bakery_table(&ctx.db)?;\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db)?.len(), 0);\n\n    let res = ctx.db.transaction::<_, _, DbErr>(|txn| {\n        ({\n            seaside_bakery().save(txn)?;\n\n            assert_eq!(bakery::Entity::find().all(txn)?.len(), 1);\n\n            top_bakery().save(txn)?;\n\n            assert_eq!(bakery::Entity::find().all(txn)?.len(), 2);\n\n            Ok(())\n        })\n    });\n\n    assert!(res.is_ok());\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db)?.len(), 2);\n\n    ctx.delete();\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub fn transaction_closure_rollback() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_closure_rollback_test\");\n    create_bakery_table(&ctx.db)?;\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db)?.len(), 0);\n\n    let res = ctx.db.transaction::<_, _, DbErr>(|txn| {\n        ({\n            seaside_bakery().save(txn)?;\n\n            assert_eq!(bakery::Entity::find().all(txn)?.len(), 1);\n\n            top_bakery().save(txn)?;\n\n            assert_eq!(bakery::Entity::find().all(txn)?.len(), 2);\n\n            bakery::ActiveModel {\n                id: Set(1),\n                name: Set(\"Duplicated primary key\".to_owned()),\n                profit_margin: Set(20.0),\n            }\n            .insert(txn)?; // Throw error and rollback\n\n            // This line won't be reached\n            unreachable!();\n\n            #[allow(unreachable_code)]\n            Ok(())\n        })\n    });\n\n    assert!(res.is_err());\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db)?.len(), 0);\n\n    ctx.delete();\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub fn transaction_with_active_model_behaviour() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_with_active_model_behaviour_test\");\n    create_bakery_table(&ctx.db)?;\n    create_cake_table(&ctx.db)?;\n\n    if let Ok(txn) = ctx.db.begin() {\n        assert_eq!(\n            cake::ActiveModel {\n                name: Set(\"Cake with invalid price\".to_owned()),\n                price: Set(rust_dec(0)),\n                gluten_free: Set(false),\n                ..Default::default()\n            }\n            .save(&txn),\n            Err(DbErr::Custom(\n                \"[before_save] Invalid Price, insert: true\".to_owned()\n            ))\n        );\n\n        assert_eq!(cake::Entity::find().all(&txn)?.len(), 0);\n\n        assert_eq!(\n            cake::ActiveModel {\n                name: Set(\"Cake with invalid price\".to_owned()),\n                price: Set(rust_dec(-10)),\n                gluten_free: Set(false),\n                ..Default::default()\n            }\n            .save(&txn),\n            Err(DbErr::Custom(\n                \"[after_save] Invalid Price, insert: true\".to_owned()\n            ))\n        );\n\n        assert_eq!(cake::Entity::find().all(&txn)?.len(), 1);\n\n        let readonly_cake_1 = cake::ActiveModel {\n            name: Set(\"Readonly cake (err_on_before_delete)\".to_owned()),\n            price: Set(rust_dec(10)),\n            gluten_free: Set(true),\n            ..Default::default()\n        }\n        .save(&txn)?;\n\n        assert_eq!(cake::Entity::find().all(&txn)?.len(), 2);\n\n        assert_eq!(\n            readonly_cake_1.delete(&txn).err(),\n            Some(DbErr::Custom(\n                \"[before_delete] Cannot be deleted\".to_owned()\n            ))\n        );\n\n        assert_eq!(cake::Entity::find().all(&txn)?.len(), 2);\n\n        let readonly_cake_2 = cake::ActiveModel {\n            name: Set(\"Readonly cake (err_on_after_delete)\".to_owned()),\n            price: Set(rust_dec(10)),\n            gluten_free: Set(true),\n            ..Default::default()\n        }\n        .save(&txn)?;\n\n        assert_eq!(cake::Entity::find().all(&txn)?.len(), 3);\n\n        assert_eq!(\n            readonly_cake_2.delete(&txn).err(),\n            Some(DbErr::Custom(\"[after_delete] Cannot be deleted\".to_owned()))\n        );\n\n        assert_eq!(cake::Entity::find().all(&txn)?.len(), 2);\n    }\n\n    assert_eq!(cake::Entity::find().all(&ctx.db)?.len(), 0);\n\n    ctx.delete();\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub fn transaction_nested() {\n    let ctx = TestContext::new(\"transaction_nested_test\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    ctx.db\n        .transaction::<_, _, DbErr>(|txn| {\n            ({\n                let _ = seaside_bakery().save(txn)?;\n\n                let _ = top_bakery().save(txn)?;\n\n                // Try nested transaction committed\n                txn.transaction::<_, _, DbErr>(|txn| {\n                    ({\n                        let _ = bakery::ActiveModel {\n                            name: Set(\"Nested Bakery\".to_owned()),\n                            profit_margin: Set(88.88),\n                            ..Default::default()\n                        }\n                        .save(txn)?;\n\n                        let bakeries = Bakery::find()\n                            .filter(bakery::Column::Name.contains(\"Bakery\"))\n                            .all(txn)?;\n\n                        assert_eq!(bakeries.len(), 3);\n\n                        // Try nested-nested transaction rollbacked\n                        let is_err = txn\n                            .transaction::<_, _, DbErr>(|txn| {\n                                ({\n                                    let _ = bakery::ActiveModel {\n                                        name: Set(\"Rock n Roll Bakery\".to_owned()),\n                                        profit_margin: Set(28.8),\n                                        ..Default::default()\n                                    }\n                                    .save(txn)?;\n\n                                    let bakeries = Bakery::find()\n                                        .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                        .all(txn)?;\n\n                                    assert_eq!(bakeries.len(), 4);\n\n                                    if true {\n                                        Err(DbErr::Query(RuntimeErr::Internal(\n                                            \"Force Rollback!\".to_owned(),\n                                        )))\n                                    } else {\n                                        Ok(())\n                                    }\n                                })\n                            })\n                            .is_err();\n\n                        assert!(is_err);\n\n                        let bakeries = Bakery::find()\n                            .filter(bakery::Column::Name.contains(\"Bakery\"))\n                            .all(txn)?;\n\n                        assert_eq!(bakeries.len(), 3);\n\n                        // Try nested-nested transaction committed\n                        txn.transaction::<_, _, DbErr>(|txn| {\n                            ({\n                                let _ = bakery::ActiveModel {\n                                    name: Set(\"Rock n Roll Bakery\".to_owned()),\n                                    profit_margin: Set(28.8),\n                                    ..Default::default()\n                                }\n                                .save(txn)?;\n\n                                let bakeries = Bakery::find()\n                                    .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                    .all(txn)?;\n\n                                assert_eq!(bakeries.len(), 4);\n\n                                Ok(())\n                            })\n                        })\n                        .unwrap();\n\n                        let bakeries = Bakery::find()\n                            .filter(bakery::Column::Name.contains(\"Bakery\"))\n                            .all(txn)?;\n\n                        assert_eq!(bakeries.len(), 4);\n\n                        Ok(())\n                    })\n                })\n                .unwrap();\n\n                // Try nested transaction rollbacked\n                let is_err = txn\n                    .transaction::<_, _, DbErr>(|txn| {\n                        ({\n                            let _ = bakery::ActiveModel {\n                                name: Set(\"Rock n Roll Bakery\".to_owned()),\n                                profit_margin: Set(28.8),\n                                ..Default::default()\n                            }\n                            .save(txn)?;\n\n                            let bakeries = Bakery::find()\n                                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                .all(txn)?;\n\n                            assert_eq!(bakeries.len(), 5);\n\n                            // Try nested-nested transaction committed\n                            txn.transaction::<_, _, DbErr>(|txn| {\n                                ({\n                                    let _ = bakery::ActiveModel {\n                                        name: Set(\"Rock n Roll Bakery\".to_owned()),\n                                        profit_margin: Set(28.8),\n                                        ..Default::default()\n                                    }\n                                    .save(txn)?;\n\n                                    let bakeries = Bakery::find()\n                                        .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                        .all(txn)?;\n\n                                    assert_eq!(bakeries.len(), 6);\n\n                                    Ok(())\n                                })\n                            })\n                            .unwrap();\n\n                            let bakeries = Bakery::find()\n                                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                .all(txn)?;\n\n                            assert_eq!(bakeries.len(), 6);\n\n                            // Try nested-nested transaction rollbacked\n                            let is_err = txn\n                                .transaction::<_, _, DbErr>(|txn| {\n                                    ({\n                                        let _ = bakery::ActiveModel {\n                                            name: Set(\"Rock n Roll Bakery\".to_owned()),\n                                            profit_margin: Set(28.8),\n                                            ..Default::default()\n                                        }\n                                        .save(txn)?;\n\n                                        let bakeries = Bakery::find()\n                                            .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                            .all(txn)?;\n\n                                        assert_eq!(bakeries.len(), 7);\n\n                                        if true {\n                                            Err(DbErr::Query(RuntimeErr::Internal(\n                                                \"Force Rollback!\".to_owned(),\n                                            )))\n                                        } else {\n                                            Ok(())\n                                        }\n                                    })\n                                })\n                                .is_err();\n\n                            assert!(is_err);\n\n                            let bakeries = Bakery::find()\n                                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                .all(txn)?;\n\n                            assert_eq!(bakeries.len(), 6);\n\n                            if true {\n                                Err(DbErr::Query(RuntimeErr::Internal(\n                                    \"Force Rollback!\".to_owned(),\n                                )))\n                            } else {\n                                Ok(())\n                            }\n                        })\n                    })\n                    .is_err();\n\n                assert!(is_err);\n\n                let bakeries = Bakery::find()\n                    .filter(bakery::Column::Name.contains(\"Bakery\"))\n                    .all(txn)?;\n\n                assert_eq!(bakeries.len(), 4);\n\n                Ok(())\n            })\n        })\n        .unwrap();\n\n    let bakeries = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Bakery\"))\n        .all(&ctx.db)\n        .unwrap();\n\n    assert_eq!(bakeries.len(), 4);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn transaction_manager_nested() -> Result<(), sea_orm::DbErr> {\n    let ctx = TestContext::new(\"transaction_manager_nested\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    let txn = ctx.db.begin()?;\n    let _ = seaside_bakery().save(&txn)?;\n    let _ = top_bakery().save(&txn)?;\n\n    // Try nested transaction committed\n    {\n        let txn = txn.begin()?;\n        let _ = bakery::ActiveModel {\n            name: Set(\"Nested Bakery\".to_owned()),\n            profit_margin: Set(88.88),\n            ..Default::default()\n        }\n        .save(&txn)?;\n\n        let bakeries = Bakery::find()\n            .filter(bakery::Column::Name.contains(\"Bakery\"))\n            .all(&txn)?;\n\n        assert_eq!(bakeries.len(), 3);\n\n        // Try nested-nested transaction rollbacked\n        {\n            let txn = txn.begin()?;\n            let _ = bakery::ActiveModel {\n                name: Set(\"Rock n Roll Bakery\".to_owned()),\n                profit_margin: Set(28.8),\n                ..Default::default()\n            }\n            .save(&txn)?;\n\n            let bakeries = Bakery::find()\n                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                .all(&txn)?;\n\n            assert_eq!(bakeries.len(), 4);\n        }\n\n        let bakeries = Bakery::find()\n            .filter(bakery::Column::Name.contains(\"Bakery\"))\n            .all(&txn)?;\n\n        assert_eq!(bakeries.len(), 3);\n\n        // Try nested-nested transaction committed\n        {\n            let txn = txn.begin()?;\n            let _ = bakery::ActiveModel {\n                name: Set(\"Rock n Roll Bakery\".to_owned()),\n                profit_margin: Set(28.8),\n                ..Default::default()\n            }\n            .save(&txn)?;\n\n            let bakeries = Bakery::find()\n                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                .all(&txn)?;\n\n            assert_eq!(bakeries.len(), 4);\n            txn.commit()?;\n        }\n\n        txn.commit()?;\n    }\n\n    // Try nested transaction rollbacked\n    {\n        let txn = txn.begin()?;\n        let _ = bakery::ActiveModel {\n            name: Set(\"Rock n Roll Bakery\".to_owned()),\n            profit_margin: Set(28.8),\n            ..Default::default()\n        }\n        .save(&txn)?;\n\n        let bakeries = Bakery::find()\n            .filter(bakery::Column::Name.contains(\"Bakery\"))\n            .all(&txn)?;\n\n        assert_eq!(bakeries.len(), 5);\n\n        // Try nested-nested transaction committed\n        {\n            let txn = txn.begin()?;\n            let _ = bakery::ActiveModel {\n                name: Set(\"Rock n Roll Bakery\".to_owned()),\n                profit_margin: Set(28.8),\n                ..Default::default()\n            }\n            .save(&txn)?;\n\n            let bakeries = Bakery::find()\n                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                .all(&txn)?;\n\n            assert_eq!(bakeries.len(), 6);\n            txn.commit()?;\n        }\n\n        let bakeries = Bakery::find()\n            .filter(bakery::Column::Name.contains(\"Bakery\"))\n            .all(&txn)?;\n\n        assert_eq!(bakeries.len(), 6);\n    }\n\n    let bakeries = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Bakery\"))\n        .all(&txn)?;\n\n    assert_eq!(bakeries.len(), 4);\n\n    txn.commit()?;\n\n    let bakeries = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Bakery\"))\n        .all(&ctx.db)\n        .unwrap();\n\n    assert_eq!(bakeries.len(), 4);\n\n    ctx.delete();\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"rbac\")]\npub fn rbac_transaction_nested() {\n    use sea_orm::rbac::{RbacEngine, RbacSnapshot, RbacUserId};\n\n    let ctx = TestContext::new(\"rbac_transaction_nested_test\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    ctx.db.replace_rbac(RbacEngine::from_snapshot(\n        RbacSnapshot::danger_unrestricted(),\n    ));\n    let db = ctx.db.restricted_for(RbacUserId(0)).unwrap();\n\n    db.transaction::<_, _, DbErr>(|txn| {\n        ({\n            let _ = seaside_bakery().save(txn)?;\n\n            let _ = top_bakery().save(txn)?;\n\n            // Try nested transaction committed\n            txn.transaction::<_, _, DbErr>(|txn| {\n                ({\n                    let _ = bakery::ActiveModel {\n                        name: Set(\"Nested Bakery\".to_owned()),\n                        profit_margin: Set(88.88),\n                        ..Default::default()\n                    }\n                    .save(txn)?;\n\n                    let bakeries = Bakery::find()\n                        .filter(bakery::Column::Name.contains(\"Bakery\"))\n                        .all(txn)?;\n\n                    assert_eq!(bakeries.len(), 3);\n\n                    // Try nested-nested transaction committed\n                    txn.transaction::<_, _, DbErr>(|txn| {\n                        ({\n                            let _ = bakery::ActiveModel {\n                                name: Set(\"Rock n Roll Bakery\".to_owned()),\n                                profit_margin: Set(28.8),\n                                ..Default::default()\n                            }\n                            .save(txn)?;\n\n                            let bakeries = Bakery::find()\n                                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                .all(txn)?;\n\n                            assert_eq!(bakeries.len(), 4);\n\n                            Ok(())\n                        })\n                    })\n                    .unwrap();\n\n                    let bakeries = Bakery::find()\n                        .filter(bakery::Column::Name.contains(\"Bakery\"))\n                        .all(txn)?;\n\n                    assert_eq!(bakeries.len(), 4);\n\n                    Ok(())\n                })\n            })\n            .unwrap();\n\n            let bakeries = Bakery::find()\n                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                .all(txn)?;\n\n            assert_eq!(bakeries.len(), 4);\n\n            Ok(())\n        })\n    })\n    .unwrap();\n\n    let bakeries = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Bakery\"))\n        .all(&ctx.db)\n        .unwrap();\n\n    assert_eq!(bakeries.len(), 4);\n\n    ctx.delete();\n}\n\n#[sea_orm_macros::test]\npub fn transaction_with_config() {\n    let ctx = TestContext::new(\"transaction_with_config\");\n    create_bakery_table(&ctx.db).unwrap();\n\n    for (i, (isolation_level, access_mode)) in [\n        (IsolationLevel::RepeatableRead, None),\n        (IsolationLevel::ReadCommitted, None),\n        (IsolationLevel::ReadUncommitted, Some(AccessMode::ReadWrite)),\n        (IsolationLevel::Serializable, Some(AccessMode::ReadWrite)),\n    ]\n    .into_iter()\n    .enumerate()\n    {\n        let name1 = format!(\"SeaSide Bakery {}\", i);\n        let name2 = format!(\"Top Bakery {}\", i);\n        let search_name = format!(\"Bakery {}\", i);\n        ctx.db\n            .transaction_with_config(\n                |txn| _transaction_with_config(txn, name1, name2, search_name),\n                Some(isolation_level),\n                access_mode,\n            )\n            .unwrap();\n    }\n\n    ctx.db\n        .transaction_with_config::<_, _, DbErr>(\n            |txn| {\n                ({\n                    let bakeries = Bakery::find()\n                        .filter(bakery::Column::Name.contains(\"Bakery\"))\n                        .all(txn)?;\n\n                    assert_eq!(bakeries.len(), 8);\n\n                    Ok(())\n                })\n            },\n            None,\n            Some(AccessMode::ReadOnly),\n        )\n        .unwrap();\n\n    ctx.delete();\n}\n\nfn _transaction_with_config<'a>(\n    txn: &'a DatabaseTransaction,\n    name1: String,\n    name2: String,\n    search_name: String,\n) -> FutureResult<'a> {\n    ({\n        let _ = bakery::ActiveModel {\n            name: Set(name1),\n            profit_margin: Set(10.4),\n            ..Default::default()\n        }\n        .save(txn)?;\n\n        let _ = bakery::ActiveModel {\n            name: Set(name2),\n            profit_margin: Set(15.0),\n            ..Default::default()\n        }\n        .save(txn)?;\n\n        let bakeries = Bakery::find()\n            .filter(bakery::Column::Name.contains(&search_name))\n            .all(txn)?;\n\n        assert_eq!(bakeries.len(), 2);\n\n        Ok(())\n    })\n}\n\n#[sea_orm_macros::test]\npub fn transaction_begin_with_options() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_begin_with_options_test\");\n    create_tables(&ctx.db)?;\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db)?.len(), 0);\n\n    {\n        // Transaction begin in this scope\n        let txn = ctx.db.begin_with_options(TransactionOptions {\n            sqlite_transaction_mode: Some(SqliteTransactionMode::Immediate),\n            ..Default::default()\n        })?;\n\n        seaside_bakery().save(&txn)?;\n\n        assert_eq!(bakery::Entity::find().all(&txn)?.len(), 1);\n\n        top_bakery().save(&txn)?;\n\n        assert_eq!(bakery::Entity::find().all(&txn)?.len(), 2);\n\n        // Commit changes before the end of scope\n        txn.commit()?;\n    }\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db)?.len(), 2);\n\n    ctx.delete();\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/type_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse sea_orm::{IntoActiveValue, TryFromU64, TryGetable, Value};\n\n/*\n\nWhen supporting a new type in SeaORM we should implement the following traits for it:\n  - `IntoActiveValue`, given that it implemented `Into<Value>` already\n  - `TryGetable`\n  - `TryFromU64`\n\nAlso, we need to update `impl FromQueryResult for JsonValue` at `src/query/json.rs`\nto correctly serialize the type as `serde_json::Value`.\n\n*/\n\npub fn it_impl_into_active_value<T: IntoActiveValue<V>, V: Into<Value>>() {}\n\npub fn it_impl_try_getable<T: TryGetable>() {}\n\npub fn it_impl_try_from_u64<T: TryFromU64>() {}\n\n#[allow(unused_macros)]\nmacro_rules! it_impl_traits {\n    ( $ty: ty ) => {\n        it_impl_into_active_value::<$ty, $ty>();\n        it_impl_into_active_value::<Option<$ty>, $ty>();\n        it_impl_into_active_value::<Option<Option<$ty>>, Option<$ty>>();\n\n        it_impl_try_getable::<$ty>();\n        it_impl_try_getable::<Option<$ty>>();\n\n        it_impl_try_from_u64::<$ty>();\n    };\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-dep\")]\nfn main() {\n    it_impl_traits!(i8);\n    it_impl_traits!(i16);\n    it_impl_traits!(i32);\n    it_impl_traits!(i64);\n    it_impl_traits!(u8);\n    it_impl_traits!(u16);\n    it_impl_traits!(u32);\n    it_impl_traits!(u64);\n    it_impl_traits!(bool);\n    it_impl_traits!(f32);\n    it_impl_traits!(f64);\n    it_impl_traits!(Vec<u8>);\n    it_impl_traits!(String);\n    it_impl_traits!(serde_json::Value);\n    it_impl_traits!(chrono::NaiveDate);\n    it_impl_traits!(chrono::NaiveTime);\n    it_impl_traits!(chrono::NaiveDateTime);\n    it_impl_traits!(chrono::DateTime<chrono::FixedOffset>);\n    it_impl_traits!(chrono::DateTime<chrono::Utc>);\n    it_impl_traits!(chrono::DateTime<chrono::Local>);\n    it_impl_traits!(time::Date);\n    it_impl_traits!(time::Time);\n    it_impl_traits!(time::PrimitiveDateTime);\n    it_impl_traits!(time::OffsetDateTime);\n    it_impl_traits!(rust_decimal::Decimal);\n    it_impl_traits!(uuid::Uuid);\n    #[cfg(feature = \"with-ipnetwork\")]\n    it_impl_traits!(ipnetwork::IpNetwork);\n    it_impl_traits!(common::features::value_type::MyUserId);\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/upsert_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::TryInsertResult;\nuse sea_orm::entity::prelude::*;\nuse sea_orm::{Set, sea_query::OnConflict};\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"upsert_tests\");\n    create_insert_default_table(&ctx.db)?;\n    create_insert_default(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    let res = Entity::insert_many::<ActiveModel, _>([]).exec(db);\n\n    assert_eq!(res?.last_insert_id, None);\n\n    let res =\n        Entity::insert_many([ActiveModel { id: Set(1) }, ActiveModel { id: Set(2) }]).exec(db);\n\n    assert_eq!(res?.last_insert_id, Some(2));\n\n    let on_conflict = OnConflict::column(Column::Id)\n        .do_nothing_on([Column::Id])\n        .to_owned();\n\n    let res = Entity::insert_many([\n        ActiveModel { id: Set(1) },\n        ActiveModel { id: Set(2) },\n        ActiveModel { id: Set(3) },\n    ])\n    .on_conflict(on_conflict.clone())\n    .exec(db);\n\n    assert_eq!(res?.last_insert_id, Some(3));\n\n    let res = Entity::insert_many([\n        ActiveModel { id: Set(1) },\n        ActiveModel { id: Set(2) },\n        ActiveModel { id: Set(3) },\n        ActiveModel { id: Set(4) },\n    ])\n    .on_conflict(on_conflict.clone())\n    .exec(db);\n\n    assert_eq!(res?.last_insert_id, Some(4));\n\n    let res =\n        Entity::insert_many([ActiveModel { id: Set(3) }, ActiveModel { id: Set(4) }]).exec(db);\n\n    assert!(matches!(res, Err(DbErr::Query(_) | DbErr::Exec(_))));\n\n    let res = Entity::insert_many([ActiveModel { id: Set(3) }, ActiveModel { id: Set(4) }])\n        .on_conflict(on_conflict.clone())\n        .exec(db);\n\n    assert!(matches!(res, Err(DbErr::RecordNotInserted)));\n\n    let res = Entity::insert_many([ActiveModel { id: Set(3) }, ActiveModel { id: Set(4) }])\n        .on_conflict_do_nothing_on([Column::Id])\n        .exec(db);\n\n    assert!(matches!(res, Ok(TryInsertResult::Conflicted)));\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/uuid_fmt_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, FromQueryResult, entity::prelude::*, entity::*};\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"uuid_fmt_tests\");\n    create_uuid_fmt_table(&ctx.db)?;\n    insert_uuid_fmt(&ctx.db)?;\n    test_text_uuid(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn insert_uuid_fmt(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let uuid = Uuid::new_v4();\n\n    let uuid_fmt = uuid_fmt::Model {\n        id: 1,\n        uuid,\n        uuid_braced: uuid.braced(),\n        uuid_hyphenated: uuid.hyphenated(),\n        uuid_simple: uuid.simple(),\n        uuid_urn: uuid.urn(),\n    };\n\n    let result = uuid_fmt.clone().into_active_model().insert(db)?;\n\n    assert_eq!(result, uuid_fmt);\n\n    Ok(())\n}\n\nmod uuid_fmt_more {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"uuid_fmt_more\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub iden: TextUuid,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub fn test_text_uuid(db: &DatabaseConnection) -> Result<(), DbErr> {\n    // ensure that column is typed\n    let _iden: sea_orm::TextUuidColumn<uuid_fmt_more::Entity> = uuid_fmt_more::COLUMN.iden;\n\n    db.get_schema_builder()\n        .register(uuid_fmt_more::Entity)\n        .apply(db)?;\n\n    #[derive(FromQueryResult)]\n    struct UuidFmtMore {\n        id: i32,\n        iden: String, // no casting needed\n    }\n\n    let uuid = Uuid::new_v4();\n    let model = uuid_fmt_more::ActiveModel {\n        iden: Set(uuid.into()),\n        ..Default::default()\n    };\n\n    let result = model.insert(db)?;\n    assert_eq!(result.iden.0, uuid);\n\n    let result: UuidFmtMore = uuid_fmt_more::Entity::find_by_id(result.id)\n        .into_model()\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(result.iden, uuid.to_string());\n\n    uuid_fmt_more::ActiveModel {\n        iden: Set(Uuid::new_v4().into()),\n        ..Default::default()\n    }\n    .insert(db)?;\n\n    let result = uuid_fmt_more::Entity::find_by_iden(uuid).one(db)?.unwrap();\n\n    assert_eq!(result.iden.0, uuid);\n\n    let result = uuid_fmt_more::Entity::find()\n        .filter(uuid_fmt_more::COLUMN.iden.eq(uuid))\n        .one(db)?\n        .unwrap();\n\n    assert_eq!(result.iden.0, uuid);\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/uuid_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\nuse serde_json::json;\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"bakery_chain_uuid_tests\");\n    create_metadata_table(&ctx.db)?;\n    create_and_update_metadata(&ctx.db)?;\n    insert_metadata(&ctx.db)?;\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn insert_metadata(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let metadata = metadata::Model {\n        uuid: Uuid::new_v4(),\n        ty: \"Type\".to_owned(),\n        key: \"markup\".to_owned(),\n        value: \"1.18\".to_owned(),\n        bytes: vec![1, 2, 3],\n        date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()),\n        time: Some(Time::from_hms_opt(11, 32, 55).unwrap()),\n    };\n\n    let result = metadata.clone().into_active_model().insert(db)?;\n\n    assert_eq!(result, metadata);\n\n    let mut json = metadata::Entity::find()\n        .filter(metadata::Column::Uuid.eq(metadata.uuid))\n        .into_json()\n        .one(db)?;\n\n    #[cfg(feature = \"rusqlite\")]\n    {\n        json.as_mut()\n            .unwrap()\n            .as_object_mut()\n            .unwrap()\n            .remove(\"uuid\");\n        // rusqlite current has no rich type info to properly deserialize a uuid\n        assert_eq!(\n            json,\n            Some(json!({\n                \"type\": metadata.ty,\n                \"key\": metadata.key,\n                \"value\": metadata.value,\n                \"bytes\": metadata.bytes,\n                \"date\": metadata.date,\n                \"time\": metadata.time,\n            }))\n        );\n    }\n    #[cfg(not(feature = \"rusqlite\"))]\n    {\n        assert_eq!(\n            json,\n            Some(json!({\n                \"uuid\": metadata.uuid,\n                \"type\": metadata.ty,\n                \"key\": metadata.key,\n                \"value\": metadata.value,\n                \"bytes\": metadata.bytes,\n                \"date\": metadata.date,\n                \"time\": metadata.time,\n            }))\n        );\n    }\n\n    Ok(())\n}\n\npub fn create_and_update_metadata(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let metadata = metadata::Model {\n        uuid: Uuid::new_v4(),\n        ty: \"Type\".to_owned(),\n        key: \"markup\".to_owned(),\n        value: \"1.18\".to_owned(),\n        bytes: vec![1, 2, 3],\n        date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()),\n        time: Some(Time::from_hms_opt(11, 32, 55).unwrap()),\n    };\n\n    let res = Metadata::insert(metadata.clone().into_active_model()).exec(db)?;\n\n    assert_eq!(Metadata::find().one(db)?, Some(metadata.clone()));\n\n    assert_eq!(res.last_insert_id, metadata.uuid);\n\n    let update_res = Metadata::update(metadata::ActiveModel {\n        value: Set(\"0.22\".to_owned()),\n        ..metadata.clone().into_active_model()\n    })\n    .validate()?\n    .filter(metadata::Column::Uuid.eq(Uuid::default()))\n    .exec(db);\n\n    assert_eq!(update_res, Err(DbErr::RecordNotUpdated));\n\n    Ok(())\n}\n"
  },
  {
    "path": "sea-orm-sync/tests/value_type_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse std::sync::Arc;\nuse std::vec;\n\npub use common::{\n    TestContext,\n    features::{\n        value_type::{\n            MyInteger, StringVec, Tag1, Tag2, Tag3, Tag4, Tag5, value_type_general, value_type_pg,\n            value_type_pk,\n        },\n        *,\n    },\n    setup::*,\n};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{\n    DatabaseConnection, DbBackend, QuerySelect,\n    entity::{prelude::*, *},\n};\nuse sea_query::{ArrayType, ColumnType, PostgresQueryBuilder, Value, ValueType, ValueTypeErr};\n\n#[sea_orm_macros::test]\nfn main() -> Result<(), DbErr> {\n    type_test();\n    conversion_test();\n\n    let ctx = TestContext::new(\"value_type_tests\");\n\n    create_value_type_table(&ctx.db)?;\n    insert_value_general(&ctx.db)?;\n    insert_value_pk(&ctx.db)?;\n\n    if cfg!(feature = \"sqlx-postgres\") {\n        create_value_type_postgres_table(&ctx.db)?;\n        insert_value_postgres(&ctx.db)?;\n    }\n\n    ctx.delete();\n\n    Ok(())\n}\n\npub fn insert_value_general(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let model = value_type_general::Model {\n        id: 1,\n        number: 48.into(),\n        tag_1: Tag1::Hard,\n        tag_2: Tag2::Grey,\n    };\n    let result = model.clone().into_active_model().insert(db)?;\n    assert_eq!(result, model);\n\n    Ok(())\n}\n\npub fn insert_value_pk(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let model = value_type_pk::Model {\n        id: MyInteger(1),\n        val: MyInteger(2),\n    };\n    let result = model.clone().into_active_model().insert(db)?;\n    assert_eq!(result, model);\n\n    let mut model = result.into_active_model();\n    model.val = Set(MyInteger(3));\n    model.save(db)?;\n    assert_eq!(\n        value_type_pk::Entity::find_by_id(MyInteger(1))\n            .one(db)?\n            .unwrap()\n            .val,\n        MyInteger(3)\n    );\n\n    Ok(())\n}\n\npub fn insert_value_postgres(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let model = value_type_pg::Model {\n        id: 1,\n        number: 48.into(),\n        str_vec: StringVec(vec![\"ab\".to_string(), \"cd\".to_string()]),\n    };\n    let result = model.clone().into_active_model().insert(db)?;\n    assert_eq!(result, model);\n\n    let query = sea_query::Query::select()\n        .from(value_type_pg::Entity)\n        .column((value_type_pg::Entity, value_type_pg::Column::Number))\n        .and_where(value_type_pg::Column::Id.eq(1))\n        .take();\n\n    let row = db.query_one(&query)?.unwrap();\n    let value: u32 = row.try_get(\"\", \"number\").unwrap();\n    assert_eq!(value, 48u32);\n\n    Ok(())\n}\n\npub fn type_test() {\n    assert_eq!(MyInteger::type_name(), \"MyInteger\");\n    assert_eq!(StringVec::type_name(), \"StringVec\");\n\n    assert_eq!(MyInteger::column_type(), ColumnType::Integer);\n    assert_eq!(MyInteger::array_type(), ArrayType::Int);\n\n    assert!(matches!(Tag1::column_type(), ColumnType::String(_)));\n    assert_eq!(Tag1::array_type(), ArrayType::String);\n\n    assert!(matches!(Tag3::column_type(), ColumnType::String(_)));\n    assert_eq!(Tag3::array_type(), ArrayType::String);\n\n    assert!(matches!(Tag4::column_type(), ColumnType::String(_)));\n    assert_eq!(Tag4::array_type(), ArrayType::String);\n\n    assert!(matches!(Tag5::column_type(), ColumnType::String(_)));\n    assert_eq!(Tag5::array_type(), ArrayType::String);\n\n    let tag_3 = Tag3 { i: 22 };\n    let tag_3_val: Value = tag_3.into();\n    assert_eq!(tag_3_val, \"22\".into());\n    let tag_3_: Tag3 = ValueType::try_from(tag_3_val).unwrap();\n    assert_eq!(tag_3_, tag_3);\n\n    let tag_4 = Tag4(22);\n    let tag_4_val: Value = tag_4.into();\n    assert_eq!(tag_4_val, \"22\".into());\n    let tag_4_: Tag4 = ValueType::try_from(tag_4_val).unwrap();\n    assert_eq!(tag_4_, tag_4);\n\n    let tag_5 = Tag5(std::path::PathBuf::from(\"foo/bar\"));\n    let tag_5_val: Value = tag_5.clone().into();\n    assert_eq!(tag_5_val, \"foo/bar\".into());\n    let tag_5_: Tag5 = ValueType::try_from(tag_5_val).unwrap();\n    assert_eq!(tag_5_, tag_5);\n\n    assert_eq!(\n        StringVec::column_type(),\n        ColumnType::Array(Arc::new(ColumnType::String(StringLen::None)))\n    );\n    assert_eq!(StringVec::array_type(), ArrayType::String);\n}\n\npub fn conversion_test() {\n    let stringvec = StringVec(vec![\"ab\".to_string(), \"cd\".to_string()]);\n    let string: Value = stringvec.into();\n    let expected: Value = vec![\"ab\".to_string(), \"cd\".to_string()].into();\n    assert_eq!(string, expected);\n\n    let value_random_int = Value::Int(Some(523));\n    let unwrap_int = MyInteger::unwrap(value_random_int.clone());\n    let try_from_int =\n        <MyInteger as ValueType>::try_from(value_random_int).expect(\"should be ok to convert\");\n\n    // tests for unwrap and try_from\n    let direct_int: MyInteger = 523.into();\n    assert_eq!(direct_int, unwrap_int);\n    assert_eq!(direct_int, try_from_int);\n\n    // test for error\n    let try_from_string_vec = <StringVec as ValueType>::try_from(Value::Char(Some('a')))\n        .expect_err(\"should not be ok to convert char to stringvec\");\n    assert_eq!(try_from_string_vec.to_string(), ValueTypeErr.to_string());\n}\n"
  },
  {
    "path": "src/database/connection.rs",
    "content": "use std::{future::Future, pin::Pin};\n\nuse futures_util::Stream;\n\nuse crate::{\n    DbBackend, DbErr, ExecResult, QueryResult, Statement, StatementBuilder, TransactionError,\n};\n\n/// The generic API for a database connection that can perform query or execute statements.\n/// It abstracts database connection and transaction\n#[async_trait::async_trait]\npub trait ConnectionTrait: Sync {\n    /// Get the database backend for the connection. This depends on feature flags enabled.\n    fn get_database_backend(&self) -> DbBackend;\n\n    /// Execute a [Statement]\n    async fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr>;\n\n    /// Execute a [QueryStatement]\n    async fn execute<S: StatementBuilder>(&self, stmt: &S) -> Result<ExecResult, DbErr> {\n        let db_backend = self.get_database_backend();\n        let stmt = db_backend.build(stmt);\n        self.execute_raw(stmt).await\n    }\n\n    /// Execute a unprepared [Statement]\n    async fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr>;\n\n    /// Execute a [Statement] and return a single row of `QueryResult`\n    async fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr>;\n\n    /// Execute a [QueryStatement] and return a single row of `QueryResult`\n    async fn query_one<S: StatementBuilder>(&self, stmt: &S) -> Result<Option<QueryResult>, DbErr> {\n        let db_backend = self.get_database_backend();\n        let stmt = db_backend.build(stmt);\n        self.query_one_raw(stmt).await\n    }\n\n    /// Execute a [Statement] and return a vector of `QueryResult`\n    async fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr>;\n\n    /// Execute a [QueryStatement] and return a vector of `QueryResult`\n    async fn query_all<S: StatementBuilder>(&self, stmt: &S) -> Result<Vec<QueryResult>, DbErr> {\n        let db_backend = self.get_database_backend();\n        let stmt = db_backend.build(stmt);\n        self.query_all_raw(stmt).await\n    }\n\n    /// Check if the connection supports `RETURNING` syntax on insert and update\n    fn support_returning(&self) -> bool {\n        let db_backend = self.get_database_backend();\n        db_backend.support_returning()\n    }\n\n    /// Check if the connection is a test connection for the Mock database\n    fn is_mock_connection(&self) -> bool {\n        false\n    }\n}\n\n/// Stream query results\npub trait StreamTrait: Send + Sync {\n    /// Create a stream for the [QueryResult]\n    type Stream<'a>: Stream<Item = Result<QueryResult, DbErr>> + Send\n    where\n        Self: 'a;\n\n    /// Get the database backend for the connection. This depends on feature flags enabled.\n    fn get_database_backend(&self) -> DbBackend;\n\n    /// Execute a [Statement] and return a stream of results\n    fn stream_raw<'a>(\n        &'a self,\n        stmt: Statement,\n    ) -> Pin<Box<dyn Future<Output = Result<Self::Stream<'a>, DbErr>> + 'a + Send>>;\n\n    /// Execute a [QueryStatement] and return a stream of results\n    fn stream<'a, S: StatementBuilder + Sync>(\n        &'a self,\n        stmt: &S,\n    ) -> Pin<Box<dyn Future<Output = Result<Self::Stream<'a>, DbErr>> + 'a + Send>> {\n        let db_backend = self.get_database_backend();\n        let stmt = db_backend.build(stmt);\n        self.stream_raw(stmt)\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\n/// Isolation level\npub enum IsolationLevel {\n    /// Consistent reads within the same transaction read the snapshot established by the first read.\n    RepeatableRead,\n    /// Each consistent read, even within the same transaction, sets and reads its own fresh snapshot.\n    ReadCommitted,\n    /// SELECT statements are performed in a nonlocking fashion, but a possible earlier version of a row might be used.\n    ReadUncommitted,\n    /// All statements of the current transaction can only see rows committed before the first query or data-modification statement was executed in this transaction.\n    Serializable,\n}\n\nimpl std::fmt::Display for IsolationLevel {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            IsolationLevel::RepeatableRead => write!(f, \"REPEATABLE READ\"),\n            IsolationLevel::ReadCommitted => write!(f, \"READ COMMITTED\"),\n            IsolationLevel::ReadUncommitted => write!(f, \"READ UNCOMMITTED\"),\n            IsolationLevel::Serializable => write!(f, \"SERIALIZABLE\"),\n        }\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\n/// Access mode\npub enum AccessMode {\n    /// Data can't be modified in this transaction\n    ReadOnly,\n    /// Data can be modified in this transaction (default)\n    ReadWrite,\n}\n\nimpl std::fmt::Display for AccessMode {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            AccessMode::ReadOnly => write!(f, \"READ ONLY\"),\n            AccessMode::ReadWrite => write!(f, \"READ WRITE\"),\n        }\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq)]\n/// Which kind of transaction to start. Only supported by SQLite.\n/// <https://www.sqlite.org/lang_transaction.html>\npub enum SqliteTransactionMode {\n    /// The default. Transaction starts when the next statement is executed, and\n    /// will be a read or write transaction depending on that statement.\n    Deferred,\n    /// Start a write transaction as soon as the BEGIN statement is received.\n    Immediate,\n    /// Start a write transaction as soon as the BEGIN statement is received.\n    /// When in non-WAL mode, also block all other transactions from reading the\n    /// database.\n    Exclusive,\n}\n\nimpl SqliteTransactionMode {\n    /// The keyword used to start a transaction in this mode (the word coming after \"BEGIN\").\n    pub fn sqlite_keyword(&self) -> &'static str {\n        match self {\n            SqliteTransactionMode::Deferred => \"DEFERRED\",\n            SqliteTransactionMode::Immediate => \"IMMEDIATE\",\n            SqliteTransactionMode::Exclusive => \"EXCLUSIVE\",\n        }\n    }\n}\n\n/// Configuration for starting a transaction\n#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]\npub struct TransactionOptions {\n    /// Isolation level for the new transaction\n    pub isolation_level: Option<IsolationLevel>,\n    /// Access mode for the new transaction\n    pub access_mode: Option<AccessMode>,\n    /// Transaction mode (deferred, immediate, exclusive) for the new transaction. Supported only by SQLite.\n    pub sqlite_transaction_mode: Option<SqliteTransactionMode>,\n}\n\n/// Spawn database transaction\n#[async_trait::async_trait]\npub trait TransactionTrait {\n    /// The concrete type for the transaction\n    type Transaction: ConnectionTrait + TransactionTrait + TransactionSession;\n\n    /// Execute SQL `BEGIN` transaction.\n    /// Returns a Transaction that can be committed or rolled back\n    async fn begin(&self) -> Result<Self::Transaction, DbErr>;\n\n    /// Execute SQL `BEGIN` transaction with isolation level and/or access mode.\n    /// Returns a Transaction that can be committed or rolled back\n    async fn begin_with_config(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<Self::Transaction, DbErr>;\n\n    /// Execute SQL `BEGIN` transaction with isolation level and/or access mode.\n    /// Returns a Transaction that can be committed or rolled back\n    async fn begin_with_options(\n        &self,\n        options: TransactionOptions,\n    ) -> Result<Self::Transaction, DbErr>;\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    async fn transaction<F, T, E>(&self, callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(\n                &'c Self::Transaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send;\n\n    /// Execute the function inside a transaction with isolation level and/or access mode.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    async fn transaction_with_config<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(\n                &'c Self::Transaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send;\n}\n\n/// Represents an open transaction\n#[async_trait::async_trait]\npub trait TransactionSession {\n    /// Commit a transaction\n    async fn commit(self) -> Result<(), DbErr>;\n\n    /// Rolls back a transaction explicitly\n    async fn rollback(self) -> Result<(), DbErr>;\n}\n"
  },
  {
    "path": "src/database/db_connection.rs",
    "content": "use crate::{\n    AccessMode, ConnectionTrait, DatabaseTransaction, ExecResult, IsolationLevel, QueryResult,\n    Schema, SchemaBuilder, Statement, StatementBuilder, StreamTrait, TransactionError,\n    TransactionOptions, TransactionTrait, error::*,\n};\nuse std::{fmt::Debug, future::Future, pin::Pin};\nuse tracing::instrument;\nuse url::Url;\n\n#[cfg(feature = \"sqlx-dep\")]\nuse sqlx::pool::PoolConnection;\n\n#[cfg(feature = \"rusqlite\")]\nuse crate::driver::rusqlite::{RusqliteInnerConnection, RusqliteSharedConnection};\n\n#[cfg(any(feature = \"mock\", feature = \"proxy\"))]\nuse std::sync::Arc;\n\n/// Handle a database connection depending on the backend enabled by the feature\n/// flags. This creates a connection pool internally (for SQLx connections),\n/// and so is cheap to clone.\n#[derive(Debug, Clone)]\n#[non_exhaustive]\npub struct DatabaseConnection {\n    /// `DatabaseConnection` used to be a enum. Now it's moved into inner,\n    /// because we have to attach other contexts.\n    pub inner: DatabaseConnectionType,\n    #[cfg(feature = \"rbac\")]\n    pub(crate) rbac: crate::RbacEngineMount,\n}\n\n/// The underlying database connection type.\n#[derive(Clone)]\npub enum DatabaseConnectionType {\n    /// MySql database connection pool\n    #[cfg(feature = \"sqlx-mysql\")]\n    SqlxMySqlPoolConnection(crate::SqlxMySqlPoolConnection),\n\n    /// PostgreSQL database connection pool\n    #[cfg(feature = \"sqlx-postgres\")]\n    SqlxPostgresPoolConnection(crate::SqlxPostgresPoolConnection),\n\n    /// SQLite database connection pool\n    #[cfg(feature = \"sqlx-sqlite\")]\n    SqlxSqlitePoolConnection(crate::SqlxSqlitePoolConnection),\n\n    /// SQLite database connection sharable across threads\n    #[cfg(feature = \"rusqlite\")]\n    RusqliteSharedConnection(RusqliteSharedConnection),\n\n    /// Mock database connection useful for testing\n    #[cfg(feature = \"mock\")]\n    MockDatabaseConnection(Arc<crate::MockDatabaseConnection>),\n\n    /// Proxy database connection\n    #[cfg(feature = \"proxy\")]\n    ProxyDatabaseConnection(Arc<crate::ProxyDatabaseConnection>),\n\n    /// The connection has never been established\n    Disconnected,\n}\n\n/// The same as a [DatabaseConnection]\npub type DbConn = DatabaseConnection;\n\nimpl Default for DatabaseConnection {\n    fn default() -> Self {\n        DatabaseConnectionType::Disconnected.into()\n    }\n}\n\nimpl From<DatabaseConnectionType> for DatabaseConnection {\n    fn from(inner: DatabaseConnectionType) -> Self {\n        Self {\n            inner,\n            #[cfg(feature = \"rbac\")]\n            rbac: Default::default(),\n        }\n    }\n}\n\n/// The type of database backend for real world databases.\n/// This is enabled by feature flags as specified in the crate documentation\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\n#[non_exhaustive]\npub enum DatabaseBackend {\n    /// A MySQL backend\n    MySql,\n    /// A PostgreSQL backend\n    Postgres,\n    /// A SQLite backend\n    Sqlite,\n}\n\n/// A shorthand for [DatabaseBackend].\npub type DbBackend = DatabaseBackend;\n\n#[derive(Debug)]\npub(crate) enum InnerConnection {\n    #[cfg(feature = \"sqlx-mysql\")]\n    MySql(PoolConnection<sqlx::MySql>),\n    #[cfg(feature = \"sqlx-postgres\")]\n    Postgres(PoolConnection<sqlx::Postgres>),\n    #[cfg(feature = \"sqlx-sqlite\")]\n    Sqlite(PoolConnection<sqlx::Sqlite>),\n    #[cfg(feature = \"rusqlite\")]\n    Rusqlite(RusqliteInnerConnection),\n    #[cfg(feature = \"mock\")]\n    Mock(Arc<crate::MockDatabaseConnection>),\n    #[cfg(feature = \"proxy\")]\n    Proxy(Arc<crate::ProxyDatabaseConnection>),\n}\n\nimpl Debug for DatabaseConnectionType {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(\n            f,\n            \"{}\",\n            match self {\n                #[cfg(feature = \"sqlx-mysql\")]\n                Self::SqlxMySqlPoolConnection(_) => \"SqlxMySqlPoolConnection\",\n                #[cfg(feature = \"sqlx-postgres\")]\n                Self::SqlxPostgresPoolConnection(_) => \"SqlxPostgresPoolConnection\",\n                #[cfg(feature = \"sqlx-sqlite\")]\n                Self::SqlxSqlitePoolConnection(_) => \"SqlxSqlitePoolConnection\",\n                #[cfg(feature = \"rusqlite\")]\n                Self::RusqliteSharedConnection(_) => \"RusqliteSharedConnection\",\n                #[cfg(feature = \"mock\")]\n                Self::MockDatabaseConnection(_) => \"MockDatabaseConnection\",\n                #[cfg(feature = \"proxy\")]\n                Self::ProxyDatabaseConnection(_) => \"ProxyDatabaseConnection\",\n                Self::Disconnected => \"Disconnected\",\n            }\n        )\n    }\n}\n\n#[async_trait::async_trait]\nimpl ConnectionTrait for DatabaseConnection {\n    fn get_database_backend(&self) -> DbBackend {\n        self.get_database_backend()\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    async fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.execute\",\n            self.get_database_backend(),\n            stmt.sql.as_str(),\n            record_stmt = true,\n            async {\n                match &self.inner {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                        conn.execute(stmt).await\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                        conn.execute(stmt).await\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                        conn.execute(stmt).await\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.execute(stmt),\n                    #[cfg(feature = \"mock\")]\n                    DatabaseConnectionType::MockDatabaseConnection(conn) => conn.execute(stmt),\n                    #[cfg(feature = \"proxy\")]\n                    DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                        conn.execute(stmt).await\n                    }\n                    DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    async fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.execute_unprepared\",\n            self.get_database_backend(),\n            sql,\n            record_stmt = false,\n            async {\n                match &self.inner {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                        conn.execute_unprepared(sql).await\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                        conn.execute_unprepared(sql).await\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                        conn.execute_unprepared(sql).await\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    DatabaseConnectionType::RusqliteSharedConnection(conn) => {\n                        conn.execute_unprepared(sql)\n                    }\n                    #[cfg(feature = \"mock\")]\n                    DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                        let db_backend = conn.get_database_backend();\n                        let stmt = Statement::from_string(db_backend, sql);\n                        conn.execute(stmt)\n                    }\n                    #[cfg(feature = \"proxy\")]\n                    DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                        let db_backend = conn.get_database_backend();\n                        let stmt = Statement::from_string(db_backend, sql);\n                        conn.execute(stmt).await\n                    }\n                    DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    async fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.query_one\",\n            self.get_database_backend(),\n            stmt.sql.as_str(),\n            record_stmt = true,\n            async {\n                match &self.inner {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                        conn.query_one(stmt).await\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                        conn.query_one(stmt).await\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                        conn.query_one(stmt).await\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.query_one(stmt),\n                    #[cfg(feature = \"mock\")]\n                    DatabaseConnectionType::MockDatabaseConnection(conn) => conn.query_one(stmt),\n                    #[cfg(feature = \"proxy\")]\n                    DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                        conn.query_one(stmt).await\n                    }\n                    DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    async fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.query_all\",\n            self.get_database_backend(),\n            stmt.sql.as_str(),\n            record_stmt = true,\n            async {\n                match &self.inner {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                        conn.query_all(stmt).await\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                        conn.query_all(stmt).await\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                        conn.query_all(stmt).await\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.query_all(stmt),\n                    #[cfg(feature = \"mock\")]\n                    DatabaseConnectionType::MockDatabaseConnection(conn) => conn.query_all(stmt),\n                    #[cfg(feature = \"proxy\")]\n                    DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                        conn.query_all(stmt).await\n                    }\n                    DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[cfg(feature = \"mock\")]\n    fn is_mock_connection(&self) -> bool {\n        matches!(\n            self,\n            DatabaseConnection {\n                inner: DatabaseConnectionType::MockDatabaseConnection(_),\n                ..\n            }\n        )\n    }\n}\n\n#[async_trait::async_trait]\nimpl StreamTrait for DatabaseConnection {\n    type Stream<'a> = crate::QueryStream;\n\n    fn get_database_backend(&self) -> DbBackend {\n        self.get_database_backend()\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    fn stream_raw<'a>(\n        &'a self,\n        stmt: Statement,\n    ) -> Pin<Box<dyn Future<Output = Result<Self::Stream<'a>, DbErr>> + 'a + Send>> {\n        Box::pin(async move {\n            match &self.inner {\n                #[cfg(feature = \"sqlx-mysql\")]\n                DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => conn.stream(stmt).await,\n                #[cfg(feature = \"sqlx-postgres\")]\n                DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => conn.stream(stmt).await,\n                #[cfg(feature = \"sqlx-sqlite\")]\n                DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => conn.stream(stmt).await,\n                #[cfg(feature = \"rusqlite\")]\n                DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.stream(stmt),\n                #[cfg(feature = \"mock\")]\n                DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                    Ok(crate::QueryStream::from((Arc::clone(conn), stmt, None)))\n                }\n                #[cfg(feature = \"proxy\")]\n                DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                    Ok(crate::QueryStream::from((Arc::clone(conn), stmt, None)))\n                }\n                DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n            }\n        })\n    }\n}\n\n#[async_trait::async_trait]\nimpl TransactionTrait for DatabaseConnection {\n    type Transaction = DatabaseTransaction;\n\n    #[instrument(level = \"trace\")]\n    async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => conn.begin(None, None).await,\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                conn.begin(None, None).await\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                conn.begin(None, None, None).await\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.begin(None, None, None),\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                DatabaseTransaction::new_mock(Arc::clone(conn), None).await\n            }\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                DatabaseTransaction::new_proxy(conn.clone(), None).await\n            }\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n        }\n    }\n\n    #[instrument(level = \"trace\")]\n    async fn begin_with_config(\n        &self,\n        _isolation_level: Option<IsolationLevel>,\n        _access_mode: Option<AccessMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode).await\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode).await\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode, None).await\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode, None)\n            }\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                DatabaseTransaction::new_mock(Arc::clone(conn), None).await\n            }\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                DatabaseTransaction::new_proxy(conn.clone(), None).await\n            }\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n        }\n    }\n\n    #[instrument(level = \"trace\")]\n    async fn begin_with_options(\n        &self,\n        TransactionOptions {\n            isolation_level: _isolation_level,\n            access_mode: _access_mode,\n            sqlite_transaction_mode: _sqlite_transaction_mode,\n        }: TransactionOptions,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode).await\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode).await\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode, _sqlite_transaction_mode)\n                    .await\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => {\n                conn.begin(_isolation_level, _access_mode, _sqlite_transaction_mode)\n            }\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                DatabaseTransaction::new_mock(Arc::clone(conn), None).await\n            }\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                DatabaseTransaction::new_proxy(conn.clone(), None).await\n            }\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n        }\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(_callback))]\n    async fn transaction<F, T, E>(&self, _callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(\n                &'c DatabaseTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                conn.transaction(_callback, None, None).await\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                conn.transaction(_callback, None, None).await\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                conn.transaction(_callback, None, None).await\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => {\n                conn.transaction(_callback, None, None)\n            }\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                let transaction = DatabaseTransaction::new_mock(Arc::clone(conn), None)\n                    .await\n                    .map_err(TransactionError::Connection)?;\n                transaction.run(_callback).await\n            }\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                let transaction = DatabaseTransaction::new_proxy(conn.clone(), None)\n                    .await\n                    .map_err(TransactionError::Connection)?;\n                transaction.run(_callback).await\n            }\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\").into()),\n        }\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(_callback))]\n    async fn transaction_with_config<F, T, E>(\n        &self,\n        _callback: F,\n        _isolation_level: Option<IsolationLevel>,\n        _access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(\n                &'c DatabaseTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                conn.transaction(_callback, _isolation_level, _access_mode)\n                    .await\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                conn.transaction(_callback, _isolation_level, _access_mode)\n                    .await\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                conn.transaction(_callback, _isolation_level, _access_mode)\n                    .await\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => {\n                conn.transaction(_callback, _isolation_level, _access_mode)\n            }\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => {\n                let transaction = DatabaseTransaction::new_mock(Arc::clone(conn), None)\n                    .await\n                    .map_err(TransactionError::Connection)?;\n                transaction.run(_callback).await\n            }\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => {\n                let transaction = DatabaseTransaction::new_proxy(conn.clone(), None)\n                    .await\n                    .map_err(TransactionError::Connection)?;\n                transaction.run(_callback).await\n            }\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\").into()),\n        }\n    }\n}\n\n#[cfg(feature = \"mock\")]\nimpl DatabaseConnection {\n    /// Generate a database connection for testing the Mock database\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DbConn] is not a mock connection.\n    pub fn as_mock_connection(&self) -> &crate::MockDatabaseConnection {\n        match &self.inner {\n            DatabaseConnectionType::MockDatabaseConnection(mock_conn) => mock_conn,\n            _ => panic!(\"Not mock connection\"),\n        }\n    }\n\n    /// Get the transaction log as a collection Vec<[crate::Transaction]>\n    ///\n    /// # Panics\n    ///\n    /// Panics if the mocker mutex is being held by another thread.\n    pub fn into_transaction_log(self) -> Vec<crate::Transaction> {\n        let mut mocker = self\n            .as_mock_connection()\n            .get_mocker_mutex()\n            .lock()\n            .expect(\"Fail to acquire mocker\");\n        mocker.drain_transaction_log()\n    }\n}\n\n#[cfg(feature = \"proxy\")]\nimpl DatabaseConnection {\n    /// Generate a database connection for testing the Proxy database\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DbConn] is not a proxy connection.\n    pub fn as_proxy_connection(&self) -> &crate::ProxyDatabaseConnection {\n        match &self.inner {\n            DatabaseConnectionType::ProxyDatabaseConnection(proxy_conn) => proxy_conn,\n            _ => panic!(\"Not proxy connection\"),\n        }\n    }\n}\n\n#[cfg(feature = \"rbac\")]\nimpl DatabaseConnection {\n    /// Load RBAC data from the same database as this connection and setup RBAC engine.\n    /// If the RBAC engine already exists, it will be replaced.\n    pub async fn load_rbac(&self) -> Result<(), DbErr> {\n        self.load_rbac_from(self).await\n    }\n\n    /// Load RBAC data from the given database connection and setup RBAC engine.\n    /// This could be from another database.\n    pub async fn load_rbac_from(&self, db: &DbConn) -> Result<(), DbErr> {\n        let engine = crate::rbac::RbacEngine::load_from(db).await?;\n        self.rbac.replace(engine);\n        Ok(())\n    }\n\n    /// Replace the internal RBAC engine.\n    pub fn replace_rbac(&self, engine: crate::rbac::RbacEngine) {\n        self.rbac.replace(engine);\n    }\n\n    /// Create a restricted connection with access control specific for the user.\n    pub fn restricted_for(\n        &self,\n        user_id: crate::rbac::RbacUserId,\n    ) -> Result<crate::RestrictedConnection, DbErr> {\n        if self.rbac.is_some() {\n            Ok(crate::RestrictedConnection {\n                user_id,\n                conn: self.clone(),\n            })\n        } else {\n            Err(DbErr::RbacError(\"engine not set up\".into()))\n        }\n    }\n}\n\nimpl DatabaseConnection {\n    /// Get the database backend for this connection\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DatabaseConnection] is `Disconnected`.\n    pub fn get_database_backend(&self) -> DbBackend {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(_) => DbBackend::MySql,\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(_) => DbBackend::Postgres,\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(_) => DbBackend::Sqlite,\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(_) => DbBackend::Sqlite,\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => conn.get_database_backend(),\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => conn.get_database_backend(),\n            DatabaseConnectionType::Disconnected => panic!(\"Disconnected\"),\n        }\n    }\n\n    /// Creates a [`SchemaBuilder`] for this backend\n    pub fn get_schema_builder(&self) -> SchemaBuilder {\n        Schema::new(self.get_database_backend()).builder()\n    }\n\n    #[cfg(feature = \"entity-registry\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"entity-registry\")))]\n    /// Builds a schema for all the entites in the given module\n    pub fn get_schema_registry(&self, prefix: &str) -> SchemaBuilder {\n        let schema = Schema::new(self.get_database_backend());\n        crate::EntityRegistry::build_schema(schema, prefix)\n    }\n\n    /// Sets a callback to metric this connection\n    pub fn set_metric_callback<F>(&mut self, _callback: F)\n    where\n        F: Fn(&crate::metric::Info<'_>) + Send + Sync + 'static,\n    {\n        match &mut self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => {\n                conn.set_metric_callback(_callback)\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => {\n                conn.set_metric_callback(_callback)\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => {\n                conn.set_metric_callback(_callback)\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => {\n                conn.set_metric_callback(_callback)\n            }\n            _ => {}\n        }\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub async fn ping(&self) -> Result<(), DbErr> {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => conn.ping().await,\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => conn.ping().await,\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => conn.ping().await,\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.ping(),\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(conn) => conn.ping(),\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(conn) => conn.ping().await,\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n        }\n    }\n\n    /// Explicitly close the database connection.\n    /// See [`Self::close_by_ref`] for usage with references.\n    pub async fn close(self) -> Result<(), DbErr> {\n        self.close_by_ref().await\n    }\n\n    /// Explicitly close the database connection\n    pub async fn close_by_ref(&self) -> Result<(), DbErr> {\n        match &self.inner {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => conn.close_by_ref().await,\n            #[cfg(feature = \"sqlx-postgres\")]\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => conn.close_by_ref().await,\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => conn.close_by_ref().await,\n            #[cfg(feature = \"rusqlite\")]\n            DatabaseConnectionType::RusqliteSharedConnection(conn) => conn.close_by_ref(),\n            #[cfg(feature = \"mock\")]\n            DatabaseConnectionType::MockDatabaseConnection(_) => {\n                // Nothing to cleanup, we just consume the `DatabaseConnection`\n                Ok(())\n            }\n            #[cfg(feature = \"proxy\")]\n            DatabaseConnectionType::ProxyDatabaseConnection(_) => {\n                // Nothing to cleanup, we just consume the `DatabaseConnection`\n                Ok(())\n            }\n            DatabaseConnectionType::Disconnected => Err(conn_err(\"Disconnected\")),\n        }\n    }\n}\n\nimpl DatabaseConnection {\n    /// Get [sqlx::MySqlPool]\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DbConn] is not a MySQL connection.\n    #[cfg(feature = \"sqlx-mysql\")]\n    pub fn get_mysql_connection_pool(&self) -> &sqlx::MySqlPool {\n        match &self.inner {\n            DatabaseConnectionType::SqlxMySqlPoolConnection(conn) => &conn.pool,\n            _ => panic!(\"Not MySQL Connection\"),\n        }\n    }\n\n    /// Get [sqlx::PgPool]\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DbConn] is not a Postgres connection.\n    #[cfg(feature = \"sqlx-postgres\")]\n    pub fn get_postgres_connection_pool(&self) -> &sqlx::PgPool {\n        match &self.inner {\n            DatabaseConnectionType::SqlxPostgresPoolConnection(conn) => &conn.pool,\n            _ => panic!(\"Not Postgres Connection\"),\n        }\n    }\n\n    /// Get [sqlx::SqlitePool]\n    ///\n    /// # Panics\n    ///\n    /// Panics if [DbConn] is not a SQLite connection.\n    #[cfg(feature = \"sqlx-sqlite\")]\n    pub fn get_sqlite_connection_pool(&self) -> &sqlx::SqlitePool {\n        match &self.inner {\n            DatabaseConnectionType::SqlxSqlitePoolConnection(conn) => &conn.pool,\n            _ => panic!(\"Not SQLite Connection\"),\n        }\n    }\n}\n\nimpl DbBackend {\n    /// Check if the URI is the same as the specified database backend.\n    /// Returns true if they match.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `base_url` cannot be parsed as `Url`.\n    pub fn is_prefix_of(self, base_url: &str) -> bool {\n        let base_url_parsed = Url::parse(base_url).expect(\"Fail to parse database URL\");\n        match self {\n            Self::Postgres => {\n                base_url_parsed.scheme() == \"postgres\" || base_url_parsed.scheme() == \"postgresql\"\n            }\n            Self::MySql => base_url_parsed.scheme() == \"mysql\",\n            Self::Sqlite => base_url_parsed.scheme() == \"sqlite\",\n        }\n    }\n\n    /// Build an SQL [Statement]\n    pub fn build<S>(&self, statement: &S) -> Statement\n    where\n        S: StatementBuilder,\n    {\n        statement.build(self)\n    }\n\n    /// Check if the database supports `RETURNING` syntax on insert and update\n    pub fn support_returning(&self) -> bool {\n        match self {\n            Self::Postgres => true,\n            Self::Sqlite if cfg!(feature = \"sqlite-use-returning-for-3_35\") => true,\n            Self::MySql if cfg!(feature = \"mariadb-use-returning\") => true,\n            _ => false,\n        }\n    }\n\n    /// A getter for database dependent boolean value\n    pub fn boolean_value(&self, boolean: bool) -> sea_query::Value {\n        match self {\n            Self::MySql | Self::Postgres | Self::Sqlite => boolean.into(),\n        }\n    }\n\n    /// Get the display string for this enum\n    pub fn as_str(&self) -> &'static str {\n        match self {\n            DatabaseBackend::MySql => \"MySql\",\n            DatabaseBackend::Postgres => \"Postgres\",\n            DatabaseBackend::Sqlite => \"Sqlite\",\n        }\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::DatabaseConnection;\n\n    #[cfg(not(feature = \"sync\"))]\n    #[test]\n    fn assert_database_connection_traits() {\n        fn assert_send_sync<T: Send + Sync>() {}\n\n        assert_send_sync::<DatabaseConnection>();\n    }\n}\n"
  },
  {
    "path": "src/database/executor.rs",
    "content": "use crate::{\n    AccessMode, ConnectionTrait, DatabaseConnection, DatabaseTransaction, DbBackend, DbErr,\n    ExecResult, IsolationLevel, QueryResult, Statement, TransactionError, TransactionOptions,\n    TransactionTrait,\n};\nuse crate::{Schema, SchemaBuilder};\nuse std::future::Future;\nuse std::pin::Pin;\n\n/// A wrapper that holds either a reference to a [`DatabaseConnection`] or [`DatabaseTransaction`],\n/// or an owned [`DatabaseTransaction`].\n#[derive(Debug)]\npub enum DatabaseExecutor<'c> {\n    /// A reference to a database connection\n    Connection(&'c DatabaseConnection),\n    /// A reference to a database transaction\n    Transaction(&'c DatabaseTransaction),\n    /// An owned database transaction (used by migration's `SchemaManager::begin()`)\n    OwnedTransaction(DatabaseTransaction),\n}\n\nimpl<'c> From<&'c DatabaseConnection> for DatabaseExecutor<'c> {\n    fn from(conn: &'c DatabaseConnection) -> Self {\n        Self::Connection(conn)\n    }\n}\n\nimpl<'c> From<&'c DatabaseTransaction> for DatabaseExecutor<'c> {\n    fn from(trans: &'c DatabaseTransaction) -> Self {\n        Self::Transaction(trans)\n    }\n}\n\n#[async_trait::async_trait]\nimpl ConnectionTrait for DatabaseExecutor<'_> {\n    fn get_database_backend(&self) -> DbBackend {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.get_database_backend(),\n            DatabaseExecutor::Transaction(trans) => trans.get_database_backend(),\n            DatabaseExecutor::OwnedTransaction(trans) => trans.get_database_backend(),\n        }\n    }\n\n    async fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.execute_raw(stmt).await,\n            DatabaseExecutor::Transaction(trans) => trans.execute_raw(stmt).await,\n            DatabaseExecutor::OwnedTransaction(trans) => trans.execute_raw(stmt).await,\n        }\n    }\n\n    async fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.execute_unprepared(sql).await,\n            DatabaseExecutor::Transaction(trans) => trans.execute_unprepared(sql).await,\n            DatabaseExecutor::OwnedTransaction(trans) => trans.execute_unprepared(sql).await,\n        }\n    }\n\n    async fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.query_one_raw(stmt).await,\n            DatabaseExecutor::Transaction(trans) => trans.query_one_raw(stmt).await,\n            DatabaseExecutor::OwnedTransaction(trans) => trans.query_one_raw(stmt).await,\n        }\n    }\n\n    async fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.query_all_raw(stmt).await,\n            DatabaseExecutor::Transaction(trans) => trans.query_all_raw(stmt).await,\n            DatabaseExecutor::OwnedTransaction(trans) => trans.query_all_raw(stmt).await,\n        }\n    }\n}\n\n#[async_trait::async_trait]\nimpl TransactionTrait for DatabaseExecutor<'_> {\n    type Transaction = DatabaseTransaction;\n\n    async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.begin().await,\n            DatabaseExecutor::Transaction(trans) => trans.begin().await,\n            DatabaseExecutor::OwnedTransaction(trans) => trans.begin().await,\n        }\n    }\n\n    async fn begin_with_config(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => {\n                conn.begin_with_config(isolation_level, access_mode).await\n            }\n            DatabaseExecutor::Transaction(trans) => {\n                trans.begin_with_config(isolation_level, access_mode).await\n            }\n            DatabaseExecutor::OwnedTransaction(trans) => {\n                trans.begin_with_config(isolation_level, access_mode).await\n            }\n        }\n    }\n\n    async fn begin_with_options(\n        &self,\n        options: TransactionOptions,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.begin_with_options(options).await,\n            DatabaseExecutor::Transaction(trans) => trans.begin_with_options(options).await,\n            DatabaseExecutor::OwnedTransaction(trans) => trans.begin_with_options(options).await,\n        }\n    }\n\n    async fn transaction<F, T, E>(&self, callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(\n                &'c DatabaseTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        match self {\n            DatabaseExecutor::Connection(conn) => conn.transaction(callback).await,\n            DatabaseExecutor::Transaction(trans) => trans.transaction(callback).await,\n            DatabaseExecutor::OwnedTransaction(trans) => trans.transaction(callback).await,\n        }\n    }\n\n    async fn transaction_with_config<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(\n                &'c DatabaseTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        match self {\n            DatabaseExecutor::Connection(conn) => {\n                conn.transaction_with_config(callback, isolation_level, access_mode)\n                    .await\n            }\n            DatabaseExecutor::Transaction(trans) => {\n                trans\n                    .transaction_with_config(callback, isolation_level, access_mode)\n                    .await\n            }\n            DatabaseExecutor::OwnedTransaction(trans) => {\n                trans\n                    .transaction_with_config(callback, isolation_level, access_mode)\n                    .await\n            }\n        }\n    }\n}\n\n/// A trait for converting into [`DatabaseExecutor`]\npub trait IntoDatabaseExecutor<'c>: Send\nwhere\n    Self: 'c,\n{\n    /// Convert into a [`DatabaseExecutor`]\n    fn into_database_executor(self) -> DatabaseExecutor<'c>;\n}\n\nimpl<'c> IntoDatabaseExecutor<'c> for DatabaseExecutor<'c> {\n    fn into_database_executor(self) -> DatabaseExecutor<'c> {\n        self\n    }\n}\n\nimpl<'c> IntoDatabaseExecutor<'c> for &'c DatabaseConnection {\n    fn into_database_executor(self) -> DatabaseExecutor<'c> {\n        DatabaseExecutor::Connection(self)\n    }\n}\n\nimpl<'c> IntoDatabaseExecutor<'c> for &'c DatabaseTransaction {\n    fn into_database_executor(self) -> DatabaseExecutor<'c> {\n        DatabaseExecutor::Transaction(self)\n    }\n}\n\nimpl IntoDatabaseExecutor<'static> for DatabaseTransaction {\n    fn into_database_executor(self) -> DatabaseExecutor<'static> {\n        DatabaseExecutor::OwnedTransaction(self)\n    }\n}\n\nimpl DatabaseExecutor<'_> {\n    /// Returns `true` if this executor is backed by a transaction (borrowed or owned).\n    pub fn is_transaction(&self) -> bool {\n        matches!(\n            self,\n            DatabaseExecutor::Transaction(_) | DatabaseExecutor::OwnedTransaction(_)\n        )\n    }\n\n    /// Creates a [`SchemaBuilder`] for this backend\n    pub fn get_schema_builder(&self) -> SchemaBuilder {\n        Schema::new(self.get_database_backend()).builder()\n    }\n\n    #[cfg(feature = \"entity-registry\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"entity-registry\")))]\n    /// Builds a schema for all the entities in the given module\n    pub fn get_schema_registry(&self, prefix: &str) -> SchemaBuilder {\n        let schema = Schema::new(self.get_database_backend());\n        crate::EntityRegistry::build_schema(schema, prefix)\n    }\n}\n"
  },
  {
    "path": "src/database/mock.rs",
    "content": "use crate::{\n    DatabaseConnection, DatabaseConnectionType, DbBackend, EntityTrait, ExecResult,\n    ExecResultHolder, Iden, IdenStatic, Iterable, MockDatabaseConnection, MockDatabaseTrait,\n    ModelTrait, QueryResult, QueryResultRow, SelectA, SelectB, Statement, error::*,\n};\nuse sea_query::{Value, ValueType, Values};\nuse std::{collections::BTreeMap, sync::Arc};\nuse tracing::instrument;\n\n/// Defines a Mock database suitable for testing\n#[derive(Debug)]\npub struct MockDatabase {\n    db_backend: DbBackend,\n    transaction: Option<OpenTransaction>,\n    transaction_log: Vec<Transaction>,\n    exec_results: Vec<Result<MockExecResult, DbErr>>,\n    query_results: Vec<Result<Vec<MockRow>, DbErr>>,\n}\n\n/// Defines the results obtained from a [MockDatabase]\n#[derive(Clone, Debug, Default)]\npub struct MockExecResult {\n    /// The last inserted id on auto-increment\n    pub last_insert_id: u64,\n    /// The number of rows affected by the database operation\n    pub rows_affected: u64,\n}\n\n/// Defines the structure of a test Row for the [MockDatabase]\n/// which is just a [BTreeMap]<[String], [Value]>\n#[derive(Clone, Debug)]\npub struct MockRow {\n    /// The values of the single row\n    pub(crate) values: BTreeMap<String, Value>,\n}\n\n/// A trait to get a [MockRow] from a type useful for testing in the [MockDatabase]\npub trait IntoMockRow {\n    /// The method to perform this operation\n    fn into_mock_row(self) -> MockRow;\n}\n\n/// Defines a transaction that is has not been committed\n#[derive(Debug)]\npub struct OpenTransaction {\n    stmts: Vec<Statement>,\n    transaction_depth: usize,\n}\n\n/// Defines a database transaction as it holds a Vec<[Statement]>\n#[derive(Debug, Clone, PartialEq)]\npub struct Transaction {\n    stmts: Vec<Statement>,\n}\n\nimpl MockDatabase {\n    /// Instantiate a mock database with a [DbBackend] to simulate real\n    /// world SQL databases\n    pub fn new(db_backend: DbBackend) -> Self {\n        Self {\n            db_backend,\n            transaction: None,\n            transaction_log: Vec::new(),\n            exec_results: Vec::new(),\n            query_results: Vec::new(),\n        }\n    }\n\n    /// Create a database connection\n    pub fn into_connection(self) -> DatabaseConnection {\n        DatabaseConnectionType::MockDatabaseConnection(Arc::new(MockDatabaseConnection::new(self)))\n            .into()\n    }\n\n    /// Add some [MockExecResult]s to `exec_results`\n    pub fn append_exec_results<I>(mut self, vec: I) -> Self\n    where\n        I: IntoIterator<Item = MockExecResult>,\n    {\n        self.exec_results.extend(vec.into_iter().map(Result::Ok));\n        self\n    }\n\n    /// Add some Values to `query_results`\n    pub fn append_query_results<T, I, II>(mut self, vec: II) -> Self\n    where\n        T: IntoMockRow,\n        I: IntoIterator<Item = T>,\n        II: IntoIterator<Item = I>,\n    {\n        for row in vec.into_iter() {\n            let row = row.into_iter().map(|vec| Ok(vec.into_mock_row())).collect();\n            self.query_results.push(row);\n        }\n        self\n    }\n\n    /// Add some [DbErr]s to `exec_results`\n    pub fn append_exec_errors<I>(mut self, vec: I) -> Self\n    where\n        I: IntoIterator<Item = DbErr>,\n    {\n        self.exec_results.extend(vec.into_iter().map(Result::Err));\n        self\n    }\n\n    /// Add some [DbErr]s to `query_results`\n    pub fn append_query_errors<I>(mut self, vec: I) -> Self\n    where\n        I: IntoIterator<Item = DbErr>,\n    {\n        self.query_results.extend(vec.into_iter().map(Result::Err));\n        self\n    }\n}\n\nimpl MockDatabaseTrait for MockDatabase {\n    #[instrument(level = \"trace\")]\n    fn execute(&mut self, counter: usize, statement: Statement) -> Result<ExecResult, DbErr> {\n        if let Some(transaction) = &mut self.transaction {\n            transaction.push(statement);\n        } else {\n            self.transaction_log.push(Transaction::one(statement));\n        }\n        if counter < self.exec_results.len() {\n            match std::mem::replace(\n                &mut self.exec_results[counter],\n                Err(exec_err(\"this value has been consumed already\")),\n            ) {\n                Ok(result) => Ok(ExecResult {\n                    result: ExecResultHolder::Mock(result),\n                }),\n                Err(err) => Err(err),\n            }\n        } else {\n            Err(exec_err(\"`exec_results` buffer is empty\"))\n        }\n    }\n\n    #[instrument(level = \"trace\")]\n    fn query(&mut self, counter: usize, statement: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        if let Some(transaction) = &mut self.transaction {\n            transaction.push(statement);\n        } else {\n            self.transaction_log.push(Transaction::one(statement));\n        }\n        if counter < self.query_results.len() {\n            match std::mem::replace(\n                &mut self.query_results[counter],\n                Err(query_err(\"this value has been consumed already\")),\n            ) {\n                Ok(result) => Ok(result\n                    .into_iter()\n                    .map(|row| QueryResult {\n                        row: QueryResultRow::Mock(row),\n                    })\n                    .collect()),\n                Err(err) => Err(err),\n            }\n        } else {\n            Err(query_err(\"`query_results` buffer is empty.\"))\n        }\n    }\n\n    #[instrument(level = \"trace\")]\n    fn begin(&mut self) {\n        match self.transaction.as_mut() {\n            Some(transaction) => transaction.begin_nested(self.db_backend),\n            None => self.transaction = Some(OpenTransaction::init()),\n        }\n    }\n\n    #[instrument(level = \"trace\")]\n    fn commit(&mut self) {\n        match self.transaction.as_mut() {\n            Some(transaction) => {\n                if transaction.commit(self.db_backend) {\n                    if let Some(transaction) = self.transaction.take() {\n                        self.transaction_log.push(transaction.into_transaction());\n                    }\n                }\n            }\n            None => panic!(\"There is no open transaction to commit\"),\n        }\n    }\n\n    #[instrument(level = \"trace\")]\n    fn rollback(&mut self) {\n        match self.transaction.as_mut() {\n            Some(transaction) => {\n                if transaction.rollback(self.db_backend) {\n                    if let Some(transaction) = self.transaction.take() {\n                        self.transaction_log.push(transaction.into_transaction());\n                    }\n                }\n            }\n            None => panic!(\"There is no open transaction to rollback\"),\n        }\n    }\n\n    fn drain_transaction_log(&mut self) -> Vec<Transaction> {\n        std::mem::take(&mut self.transaction_log)\n    }\n\n    fn get_database_backend(&self) -> DbBackend {\n        self.db_backend\n    }\n\n    fn ping(&self) -> Result<(), DbErr> {\n        Ok(())\n    }\n}\n\nimpl MockRow {\n    /// Get a value from the [MockRow]\n    pub fn try_get<T, I: crate::ColIdx>(&self, index: I) -> Result<T, DbErr>\n    where\n        T: ValueType,\n    {\n        if let Some(index) = index.as_str() {\n            T::try_from(\n                self.values\n                    .get(index)\n                    .ok_or_else(|| query_err(format!(\"No column for ColIdx {index:?}\")))?\n                    .clone(),\n            )\n            .map_err(type_err)\n        } else if let Some(index) = index.as_usize() {\n            let (_, value) = self\n                .values\n                .iter()\n                .nth(*index)\n                .ok_or_else(|| query_err(format!(\"Column at index {index} not found\")))?;\n            T::try_from(value.clone()).map_err(type_err)\n        } else {\n            unreachable!(\"Missing ColIdx implementation for MockRow\");\n        }\n    }\n\n    /// An iterator over the keys and values of a mock row\n    pub fn into_column_value_tuples(self) -> impl Iterator<Item = (String, Value)> {\n        self.values.into_iter()\n    }\n}\n\nimpl IntoMockRow for MockRow {\n    fn into_mock_row(self) -> MockRow {\n        self\n    }\n}\n\nimpl<M> IntoMockRow for M\nwhere\n    M: ModelTrait,\n{\n    fn into_mock_row(self) -> MockRow {\n        let mut values = BTreeMap::new();\n        for col in <<M::Entity as EntityTrait>::Column>::iter() {\n            values.insert(col.to_string(), self.get(col));\n        }\n        MockRow { values }\n    }\n}\n\nimpl<M, N> IntoMockRow for (M, N)\nwhere\n    M: ModelTrait,\n    N: ModelTrait,\n{\n    fn into_mock_row(self) -> MockRow {\n        let mut mapped_join = BTreeMap::new();\n\n        for column in <<M as ModelTrait>::Entity as EntityTrait>::Column::iter() {\n            mapped_join.insert(\n                format!(\"{}{}\", SelectA.as_str(), column.as_str()),\n                self.0.get(column),\n            );\n        }\n        for column in <<N as ModelTrait>::Entity as EntityTrait>::Column::iter() {\n            mapped_join.insert(\n                format!(\"{}{}\", SelectB.as_str(), column.as_str()),\n                self.1.get(column),\n            );\n        }\n\n        mapped_join.into_mock_row()\n    }\n}\n\nimpl<M, N> IntoMockRow for (M, Option<N>)\nwhere\n    M: ModelTrait,\n    N: ModelTrait,\n{\n    fn into_mock_row(self) -> MockRow {\n        let mut mapped_join = BTreeMap::new();\n\n        for column in <<M as ModelTrait>::Entity as EntityTrait>::Column::iter() {\n            mapped_join.insert(\n                format!(\"{}{}\", SelectA.as_str(), column.as_str()),\n                self.0.get(column),\n            );\n        }\n        if let Some(b_entity) = self.1 {\n            for column in <<N as ModelTrait>::Entity as EntityTrait>::Column::iter() {\n                mapped_join.insert(\n                    format!(\"{}{}\", SelectB.as_str(), column.as_str()),\n                    b_entity.get(column),\n                );\n            }\n        }\n\n        mapped_join.into_mock_row()\n    }\n}\n\nimpl<T> IntoMockRow for BTreeMap<T, Value>\nwhere\n    T: Into<String>,\n{\n    fn into_mock_row(self) -> MockRow {\n        MockRow {\n            values: self.into_iter().map(|(k, v)| (k.into(), v)).collect(),\n        }\n    }\n}\n\nimpl Transaction {\n    /// Get the [Value]s from s raw SQL statement depending on the [DatabaseBackend](crate::DatabaseBackend)\n    pub fn from_sql_and_values<I, T>(db_backend: DbBackend, sql: T, values: I) -> Self\n    where\n        I: IntoIterator<Item = Value>,\n        T: Into<String>,\n    {\n        Self::one(Statement::from_string_values_tuple(\n            db_backend,\n            (sql, Values(values.into_iter().collect())),\n        ))\n    }\n\n    /// Create a Transaction with one statement\n    pub fn one(stmt: Statement) -> Self {\n        Self { stmts: vec![stmt] }\n    }\n\n    /// Create a Transaction with many statements\n    pub fn many<I>(stmts: I) -> Self\n    where\n        I: IntoIterator<Item = Statement>,\n    {\n        Self {\n            stmts: stmts.into_iter().collect(),\n        }\n    }\n\n    /// Wrap each Statement as a single-statement Transaction\n    pub fn wrap<I>(stmts: I) -> Vec<Self>\n    where\n        I: IntoIterator<Item = Statement>,\n    {\n        stmts.into_iter().map(Self::one).collect()\n    }\n\n    /// Get the list of statements\n    pub fn statements(&self) -> &[Statement] {\n        &self.stmts\n    }\n}\n\nimpl OpenTransaction {\n    fn init() -> Self {\n        Self {\n            stmts: vec![Statement::from_string(DbBackend::Postgres, \"BEGIN\")],\n            transaction_depth: 0,\n        }\n    }\n\n    fn begin_nested(&mut self, db_backend: DbBackend) {\n        self.transaction_depth += 1;\n        self.push(Statement::from_string(\n            db_backend,\n            format!(\"SAVEPOINT savepoint_{}\", self.transaction_depth),\n        ));\n    }\n\n    fn commit(&mut self, db_backend: DbBackend) -> bool {\n        if self.transaction_depth == 0 {\n            self.push(Statement::from_string(db_backend, \"COMMIT\"));\n            true\n        } else {\n            self.push(Statement::from_string(\n                db_backend,\n                format!(\"RELEASE SAVEPOINT savepoint_{}\", self.transaction_depth),\n            ));\n            self.transaction_depth -= 1;\n            false\n        }\n    }\n\n    fn rollback(&mut self, db_backend: DbBackend) -> bool {\n        if self.transaction_depth == 0 {\n            self.push(Statement::from_string(db_backend, \"ROLLBACK\"));\n            true\n        } else {\n            self.push(Statement::from_string(\n                db_backend,\n                format!(\"ROLLBACK TO SAVEPOINT savepoint_{}\", self.transaction_depth),\n            ));\n            self.transaction_depth -= 1;\n            false\n        }\n    }\n\n    fn push(&mut self, stmt: Statement) {\n        self.stmts.push(stmt);\n    }\n\n    fn into_transaction(self) -> Transaction {\n        match self.transaction_depth {\n            0 => Transaction { stmts: self.stmts },\n            _ => panic!(\"There is uncommitted nested transaction\"),\n        }\n    }\n}\n\n#[cfg(test)]\n#[cfg(feature = \"mock\")]\nmod tests {\n    #[cfg(feature = \"sync\")]\n    use crate::util::StreamShim;\n    use crate::{\n        DbBackend, DbErr, IntoMockRow, MockDatabase, Statement, Transaction, TransactionError,\n        TransactionTrait, entity::*, error::*, tests_cfg::*,\n    };\n    use futures_util::{TryStreamExt, stream::TryNext};\n    use pretty_assertions::assert_eq;\n\n    #[derive(Debug, PartialEq, Eq)]\n    pub struct MyErr(String);\n\n    impl std::error::Error for MyErr {}\n\n    impl std::fmt::Display for MyErr {\n        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n            write!(f, \"{}\", self.0.as_str())\n        }\n    }\n\n    #[smol_potat::test]\n    async fn test_transaction_1() {\n        let db = MockDatabase::new(DbBackend::Postgres).into_connection();\n\n        db.transaction::<_, (), DbErr>(|txn| {\n            Box::pin(async move {\n                let _1 = cake::Entity::find().one(txn).await;\n                let _2 = fruit::Entity::find().all(txn).await;\n\n                Ok(())\n            })\n        })\n        .await\n        .unwrap();\n\n        let _ = cake::Entity::find().all(&db).await;\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [\n                Transaction::many([\n                    Statement::from_string(DbBackend::Postgres, \"BEGIN\"),\n                    Statement::from_sql_and_values(\n                        DbBackend::Postgres,\n                        r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" LIMIT $1\"#,\n                        [1u64.into()]\n                    ),\n                    Statement::from_sql_and_values(\n                        DbBackend::Postgres,\n                        r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\"\"#,\n                        []\n                    ),\n                    Statement::from_string(DbBackend::Postgres, \"COMMIT\"),\n                ]),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n                    []\n                ),\n            ]\n        );\n    }\n\n    #[smol_potat::test]\n    async fn test_transaction_2() {\n        let db = MockDatabase::new(DbBackend::Postgres).into_connection();\n\n        let result = db\n            .transaction::<_, (), MyErr>(|txn| {\n                Box::pin(async move {\n                    let _ = cake::Entity::find().one(txn).await;\n                    Err(MyErr(\"test\".to_owned()))\n                })\n            })\n            .await;\n\n        match result {\n            Err(TransactionError::Transaction(err)) => {\n                assert_eq!(err, MyErr(\"test\".to_owned()))\n            }\n            _ => unreachable!(),\n        }\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([\n                Statement::from_string(DbBackend::Postgres, \"BEGIN\"),\n                Statement::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" LIMIT $1\"#,\n                    [1u64.into()]\n                ),\n                Statement::from_string(DbBackend::Postgres, \"ROLLBACK\"),\n            ])]\n        );\n    }\n\n    #[smol_potat::test]\n    async fn test_nested_transaction_1() {\n        let db = MockDatabase::new(DbBackend::Postgres).into_connection();\n\n        db.transaction::<_, (), DbErr>(|txn| {\n            Box::pin(async move {\n                let _ = cake::Entity::find().one(txn).await;\n\n                txn.transaction::<_, (), DbErr>(|txn| {\n                    Box::pin(async move {\n                        let _ = fruit::Entity::find().all(txn).await;\n\n                        Ok(())\n                    })\n                })\n                .await\n                .unwrap();\n\n                Ok(())\n            })\n        })\n        .await\n        .unwrap();\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([\n                Statement::from_string(DbBackend::Postgres, \"BEGIN\"),\n                Statement::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" LIMIT $1\"#,\n                    [1u64.into()]\n                ),\n                Statement::from_string(DbBackend::Postgres, \"SAVEPOINT savepoint_1\"),\n                Statement::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\"\"#,\n                    []\n                ),\n                Statement::from_string(DbBackend::Postgres, \"RELEASE SAVEPOINT savepoint_1\"),\n                Statement::from_string(DbBackend::Postgres, \"COMMIT\"),\n            ]),]\n        );\n    }\n\n    #[smol_potat::test]\n    async fn test_nested_transaction_2() {\n        let db = MockDatabase::new(DbBackend::Postgres).into_connection();\n\n        db.transaction::<_, (), DbErr>(|txn| {\n            Box::pin(async move {\n                let _ = cake::Entity::find().one(txn).await;\n\n                txn.transaction::<_, (), DbErr>(|txn| {\n                    Box::pin(async move {\n                        let _ = fruit::Entity::find().all(txn).await;\n\n                        txn.transaction::<_, (), DbErr>(|txn| {\n                            Box::pin(async move {\n                                let _ = cake::Entity::find().all(txn).await;\n\n                                Ok(())\n                            })\n                        })\n                        .await\n                        .unwrap();\n\n                        Ok(())\n                    })\n                })\n                .await\n                .unwrap();\n\n                Ok(())\n            })\n        })\n        .await\n        .unwrap();\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([\n                Statement::from_string(DbBackend::Postgres, \"BEGIN\"),\n                Statement::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" LIMIT $1\"#,\n                    [1u64.into()]\n                ),\n                Statement::from_string(DbBackend::Postgres, \"SAVEPOINT savepoint_1\"),\n                Statement::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\"\"#,\n                    []\n                ),\n                Statement::from_string(DbBackend::Postgres, \"SAVEPOINT savepoint_2\"),\n                Statement::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n                    []\n                ),\n                Statement::from_string(DbBackend::Postgres, \"RELEASE SAVEPOINT savepoint_2\"),\n                Statement::from_string(DbBackend::Postgres, \"RELEASE SAVEPOINT savepoint_1\"),\n                Statement::from_string(DbBackend::Postgres, \"COMMIT\"),\n            ]),]\n        );\n    }\n\n    #[smol_potat::test]\n    async fn test_stream_1() -> Result<(), DbErr> {\n        let apple = fruit::Model {\n            id: 1,\n            name: \"Apple\".to_owned(),\n            cake_id: Some(1),\n        };\n\n        let orange = fruit::Model {\n            id: 2,\n            name: \"orange\".to_owned(),\n            cake_id: None,\n        };\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[apple.clone(), orange.clone()]])\n            .into_connection();\n\n        let mut stream = fruit::Entity::find().stream(&db).await?;\n\n        assert_eq!(stream.try_next().await?, Some(apple));\n\n        assert_eq!(stream.try_next().await?, Some(orange));\n\n        assert_eq!(stream.try_next().await?, None);\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn test_stream_2() -> Result<(), DbErr> {\n        use fruit::Entity as Fruit;\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([Vec::<fruit::Model>::new()])\n            .into_connection();\n\n        let mut stream = Fruit::find().stream(&db).await?;\n\n        while let Some(item) = stream.try_next().await? {\n            let _item: fruit::ActiveModel = item.into();\n        }\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn test_stream_in_transaction() -> Result<(), DbErr> {\n        let apple = fruit::Model {\n            id: 1,\n            name: \"Apple\".to_owned(),\n            cake_id: Some(1),\n        };\n\n        let orange = fruit::Model {\n            id: 2,\n            name: \"orange\".to_owned(),\n            cake_id: None,\n        };\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[apple.clone(), orange.clone()]])\n            .into_connection();\n\n        let txn = db.begin().await?;\n\n        if let Ok(mut stream) = fruit::Entity::find().stream(&txn).await {\n            assert_eq!(stream.try_next().await?, Some(apple));\n\n            assert_eq!(stream.try_next().await?, Some(orange));\n\n            assert_eq!(stream.try_next().await?, None);\n\n            // stream will be dropped end of scope\n        }\n\n        txn.commit().await?;\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn test_mocked_join() {\n        let row = (\n            cake::Model {\n                id: 1,\n                name: \"Apple Cake\".to_owned(),\n            },\n            fruit::Model {\n                id: 2,\n                name: \"Apple\".to_owned(),\n                cake_id: Some(1),\n            },\n        );\n        let mocked_row = row.into_mock_row();\n\n        let a_id = mocked_row.try_get::<i32, _>(\"A_id\");\n        assert!(a_id.is_ok());\n        assert_eq!(1, a_id.unwrap());\n        let b_id = mocked_row.try_get::<i32, _>(\"B_id\");\n        assert!(b_id.is_ok());\n        assert_eq!(2, b_id.unwrap());\n    }\n\n    #[smol_potat::test]\n    async fn test_find_also_related_1() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                cake::Model {\n                    id: 1,\n                    name: \"Apple Cake\".to_owned(),\n                },\n                fruit::Model {\n                    id: 2,\n                    name: \"Apple\".to_owned(),\n                    cake_id: Some(1),\n                },\n            )]])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_related(fruit::Entity)\n                .all(&db)\n                .await?,\n            [(\n                cake::Model {\n                    id: 1,\n                    name: \"Apple Cake\".to_owned(),\n                },\n                Some(fruit::Model {\n                    id: 2,\n                    name: \"Apple\".to_owned(),\n                    cake_id: Some(1),\n                })\n            )]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::from_sql_and_values(\n                DbBackend::Postgres,\n                r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\", \"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\" FROM \"cake\" LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                []\n            ),]\n        );\n\n        Ok(())\n    }\n\n    #[cfg(feature = \"postgres-array\")]\n    #[smol_potat::test]\n    async fn test_postgres_array_1() -> Result<(), DbErr> {\n        mod collection {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"collection\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                pub integers: Vec<i32>,\n                pub integers_opt: Option<Vec<i32>>,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                collection::Model {\n                    id: 1,\n                    integers: vec![1, 2, 3],\n                    integers_opt: Some(vec![1, 2, 3]),\n                },\n                collection::Model {\n                    id: 2,\n                    integers: vec![],\n                    integers_opt: Some(vec![]),\n                },\n                collection::Model {\n                    id: 3,\n                    integers: vec![3, 1, 4],\n                    integers_opt: None,\n                },\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            collection::Entity::find().all(&db).await?,\n            [\n                collection::Model {\n                    id: 1,\n                    integers: vec![1, 2, 3],\n                    integers_opt: Some(vec![1, 2, 3]),\n                },\n                collection::Model {\n                    id: 2,\n                    integers: vec![],\n                    integers_opt: Some(vec![]),\n                },\n                collection::Model {\n                    id: 3,\n                    integers: vec![3, 1, 4],\n                    integers_opt: None,\n                },\n            ]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::from_sql_and_values(\n                DbBackend::Postgres,\n                r#\"SELECT \"collection\".\"id\", \"collection\".\"integers\", \"collection\".\"integers_opt\" FROM \"collection\"\"#,\n                []\n            ),]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn test_query_err() {\n        let db = MockDatabase::new(DbBackend::MySql)\n            .append_query_errors([query_err(\"this is a mock query error\")])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find().all(&db).await,\n            Err(query_err(\"this is a mock query error\"))\n        );\n    }\n\n    #[smol_potat::test]\n    async fn test_exec_err() {\n        let db = MockDatabase::new(DbBackend::MySql)\n            .append_exec_errors([exec_err(\"this is a mock exec error\")])\n            .into_connection();\n\n        let model = cake::ActiveModel::new();\n\n        assert_eq!(\n            model.save(&db).await,\n            Err(exec_err(\"this is a mock exec error\"))\n        );\n    }\n}\n"
  },
  {
    "path": "src/database/mod.rs",
    "content": "use std::{sync::Arc, time::Duration};\n\nuse futures_util::future::BoxFuture;\n#[cfg(feature = \"sqlx-mysql\")]\nuse sqlx::mysql::MySqlConnectOptions;\n#[cfg(feature = \"sqlx-postgres\")]\nuse sqlx::postgres::PgConnectOptions;\n#[cfg(feature = \"sqlx-sqlite\")]\nuse sqlx::sqlite::SqliteConnectOptions;\n\nmod connection;\nmod db_connection;\nmod executor;\n#[cfg(feature = \"mock\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"mock\")))]\nmod mock;\n#[cfg(feature = \"proxy\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"proxy\")))]\nmod proxy;\n#[cfg(feature = \"rbac\")]\nmod restricted_connection;\n#[cfg(all(feature = \"schema-sync\", feature = \"rusqlite\"))]\nmod sea_schema_rusqlite;\n#[cfg(all(feature = \"schema-sync\", feature = \"sqlx-dep\"))]\nmod sea_schema_shim;\nmod statement;\nmod stream;\nmod tracing_spans;\nmod transaction;\n\npub use connection::*;\npub use db_connection::*;\npub use executor::*;\n#[cfg(feature = \"mock\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"mock\")))]\npub use mock::*;\n#[cfg(feature = \"proxy\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"proxy\")))]\npub use proxy::*;\n#[cfg(feature = \"rbac\")]\npub use restricted_connection::*;\npub use statement::*;\nuse std::borrow::Cow;\npub use stream::*;\nuse tracing::instrument;\npub use transaction::*;\n\nuse crate::error::*;\n\n/// Defines a database\n#[derive(Debug, Default)]\npub struct Database;\n\n#[cfg(feature = \"sync\")]\ntype BoxFuture<'a, T> = T;\n\ntype AfterConnectCallback = Option<\n    Arc<\n        dyn Fn(DatabaseConnection) -> BoxFuture<'static, Result<(), DbErr>> + Send + Sync + 'static,\n    >,\n>;\n\n/// Defines the configuration options of a database\n#[derive(derive_more::Debug, Clone)]\npub struct ConnectOptions {\n    /// The URI of the database\n    pub(crate) url: String,\n    /// Maximum number of connections for a pool\n    pub(crate) max_connections: Option<u32>,\n    /// Minimum number of connections for a pool\n    pub(crate) min_connections: Option<u32>,\n    /// The connection timeout for a packet connection\n    pub(crate) connect_timeout: Option<Duration>,\n    /// Maximum idle time for a particular connection to prevent\n    /// network resource exhaustion\n    pub(crate) idle_timeout: Option<Option<Duration>>,\n    /// Set the maximum amount of time to spend waiting for acquiring a connection\n    pub(crate) acquire_timeout: Option<Duration>,\n    /// Set the maximum lifetime of individual connections\n    pub(crate) max_lifetime: Option<Option<Duration>>,\n    /// Enable SQLx statement logging\n    pub(crate) sqlx_logging: bool,\n    /// SQLx statement logging level (ignored if `sqlx_logging` is false)\n    pub(crate) sqlx_logging_level: log::LevelFilter,\n    /// SQLx slow statements logging level (ignored if `sqlx_logging` is false)\n    pub(crate) sqlx_slow_statements_logging_level: log::LevelFilter,\n    /// SQLx slow statements duration threshold (ignored if `sqlx_logging` is false)\n    pub(crate) sqlx_slow_statements_logging_threshold: Duration,\n    /// set sqlcipher key\n    pub(crate) sqlcipher_key: Option<Cow<'static, str>>,\n    /// Schema search path (PostgreSQL only)\n    pub(crate) schema_search_path: Option<String>,\n    /// Application name (PostgreSQL only)\n    pub(crate) application_name: Option<String>,\n    /// Statement timeout (PostgreSQL only)\n    pub(crate) statement_timeout: Option<Duration>,\n    pub(crate) test_before_acquire: bool,\n    /// Only establish connections to the DB as needed. If set to `true`, the db connection will\n    /// be created using SQLx's [connect_lazy](https://docs.rs/sqlx/latest/sqlx/struct.Pool.html#method.connect_lazy)\n    /// method.\n    pub(crate) connect_lazy: bool,\n\n    #[debug(skip)]\n    pub(crate) after_connect: AfterConnectCallback,\n\n    #[cfg(feature = \"sqlx-mysql\")]\n    #[debug(skip)]\n    pub(crate) mysql_opts_fn:\n        Option<Arc<dyn Fn(MySqlConnectOptions) -> MySqlConnectOptions + Send + Sync>>,\n    #[cfg(feature = \"sqlx-postgres\")]\n    #[debug(skip)]\n    pub(crate) pg_opts_fn: Option<Arc<dyn Fn(PgConnectOptions) -> PgConnectOptions + Send + Sync>>,\n    #[cfg(feature = \"sqlx-sqlite\")]\n    #[debug(skip)]\n    pub(crate) sqlite_opts_fn:\n        Option<Arc<dyn Fn(SqliteConnectOptions) -> SqliteConnectOptions + Send + Sync>>,\n}\n\nimpl Database {\n    /// Method to create a [DatabaseConnection] on a database. This method will return an error\n    /// if the database is not available.\n    #[instrument(level = \"trace\", skip(opt))]\n    pub async fn connect<C>(opt: C) -> Result<DatabaseConnection, DbErr>\n    where\n        C: Into<ConnectOptions>,\n    {\n        let opt: ConnectOptions = opt.into();\n\n        if url::Url::parse(&opt.url).is_err() {\n            return Err(conn_err(format!(\n                \"The connection string '{}' cannot be parsed.\",\n                opt.url\n            )));\n        }\n\n        #[cfg(feature = \"sqlx-mysql\")]\n        if DbBackend::MySql.is_prefix_of(&opt.url) {\n            return crate::SqlxMySqlConnector::connect(opt).await;\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        if DbBackend::Postgres.is_prefix_of(&opt.url) {\n            return crate::SqlxPostgresConnector::connect(opt).await;\n        }\n        #[cfg(feature = \"sqlx-sqlite\")]\n        if DbBackend::Sqlite.is_prefix_of(&opt.url) {\n            return crate::SqlxSqliteConnector::connect(opt).await;\n        }\n        #[cfg(feature = \"rusqlite\")]\n        if DbBackend::Sqlite.is_prefix_of(&opt.url) {\n            return crate::driver::rusqlite::RusqliteConnector::connect(opt);\n        }\n        #[cfg(feature = \"mock\")]\n        if crate::MockDatabaseConnector::accepts(&opt.url) {\n            return crate::MockDatabaseConnector::connect(&opt.url).await;\n        }\n\n        Err(conn_err(format!(\n            \"The connection string '{}' has no supporting driver.\",\n            opt.url\n        )))\n    }\n\n    /// Method to create a [DatabaseConnection] on a proxy database\n    #[cfg(feature = \"proxy\")]\n    #[instrument(level = \"trace\", skip(proxy_func_arc))]\n    pub async fn connect_proxy(\n        db_type: DbBackend,\n        proxy_func_arc: std::sync::Arc<Box<dyn ProxyDatabaseTrait>>,\n    ) -> Result<DatabaseConnection, DbErr> {\n        match db_type {\n            DbBackend::MySql => {\n                return crate::ProxyDatabaseConnector::connect(\n                    DbBackend::MySql,\n                    proxy_func_arc.to_owned(),\n                );\n            }\n            DbBackend::Postgres => {\n                return crate::ProxyDatabaseConnector::connect(\n                    DbBackend::Postgres,\n                    proxy_func_arc.to_owned(),\n                );\n            }\n            DbBackend::Sqlite => {\n                return crate::ProxyDatabaseConnector::connect(\n                    DbBackend::Sqlite,\n                    proxy_func_arc.to_owned(),\n                );\n            }\n        }\n    }\n}\n\nimpl<T> From<T> for ConnectOptions\nwhere\n    T: Into<String>,\n{\n    fn from(s: T) -> ConnectOptions {\n        ConnectOptions::new(s.into())\n    }\n}\n\nimpl ConnectOptions {\n    /// Create new [ConnectOptions] for a [Database] by passing in a URI string\n    pub fn new<T>(url: T) -> Self\n    where\n        T: Into<String>,\n    {\n        Self {\n            url: url.into(),\n            max_connections: None,\n            min_connections: None,\n            connect_timeout: None,\n            idle_timeout: None,\n            acquire_timeout: None,\n            max_lifetime: None,\n            sqlx_logging: true,\n            sqlx_logging_level: log::LevelFilter::Info,\n            sqlx_slow_statements_logging_level: log::LevelFilter::Off,\n            sqlx_slow_statements_logging_threshold: Duration::from_secs(1),\n            sqlcipher_key: None,\n            schema_search_path: None,\n            application_name: None,\n            statement_timeout: None,\n            test_before_acquire: true,\n            connect_lazy: false,\n            after_connect: None,\n            #[cfg(feature = \"sqlx-mysql\")]\n            mysql_opts_fn: None,\n            #[cfg(feature = \"sqlx-postgres\")]\n            pg_opts_fn: None,\n            #[cfg(feature = \"sqlx-sqlite\")]\n            sqlite_opts_fn: None,\n        }\n    }\n\n    /// Get the database URL of the pool\n    pub fn get_url(&self) -> &str {\n        &self.url\n    }\n\n    /// Set the maximum number of connections of the pool\n    pub fn max_connections(&mut self, value: u32) -> &mut Self {\n        self.max_connections = Some(value);\n        self\n    }\n\n    /// Get the maximum number of connections of the pool, if set\n    pub fn get_max_connections(&self) -> Option<u32> {\n        self.max_connections\n    }\n\n    /// Set the minimum number of connections of the pool\n    pub fn min_connections(&mut self, value: u32) -> &mut Self {\n        self.min_connections = Some(value);\n        self\n    }\n\n    /// Get the minimum number of connections of the pool, if set\n    pub fn get_min_connections(&self) -> Option<u32> {\n        self.min_connections\n    }\n\n    /// Set the timeout duration when acquiring a connection\n    pub fn connect_timeout(&mut self, value: Duration) -> &mut Self {\n        self.connect_timeout = Some(value);\n        self\n    }\n\n    /// Get the timeout duration when acquiring a connection, if set\n    pub fn get_connect_timeout(&self) -> Option<Duration> {\n        self.connect_timeout\n    }\n\n    /// Set the idle duration before closing a connection.\n    pub fn idle_timeout<T>(&mut self, value: T) -> &mut Self\n    where\n        T: Into<Option<Duration>>,\n    {\n        self.idle_timeout = Some(value.into());\n        self\n    }\n\n    /// Get the idle duration before closing a connection, if set\n    pub fn get_idle_timeout(&self) -> Option<Option<Duration>> {\n        self.idle_timeout\n    }\n\n    /// Set the maximum amount of time to spend waiting for acquiring a connection\n    pub fn acquire_timeout(&mut self, value: Duration) -> &mut Self {\n        self.acquire_timeout = Some(value);\n        self\n    }\n\n    /// Get the maximum amount of time to spend waiting for acquiring a connection\n    pub fn get_acquire_timeout(&self) -> Option<Duration> {\n        self.acquire_timeout\n    }\n\n    /// Set the maximum lifetime of individual connections.\n    pub fn max_lifetime<T>(&mut self, lifetime: T) -> &mut Self\n    where\n        T: Into<Option<Duration>>,\n    {\n        self.max_lifetime = Some(lifetime.into());\n        self\n    }\n\n    /// Get the maximum lifetime of individual connections, if set\n    pub fn get_max_lifetime(&self) -> Option<Option<Duration>> {\n        self.max_lifetime\n    }\n\n    /// Enable SQLx statement logging (default true)\n    pub fn sqlx_logging(&mut self, value: bool) -> &mut Self {\n        self.sqlx_logging = value;\n        self\n    }\n\n    /// Get whether SQLx statement logging is enabled\n    pub fn get_sqlx_logging(&self) -> bool {\n        self.sqlx_logging\n    }\n\n    /// Set SQLx statement logging level (default INFO).\n    /// (ignored if `sqlx_logging` is `false`)\n    pub fn sqlx_logging_level(&mut self, level: log::LevelFilter) -> &mut Self {\n        self.sqlx_logging_level = level;\n        self\n    }\n\n    /// Set SQLx slow statements logging level and duration threshold (default `LevelFilter::Off`).\n    /// (ignored if `sqlx_logging` is `false`)\n    pub fn sqlx_slow_statements_logging_settings(\n        &mut self,\n        level: log::LevelFilter,\n        duration: Duration,\n    ) -> &mut Self {\n        self.sqlx_slow_statements_logging_level = level;\n        self.sqlx_slow_statements_logging_threshold = duration;\n        self\n    }\n\n    /// Get the level of SQLx statement logging\n    pub fn get_sqlx_logging_level(&self) -> log::LevelFilter {\n        self.sqlx_logging_level\n    }\n\n    /// Get the SQLx slow statements logging settings\n    pub fn get_sqlx_slow_statements_logging_settings(&self) -> (log::LevelFilter, Duration) {\n        (\n            self.sqlx_slow_statements_logging_level,\n            self.sqlx_slow_statements_logging_threshold,\n        )\n    }\n\n    /// set key for sqlcipher\n    pub fn sqlcipher_key<T>(&mut self, value: T) -> &mut Self\n    where\n        T: Into<Cow<'static, str>>,\n    {\n        self.sqlcipher_key = Some(value.into());\n        self\n    }\n\n    /// Set schema search path (PostgreSQL only)\n    pub fn set_schema_search_path<T>(&mut self, schema_search_path: T) -> &mut Self\n    where\n        T: Into<String>,\n    {\n        self.schema_search_path = Some(schema_search_path.into());\n        self\n    }\n\n    /// Set application name (PostgreSQL only)\n    pub fn set_application_name<T>(&mut self, application_name: T) -> &mut Self\n    where\n        T: Into<String>,\n    {\n        self.application_name = Some(application_name.into());\n        self\n    }\n\n    /// Set the statement timeout (PostgreSQL only).\n    ///\n    /// This sets the PostgreSQL `statement_timeout` parameter via the connection options,\n    /// causing the server to abort any statement that exceeds the specified duration.\n    /// The timeout is applied at connection time and does not require an extra roundtrip.\n    ///\n    /// Has no effect on MySQL or SQLite connections.\n    pub fn statement_timeout(&mut self, value: Duration) -> &mut Self {\n        self.statement_timeout = Some(value);\n        self\n    }\n\n    /// Get the statement timeout, if set\n    pub fn get_statement_timeout(&self) -> Option<Duration> {\n        self.statement_timeout\n    }\n\n    /// If true, the connection will be pinged upon acquiring from the pool (default true).\n    pub fn test_before_acquire(&mut self, value: bool) -> &mut Self {\n        self.test_before_acquire = value;\n        self\n    }\n\n    /// If set to `true`, the db connection pool will be created using SQLx's\n    /// [connect_lazy](https://docs.rs/sqlx/latest/sqlx/struct.Pool.html#method.connect_lazy) method.\n    pub fn connect_lazy(&mut self, value: bool) -> &mut Self {\n        self.connect_lazy = value;\n        self\n    }\n\n    /// Get whether DB connections will be established when the pool is created or only as needed.\n    pub fn get_connect_lazy(&self) -> bool {\n        self.connect_lazy\n    }\n\n    /// Set a callback function that will be called after a new connection is established.\n    pub fn after_connect<F>(&mut self, f: F) -> &mut Self\n    where\n        F: Fn(DatabaseConnection) -> BoxFuture<'static, Result<(), DbErr>> + Send + Sync + 'static,\n    {\n        self.after_connect = Some(Arc::new(f));\n\n        self\n    }\n\n    #[cfg(feature = \"sqlx-mysql\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"sqlx-mysql\")))]\n    /// Apply a function to modify the underlying [`MySqlConnectOptions`] before\n    /// creating the connection pool.\n    pub fn map_sqlx_mysql_opts<F>(&mut self, f: F) -> &mut Self\n    where\n        F: Fn(MySqlConnectOptions) -> MySqlConnectOptions + Send + Sync + 'static,\n    {\n        self.mysql_opts_fn = Some(Arc::new(f));\n        self\n    }\n\n    #[cfg(feature = \"sqlx-postgres\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"sqlx-postgres\")))]\n    /// Apply a function to modify the underlying [`PgConnectOptions`] before\n    /// creating the connection pool.\n    pub fn map_sqlx_postgres_opts<F>(&mut self, f: F) -> &mut Self\n    where\n        F: Fn(PgConnectOptions) -> PgConnectOptions + Send + Sync + 'static,\n    {\n        self.pg_opts_fn = Some(Arc::new(f));\n        self\n    }\n\n    #[cfg(feature = \"sqlx-sqlite\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"sqlx-sqlite\")))]\n    /// Apply a function to modify the underlying [`SqliteConnectOptions`] before\n    /// creating the connection pool.\n    pub fn map_sqlx_sqlite_opts<F>(&mut self, f: F) -> &mut Self\n    where\n        F: Fn(SqliteConnectOptions) -> SqliteConnectOptions + Send + Sync + 'static,\n    {\n        self.sqlite_opts_fn = Some(Arc::new(f));\n        self\n    }\n}\n"
  },
  {
    "path": "src/database/proxy.rs",
    "content": "use crate::{ExecResult, ExecResultHolder, QueryResult, QueryResultRow, Statement, error::*};\n\nuse sea_query::{Value, ValueType};\nuse std::{collections::BTreeMap, fmt::Debug};\n\n/// Defines the [ProxyDatabaseTrait] to save the functions\n#[async_trait::async_trait]\npub trait ProxyDatabaseTrait: Send + Sync + Debug {\n    /// Execute a query in the [ProxyDatabase], and return the query results\n    async fn query(&self, statement: Statement) -> Result<Vec<ProxyRow>, DbErr>;\n\n    /// Execute a command in the [ProxyDatabase], and report the number of rows affected\n    async fn execute(&self, statement: Statement) -> Result<ProxyExecResult, DbErr>;\n\n    /// Begin a transaction in the [ProxyDatabase]\n    async fn begin(&self) {}\n\n    /// Commit a transaction in the [ProxyDatabase]\n    async fn commit(&self) {}\n\n    /// Rollback a transaction in the [ProxyDatabase]\n    async fn rollback(&self) {}\n\n    /// Start rollback a transaction in the [ProxyDatabase]\n    fn start_rollback(&self) {}\n\n    /// Ping the [ProxyDatabase], it should return an error if the database is not available\n    async fn ping(&self) -> Result<(), DbErr> {\n        Ok(())\n    }\n}\n\n/// Defines the results obtained from a [ProxyDatabase]\n#[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize)]\npub struct ProxyExecResult {\n    /// The last inserted id on auto-increment\n    pub last_insert_id: u64,\n    /// The number of rows affected by the database operation\n    pub rows_affected: u64,\n}\n\nimpl ProxyExecResult {\n    /// Create a new [ProxyExecResult] from the last inserted id and the number of rows affected\n    pub fn new(last_insert_id: u64, rows_affected: u64) -> Self {\n        Self {\n            last_insert_id,\n            rows_affected,\n        }\n    }\n}\n\nimpl Default for ExecResultHolder {\n    fn default() -> Self {\n        Self::Proxy(ProxyExecResult::default())\n    }\n}\n\nimpl From<ProxyExecResult> for ExecResult {\n    fn from(result: ProxyExecResult) -> Self {\n        Self {\n            result: ExecResultHolder::Proxy(result),\n        }\n    }\n}\n\nimpl From<ExecResult> for ProxyExecResult {\n    fn from(result: ExecResult) -> Self {\n        match result.result {\n            #[cfg(feature = \"sqlx-mysql\")]\n            ExecResultHolder::SqlxMySql(result) => Self {\n                last_insert_id: result.last_insert_id(),\n                rows_affected: result.rows_affected(),\n            },\n            #[cfg(feature = \"sqlx-postgres\")]\n            ExecResultHolder::SqlxPostgres(result) => Self {\n                last_insert_id: 0,\n                rows_affected: result.rows_affected(),\n            },\n            #[cfg(feature = \"sqlx-sqlite\")]\n            ExecResultHolder::SqlxSqlite(result) => Self {\n                last_insert_id: result.last_insert_rowid() as u64,\n                rows_affected: result.rows_affected(),\n            },\n            #[cfg(feature = \"mock\")]\n            ExecResultHolder::Mock(result) => Self {\n                last_insert_id: result.last_insert_id,\n                rows_affected: result.rows_affected,\n            },\n            ExecResultHolder::Proxy(result) => result,\n        }\n    }\n}\n\n/// Defines the structure of a Row for the [ProxyDatabase]\n/// which is just a [BTreeMap]<[String], [Value]>\n#[derive(Clone, Debug, Default)]\npub struct ProxyRow {\n    /// The values of the single row\n    pub values: BTreeMap<String, Value>,\n}\n\nimpl ProxyRow {\n    /// Create a new [ProxyRow] from a [BTreeMap]<[String], [Value]>\n    pub fn new(values: BTreeMap<String, Value>) -> Self {\n        Self { values }\n    }\n}\n\nimpl From<BTreeMap<String, Value>> for ProxyRow {\n    fn from(values: BTreeMap<String, Value>) -> Self {\n        Self { values }\n    }\n}\n\nimpl From<ProxyRow> for BTreeMap<String, Value> {\n    fn from(row: ProxyRow) -> Self {\n        row.values\n    }\n}\n\nimpl From<ProxyRow> for Vec<(String, Value)> {\n    fn from(row: ProxyRow) -> Self {\n        row.values.into_iter().collect()\n    }\n}\n\nimpl From<ProxyRow> for QueryResult {\n    fn from(row: ProxyRow) -> Self {\n        QueryResult {\n            row: QueryResultRow::Proxy(row),\n        }\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl From<ProxyRow> for serde_json::Value {\n    fn from(val: ProxyRow) -> serde_json::Value {\n        val.values\n            .into_iter()\n            .map(|(k, v)| (k, sea_query::sea_value_to_json_value(&v)))\n            .collect()\n    }\n}\n\n/// Convert [QueryResult] to [ProxyRow]\npub fn from_query_result_to_proxy_row(result: &QueryResult) -> ProxyRow {\n    match &result.row {\n        #[cfg(feature = \"sqlx-mysql\")]\n        QueryResultRow::SqlxMySql(row) => crate::from_sqlx_mysql_row_to_proxy_row(row),\n        #[cfg(feature = \"sqlx-postgres\")]\n        QueryResultRow::SqlxPostgres(row) => crate::from_sqlx_postgres_row_to_proxy_row(row),\n        #[cfg(feature = \"sqlx-sqlite\")]\n        QueryResultRow::SqlxSqlite(row) => crate::from_sqlx_sqlite_row_to_proxy_row(row),\n        #[cfg(feature = \"mock\")]\n        QueryResultRow::Mock(row) => ProxyRow {\n            values: row.values.clone(),\n        },\n        QueryResultRow::Proxy(row) => row.to_owned(),\n    }\n}\n\nimpl ProxyRow {\n    /// Get a value from the [ProxyRow]\n    pub fn try_get<T, I: crate::ColIdx>(&self, index: I) -> Result<T, DbErr>\n    where\n        T: ValueType,\n    {\n        if let Some(index) = index.as_str() {\n            T::try_from(\n                self.values\n                    .get(index)\n                    .ok_or_else(|| query_err(format!(\"No column for ColIdx {index:?}\")))?\n                    .clone(),\n            )\n            .map_err(type_err)\n        } else if let Some(index) = index.as_usize() {\n            let (_, value) = self\n                .values\n                .iter()\n                .nth(*index)\n                .ok_or_else(|| query_err(format!(\"Column at index {index} not found\")))?;\n            T::try_from(value.clone()).map_err(type_err)\n        } else {\n            unreachable!(\"Missing ColIdx implementation for ProxyRow\");\n        }\n    }\n\n    /// An iterator over the keys and values of a proxy row\n    pub fn into_column_value_tuples(self) -> impl Iterator<Item = (String, Value)> {\n        self.values.into_iter()\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        Database, DbBackend, DbErr, ProxyDatabaseTrait, ProxyExecResult, ProxyRow, Statement,\n        entity::*, tests_cfg::*,\n    };\n    use std::sync::Arc;\n\n    #[derive(Debug)]\n    struct ProxyDb {}\n\n    #[async_trait::async_trait]\n    impl ProxyDatabaseTrait for ProxyDb {\n        async fn query(&self, statement: Statement) -> Result<Vec<ProxyRow>, DbErr> {\n            println!(\"SQL query: {}\", statement.sql);\n            Ok(vec![].into())\n        }\n\n        async fn execute(&self, statement: Statement) -> Result<ProxyExecResult, DbErr> {\n            println!(\"SQL execute: {}\", statement.sql);\n            Ok(ProxyExecResult {\n                last_insert_id: 1,\n                rows_affected: 1,\n            })\n        }\n    }\n\n    #[smol_potat::test]\n    async fn create_proxy_conn() {\n        let _db = Database::connect_proxy(DbBackend::MySql, Arc::new(Box::new(ProxyDb {})))\n            .await\n            .unwrap();\n    }\n\n    #[smol_potat::test]\n    async fn select_rows() {\n        let db = Database::connect_proxy(DbBackend::MySql, Arc::new(Box::new(ProxyDb {})))\n            .await\n            .unwrap();\n\n        let _ = cake::Entity::find().all(&db).await;\n    }\n\n    #[smol_potat::test]\n    async fn insert_one_row() {\n        let db = Database::connect_proxy(DbBackend::MySql, Arc::new(Box::new(ProxyDb {})))\n            .await\n            .unwrap();\n\n        let item = cake::ActiveModel {\n            id: NotSet,\n            name: Set(\"Alice\".to_string()),\n        };\n\n        cake::Entity::insert(item).exec(&db).await.unwrap();\n    }\n}\n"
  },
  {
    "path": "src/database/restricted_connection.rs",
    "content": "use crate::{\n    AccessMode, ConnectionTrait, DatabaseConnection, DatabaseTransaction, DbBackend, DbErr,\n    ExecResult, IsolationLevel, QueryResult, Statement, StatementBuilder, TransactionError,\n    TransactionSession, TransactionTrait,\n};\nuse crate::{\n    TransactionOptions,\n    rbac::{\n        PermissionRequest, RbacEngine, RbacError, RbacPermissionsByResources,\n        RbacResourcesAndPermissions, RbacRoleHierarchyList, RbacRolesAndRanks,\n        RbacUserRolePermissions, ResourceRequest,\n        entity::{role::RoleId, user::UserId},\n    },\n};\nuse std::{\n    pin::Pin,\n    sync::{Arc, RwLock},\n};\nuse tracing::instrument;\n\n/// Wrapper of [`DatabaseConnection`] that performs authorization on all executed\n/// queries for the current user. Note that raw SQL [`Statement`] is not allowed\n/// currently.\n#[derive(Debug, Clone)]\n#[cfg_attr(docsrs, doc(cfg(feature = \"rbac\")))]\npub struct RestrictedConnection {\n    pub(crate) user_id: UserId,\n    pub(crate) conn: DatabaseConnection,\n}\n\n/// Wrapper of [`DatabaseTransaction`] that performs authorization on all executed\n/// queries for the current user. Note that raw SQL [`Statement`] is not allowed\n/// currently.\n#[derive(Debug)]\npub struct RestrictedTransaction {\n    user_id: UserId,\n    conn: DatabaseTransaction,\n    rbac: RbacEngineMount,\n}\n\n#[derive(Debug, Default, Clone)]\npub(crate) struct RbacEngineMount {\n    inner: Arc<RwLock<Option<RbacEngine>>>,\n}\n\n#[async_trait::async_trait]\nimpl ConnectionTrait for RestrictedConnection {\n    fn get_database_backend(&self) -> DbBackend {\n        self.conn.get_database_backend()\n    }\n\n    async fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {stmt}\"\n        )))\n    }\n\n    async fn execute<S: StatementBuilder>(&self, stmt: &S) -> Result<ExecResult, DbErr> {\n        self.user_can_run(stmt)?;\n        self.conn.execute(stmt).await\n    }\n\n    async fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {sql}\"\n        )))\n    }\n\n    async fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {stmt}\"\n        )))\n    }\n\n    async fn query_one<S: StatementBuilder>(&self, stmt: &S) -> Result<Option<QueryResult>, DbErr> {\n        self.user_can_run(stmt)?;\n        self.conn.query_one(stmt).await\n    }\n\n    async fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {stmt}\"\n        )))\n    }\n\n    async fn query_all<S: StatementBuilder>(&self, stmt: &S) -> Result<Vec<QueryResult>, DbErr> {\n        self.user_can_run(stmt)?;\n        self.conn.query_all(stmt).await\n    }\n}\n\n#[async_trait::async_trait]\nimpl ConnectionTrait for RestrictedTransaction {\n    fn get_database_backend(&self) -> DbBackend {\n        self.conn.get_database_backend()\n    }\n\n    async fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {stmt}\"\n        )))\n    }\n\n    async fn execute<S: StatementBuilder>(&self, stmt: &S) -> Result<ExecResult, DbErr> {\n        self.user_can_run(stmt)?;\n        self.conn.execute(stmt).await\n    }\n\n    async fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {sql}\"\n        )))\n    }\n\n    async fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {stmt}\"\n        )))\n    }\n\n    async fn query_one<S: StatementBuilder>(&self, stmt: &S) -> Result<Option<QueryResult>, DbErr> {\n        self.user_can_run(stmt)?;\n        self.conn.query_one(stmt).await\n    }\n\n    async fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        Err(DbErr::RbacError(format!(\n            \"Raw query is not supported: {stmt}\"\n        )))\n    }\n\n    async fn query_all<S: StatementBuilder>(&self, stmt: &S) -> Result<Vec<QueryResult>, DbErr> {\n        self.user_can_run(stmt)?;\n        self.conn.query_all(stmt).await\n    }\n}\n\nimpl RestrictedConnection {\n    /// Get the [`RbacUserId`] bounded to this connection.\n    pub fn user_id(&self) -> UserId {\n        self.user_id\n    }\n\n    /// Returns `()` if the current user can execute / query the given SQL statement.\n    /// Returns `DbErr::AccessDenied` otherwise.\n    pub fn user_can_run<S: StatementBuilder>(&self, stmt: &S) -> Result<(), DbErr> {\n        self.conn.rbac.user_can_run(self.user_id, stmt)\n    }\n\n    /// Returns true if the current user can perform action on resource\n    pub fn user_can<P, R>(&self, permission: P, resource: R) -> Result<bool, DbErr>\n    where\n        P: Into<PermissionRequest>,\n        R: Into<ResourceRequest>,\n    {\n        self.conn.rbac.user_can(self.user_id, permission, resource)\n    }\n\n    /// Get current user's role and associated permissions.\n    /// This includes permissions \"inherited\" from child roles.\n    pub fn current_user_role_permissions(&self) -> Result<RbacUserRolePermissions, DbErr> {\n        self.conn.rbac.user_role_permissions(self.user_id)\n    }\n\n    /// Get a list of all roles and their ranks.\n    /// Rank is defined as (1 + number of child roles).\n    pub fn roles_and_ranks(&self) -> Result<RbacRolesAndRanks, DbErr> {\n        self.conn.rbac.roles_and_ranks()\n    }\n\n    /// Get two lists of all resources and permissions, excluding wildcards.\n    pub fn resources_and_permissions(&self) -> Result<RbacResourcesAndPermissions, DbErr> {\n        self.conn.rbac.resources_and_permissions()\n    }\n\n    /// Get a list of edges walking the role hierarchy tree\n    pub fn role_hierarchy_edges(&self, role_id: RoleId) -> Result<RbacRoleHierarchyList, DbErr> {\n        self.conn.rbac.role_hierarchy_edges(role_id)\n    }\n\n    /// Get a list of permissions for the specific role, grouped by resources.\n    /// This does not include permissions of child roles.\n    pub fn role_permissions_by_resources(\n        &self,\n        role_id: RoleId,\n    ) -> Result<RbacPermissionsByResources, DbErr> {\n        self.conn.rbac.role_permissions_by_resources(role_id)\n    }\n}\n\nimpl RestrictedTransaction {\n    /// Get the [`RbacUserId`] bounded to this connection.\n    pub fn user_id(&self) -> UserId {\n        self.user_id\n    }\n\n    /// Returns `()` if the current user can execute / query the given SQL statement.\n    /// Returns `DbErr::AccessDenied` otherwise.\n    pub fn user_can_run<S: StatementBuilder>(&self, stmt: &S) -> Result<(), DbErr> {\n        self.rbac.user_can_run(self.user_id, stmt)\n    }\n\n    /// Returns true if the current user can perform action on resource\n    pub fn user_can<P, R>(&self, permission: P, resource: R) -> Result<bool, DbErr>\n    where\n        P: Into<PermissionRequest>,\n        R: Into<ResourceRequest>,\n    {\n        self.rbac.user_can(self.user_id, permission, resource)\n    }\n}\n\n#[async_trait::async_trait]\nimpl TransactionTrait for RestrictedConnection {\n    type Transaction = RestrictedTransaction;\n\n    #[instrument(level = \"trace\")]\n    async fn begin(&self) -> Result<RestrictedTransaction, DbErr> {\n        Ok(RestrictedTransaction {\n            user_id: self.user_id,\n            conn: self.conn.begin().await?,\n            rbac: self.conn.rbac.clone(),\n        })\n    }\n\n    #[instrument(level = \"trace\")]\n    async fn begin_with_config(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<RestrictedTransaction, DbErr> {\n        Ok(RestrictedTransaction {\n            user_id: self.user_id,\n            conn: self\n                .conn\n                .begin_with_config(isolation_level, access_mode)\n                .await?,\n            rbac: self.conn.rbac.clone(),\n        })\n    }\n\n    #[instrument(level = \"trace\")]\n    async fn begin_with_options(\n        &self,\n        options: TransactionOptions,\n    ) -> Result<RestrictedTransaction, DbErr> {\n        Ok(RestrictedTransaction {\n            user_id: self.user_id,\n            conn: self.conn.begin_with_options(options).await?,\n            rbac: self.conn.rbac.clone(),\n        })\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(callback))]\n    async fn transaction<F, T, E>(&self, callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(\n                &'c RestrictedTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        let transaction = self.begin().await.map_err(TransactionError::Connection)?;\n        transaction.run(callback).await\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(callback))]\n    async fn transaction_with_config<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(\n                &'c RestrictedTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        let transaction = self\n            .begin_with_config(isolation_level, access_mode)\n            .await\n            .map_err(TransactionError::Connection)?;\n        transaction.run(callback).await\n    }\n}\n\n#[async_trait::async_trait]\nimpl TransactionTrait for RestrictedTransaction {\n    type Transaction = RestrictedTransaction;\n\n    #[instrument(level = \"trace\")]\n    async fn begin(&self) -> Result<RestrictedTransaction, DbErr> {\n        Ok(RestrictedTransaction {\n            user_id: self.user_id,\n            conn: self.conn.begin().await?,\n            rbac: self.rbac.clone(),\n        })\n    }\n\n    #[instrument(level = \"trace\")]\n    async fn begin_with_config(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<RestrictedTransaction, DbErr> {\n        Ok(RestrictedTransaction {\n            user_id: self.user_id,\n            conn: self\n                .conn\n                .begin_with_config(isolation_level, access_mode)\n                .await?,\n            rbac: self.rbac.clone(),\n        })\n    }\n\n    #[instrument(level = \"trace\")]\n    async fn begin_with_options(\n        &self,\n        options: TransactionOptions,\n    ) -> Result<RestrictedTransaction, DbErr> {\n        Ok(RestrictedTransaction {\n            user_id: self.user_id,\n            conn: self.conn.begin_with_options(options).await?,\n            rbac: self.rbac.clone(),\n        })\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(callback))]\n    async fn transaction<F, T, E>(&self, callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(\n                &'c RestrictedTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        let transaction = self.begin().await.map_err(TransactionError::Connection)?;\n        transaction.run(callback).await\n    }\n\n    /// Execute the function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back. If it does not return an error, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(callback))]\n    async fn transaction_with_config<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(\n                &'c RestrictedTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        let transaction = self\n            .begin_with_config(isolation_level, access_mode)\n            .await\n            .map_err(TransactionError::Connection)?;\n        transaction.run(callback).await\n    }\n}\n\n#[async_trait::async_trait]\nimpl TransactionSession for RestrictedTransaction {\n    async fn commit(self) -> Result<(), DbErr> {\n        self.commit().await\n    }\n\n    async fn rollback(self) -> Result<(), DbErr> {\n        self.rollback().await\n    }\n}\n\nimpl RestrictedTransaction {\n    /// Runs a transaction to completion passing through the result.\n    /// Rolling back the transaction on encountering an error.\n    #[instrument(level = \"trace\", skip(callback))]\n    async fn run<F, T, E>(self, callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'b> FnOnce(\n                &'b RestrictedTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'b>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        let res = callback(&self).await.map_err(TransactionError::Transaction);\n        if res.is_ok() {\n            self.commit().await.map_err(TransactionError::Connection)?;\n        } else {\n            self.rollback()\n                .await\n                .map_err(TransactionError::Connection)?;\n        }\n        res\n    }\n\n    /// Commit a transaction\n    #[instrument(level = \"trace\")]\n    pub async fn commit(self) -> Result<(), DbErr> {\n        self.conn.commit().await\n    }\n\n    /// Rolls back a transaction explicitly\n    #[instrument(level = \"trace\")]\n    pub async fn rollback(self) -> Result<(), DbErr> {\n        self.conn.rollback().await\n    }\n}\n\nimpl RbacEngineMount {\n    pub fn is_some(&self) -> bool {\n        let engine = self.inner.read().expect(\"RBAC Engine died\");\n        engine.is_some()\n    }\n\n    pub fn replace(&self, engine: RbacEngine) {\n        let mut inner = self.inner.write().expect(\"RBAC Engine died\");\n        *inner = Some(engine);\n    }\n\n    pub fn user_can<P, R>(&self, user_id: UserId, permission: P, resource: R) -> Result<bool, DbErr>\n    where\n        P: Into<PermissionRequest>,\n        R: Into<ResourceRequest>,\n    {\n        let permission = permission.into();\n        let resource = resource.into();\n        // There is nothing we can do if RwLock is poisoned.\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        // Constructor of this struct should ensure engine is not None.\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        engine\n            .user_can(user_id, permission, resource)\n            .map_err(map_err)\n    }\n\n    pub fn user_can_run<S: StatementBuilder>(\n        &self,\n        user_id: UserId,\n        stmt: &S,\n    ) -> Result<(), DbErr> {\n        let audit = match stmt.audit() {\n            Ok(audit) => audit,\n            Err(err) => return Err(DbErr::RbacError(err.to_string())),\n        };\n        // There is nothing we can do if RwLock is poisoned.\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        // Constructor of this struct should ensure engine is not None.\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        for request in audit.requests {\n            let permission = || PermissionRequest {\n                action: request.access_type.as_str().to_owned(),\n            };\n            let resource = || ResourceRequest {\n                schema: request.schema_table.0.as_ref().map(|s| s.1.to_string()),\n                table: request.schema_table.1.to_string(),\n            };\n            if !engine\n                .user_can(user_id, permission(), resource())\n                .map_err(map_err)?\n            {\n                return Err(DbErr::AccessDenied {\n                    permission: permission().action.to_owned(),\n                    resource: resource().to_string(),\n                });\n            }\n        }\n        Ok(())\n    }\n\n    pub fn user_role_permissions(&self, user_id: UserId) -> Result<RbacUserRolePermissions, DbErr> {\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        engine\n            .get_user_role_permissions(user_id)\n            .map_err(|err| DbErr::RbacError(err.to_string()))\n    }\n\n    pub fn roles_and_ranks(&self) -> Result<RbacRolesAndRanks, DbErr> {\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        engine\n            .get_roles_and_ranks()\n            .map_err(|err| DbErr::RbacError(err.to_string()))\n    }\n\n    pub fn resources_and_permissions(&self) -> Result<RbacResourcesAndPermissions, DbErr> {\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        Ok(engine.list_resources_and_permissions())\n    }\n\n    pub fn role_hierarchy_edges(&self, role_id: RoleId) -> Result<RbacRoleHierarchyList, DbErr> {\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        Ok(engine.list_role_hierarchy_edges(role_id))\n    }\n\n    pub fn role_permissions_by_resources(\n        &self,\n        role_id: RoleId,\n    ) -> Result<RbacPermissionsByResources, DbErr> {\n        let holder = self.inner.read().expect(\"RBAC Engine died\");\n        let engine = holder.as_ref().expect(\"RBAC Engine not set\");\n        engine\n            .list_role_permissions_by_resources(role_id)\n            .map_err(|err| DbErr::RbacError(err.to_string()))\n    }\n}\n\nfn map_err(err: RbacError) -> DbErr {\n    DbErr::RbacError(err.to_string())\n}\n"
  },
  {
    "path": "src/database/sea_schema_rusqlite.rs",
    "content": "use crate::{\n    ConnectionTrait, DatabaseConnection, DatabaseTransaction, DbErr, QueryResult, QueryResultRow,\n    RuntimeErr, Statement, driver::rusqlite::RusqliteRow as OurRusqliteRow,\n};\nuse sea_query::SelectStatement;\nuse sea_schema::rusqlite_types::{RusqliteError, RusqliteRow};\nuse std::sync::Arc;\n\nimpl sea_schema::Connection for DatabaseConnection {\n    fn query_all(&self, select: SelectStatement) -> Result<Vec<RusqliteRow>, RusqliteError> {\n        map_result(ConnectionTrait::query_all(self, &select))\n    }\n\n    fn query_all_raw(&self, sql: String) -> Result<Vec<RusqliteRow>, RusqliteError> {\n        map_result(ConnectionTrait::query_all_raw(\n            self,\n            Statement::from_string(self.get_database_backend(), sql),\n        ))\n    }\n}\n\nimpl sea_schema::Connection for DatabaseTransaction {\n    fn query_all(&self, select: SelectStatement) -> Result<Vec<RusqliteRow>, RusqliteError> {\n        map_result(ConnectionTrait::query_all(self, &select))\n    }\n\n    fn query_all_raw(&self, sql: String) -> Result<Vec<RusqliteRow>, RusqliteError> {\n        map_result(ConnectionTrait::query_all_raw(\n            self,\n            Statement::from_string(self.get_database_backend(), sql),\n        ))\n    }\n}\n\nfn map_result(result: Result<Vec<QueryResult>, DbErr>) -> Result<Vec<RusqliteRow>, RusqliteError> {\n    match result {\n        Ok(rows) => Ok(rows\n            .into_iter()\n            .filter_map(|r| match r.row {\n                #[cfg(feature = \"rusqlite\")]\n                QueryResultRow::Rusqlite(OurRusqliteRow { values, .. }) => {\n                    Some(RusqliteRow { values })\n                }\n                #[allow(unreachable_patterns)]\n                _ => None,\n            })\n            .collect()),\n        Err(err) => Err(match err {\n            DbErr::Conn(RuntimeErr::Rusqlite(err)) => {\n                Arc::into_inner(err).expect(\"Should only have one owner\")\n            }\n            DbErr::Exec(RuntimeErr::Rusqlite(err)) => {\n                Arc::into_inner(err).expect(\"Should only have one owner\")\n            }\n            DbErr::Query(RuntimeErr::Rusqlite(err)) => {\n                Arc::into_inner(err).expect(\"Should only have one owner\")\n            }\n            _ => RusqliteError::InvalidParameterName(err.to_string()),\n        }),\n    }\n}\n"
  },
  {
    "path": "src/database/sea_schema_shim.rs",
    "content": "use crate::{\n    ConnectionTrait, DatabaseConnection, DatabaseTransaction, DbErr, QueryResult, QueryResultRow,\n    RuntimeErr, Statement,\n};\nuse sea_query::SelectStatement;\nuse sea_schema::sqlx_types::SqlxRow;\nuse sqlx::Error as SqlxError;\nuse std::sync::Arc;\n\n#[async_trait::async_trait]\nimpl sea_schema::Connection for DatabaseConnection {\n    async fn query_all(&self, select: SelectStatement) -> Result<Vec<SqlxRow>, SqlxError> {\n        map_result(ConnectionTrait::query_all(self, &select).await)\n    }\n\n    async fn query_all_raw(&self, sql: String) -> Result<Vec<SqlxRow>, SqlxError> {\n        map_result(\n            ConnectionTrait::query_all_raw(\n                self,\n                Statement::from_string(self.get_database_backend(), sql),\n            )\n            .await,\n        )\n    }\n}\n\n#[async_trait::async_trait]\nimpl sea_schema::Connection for DatabaseTransaction {\n    async fn query_all(&self, select: SelectStatement) -> Result<Vec<SqlxRow>, SqlxError> {\n        map_result(ConnectionTrait::query_all(self, &select).await)\n    }\n\n    async fn query_all_raw(&self, sql: String) -> Result<Vec<SqlxRow>, SqlxError> {\n        map_result(\n            ConnectionTrait::query_all_raw(\n                self,\n                Statement::from_string(self.get_database_backend(), sql),\n            )\n            .await,\n        )\n    }\n}\n\n#[async_trait::async_trait]\nimpl sea_schema::Connection for crate::DatabaseExecutor<'_> {\n    async fn query_all(&self, select: SelectStatement) -> Result<Vec<SqlxRow>, SqlxError> {\n        match self {\n            crate::DatabaseExecutor::Connection(conn) => {\n                <DatabaseConnection as sea_schema::Connection>::query_all(conn, select).await\n            }\n            crate::DatabaseExecutor::Transaction(txn) => {\n                <DatabaseTransaction as sea_schema::Connection>::query_all(txn, select).await\n            }\n            crate::DatabaseExecutor::OwnedTransaction(txn) => {\n                <DatabaseTransaction as sea_schema::Connection>::query_all(txn, select).await\n            }\n        }\n    }\n\n    async fn query_all_raw(&self, sql: String) -> Result<Vec<SqlxRow>, SqlxError> {\n        match self {\n            crate::DatabaseExecutor::Connection(conn) => {\n                <DatabaseConnection as sea_schema::Connection>::query_all_raw(conn, sql).await\n            }\n            crate::DatabaseExecutor::Transaction(txn) => {\n                <DatabaseTransaction as sea_schema::Connection>::query_all_raw(txn, sql).await\n            }\n            crate::DatabaseExecutor::OwnedTransaction(txn) => {\n                <DatabaseTransaction as sea_schema::Connection>::query_all_raw(txn, sql).await\n            }\n        }\n    }\n}\n\nfn map_result(result: Result<Vec<QueryResult>, DbErr>) -> Result<Vec<SqlxRow>, SqlxError> {\n    match result {\n        Ok(rows) => Ok(rows\n            .into_iter()\n            .filter_map(|r| match r.row {\n                #[cfg(feature = \"sqlx-mysql\")]\n                QueryResultRow::SqlxMySql(r) => Some(SqlxRow::MySql(r)),\n                #[cfg(feature = \"sqlx-postgres\")]\n                QueryResultRow::SqlxPostgres(r) => Some(SqlxRow::Postgres(r)),\n                #[cfg(feature = \"sqlx-sqlite\")]\n                QueryResultRow::SqlxSqlite(r) => Some(SqlxRow::Sqlite(r)),\n                #[allow(unreachable_patterns)]\n                _ => None,\n            })\n            .collect()),\n        Err(err) => Err(match err {\n            DbErr::Conn(RuntimeErr::SqlxError(err)) => {\n                Arc::into_inner(err).expect(\"Should only have one owner\")\n            }\n            DbErr::Exec(RuntimeErr::SqlxError(err)) => {\n                Arc::into_inner(err).expect(\"Should only have one owner\")\n            }\n            DbErr::Query(RuntimeErr::SqlxError(err)) => {\n                Arc::into_inner(err).expect(\"Should only have one owner\")\n            }\n            _ => SqlxError::AnyDriverError(Box::new(err)),\n        }),\n    }\n}\n"
  },
  {
    "path": "src/database/statement.rs",
    "content": "use crate::DbBackend;\n#[cfg(feature = \"rbac\")]\npub use sea_query::audit::{AuditTrait, Error as AuditError, QueryAccessAudit};\nuse sea_query::{MysqlQueryBuilder, PostgresQueryBuilder, SqliteQueryBuilder, inject_parameters};\npub use sea_query::{Value, Values};\nuse std::fmt;\n\n/// Defines an SQL statement\n#[derive(Debug, Clone, PartialEq)]\npub struct Statement {\n    /// The SQL query\n    pub sql: String,\n    /// The values for the SQL statement's parameters\n    pub values: Option<Values>,\n    /// The database backend this statement is constructed for.\n    /// The SQL dialect and values should be valid for the DbBackend.\n    pub db_backend: DbBackend,\n}\n\n/// Any type that can build a [Statement]\npub trait StatementBuilder: Sync {\n    /// Method to build a [Statement]\n    fn build(&self, db_backend: &DbBackend) -> Statement;\n\n    #[cfg(feature = \"rbac\")]\n    /// Method to audit access request of query\n    fn audit(&self) -> Result<QueryAccessAudit, AuditError>;\n}\n\nimpl Statement {\n    /// Create a [Statement] from a [crate::DatabaseBackend] and a raw SQL statement\n    pub fn from_string<T>(db_backend: DbBackend, stmt: T) -> Statement\n    where\n        T: Into<String>,\n    {\n        Statement {\n            sql: stmt.into(),\n            values: None,\n            db_backend,\n        }\n    }\n\n    /// Create a SQL statement from a [crate::DatabaseBackend], a\n    /// raw SQL statement and param values\n    pub fn from_sql_and_values<I, T>(db_backend: DbBackend, sql: T, values: I) -> Self\n    where\n        I: IntoIterator<Item = Value>,\n        T: Into<String>,\n    {\n        Self::from_string_values_tuple(db_backend, (sql, Values(values.into_iter().collect())))\n    }\n\n    pub(crate) fn from_string_values_tuple<T>(db_backend: DbBackend, stmt: (T, Values)) -> Statement\n    where\n        T: Into<String>,\n    {\n        Statement {\n            sql: stmt.0.into(),\n            values: Some(stmt.1),\n            db_backend,\n        }\n    }\n}\n\nimpl fmt::Display for Statement {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        match &self.values {\n            Some(values) => {\n                let string = match self.db_backend {\n                    DbBackend::MySql => inject_parameters(&self.sql, &values.0, &MysqlQueryBuilder),\n                    DbBackend::Postgres => {\n                        inject_parameters(&self.sql, &values.0, &PostgresQueryBuilder)\n                    }\n                    DbBackend::Sqlite => {\n                        inject_parameters(&self.sql, &values.0, &SqliteQueryBuilder)\n                    }\n                };\n                write!(f, \"{}\", &string)\n            }\n            None => {\n                write!(f, \"{}\", &self.sql)\n            }\n        }\n    }\n}\n\nmacro_rules! build_any_stmt {\n    ($stmt: expr, $db_backend: expr) => {\n        match $db_backend {\n            DbBackend::MySql => $stmt.build(MysqlQueryBuilder),\n            DbBackend::Postgres => $stmt.build(PostgresQueryBuilder),\n            DbBackend::Sqlite => $stmt.build(SqliteQueryBuilder),\n        }\n    };\n}\n\nmacro_rules! build_postgres_stmt {\n    ($stmt: expr, $db_backend: expr) => {\n        match $db_backend {\n            DbBackend::Postgres => $stmt.to_string(PostgresQueryBuilder),\n            DbBackend::MySql | DbBackend::Sqlite => unimplemented!(),\n        }\n    };\n}\n\nmacro_rules! build_query_stmt {\n    ($stmt: ty) => {\n        impl StatementBuilder for $stmt {\n            fn build(&self, db_backend: &DbBackend) -> Statement {\n                let stmt = build_any_stmt!(self, db_backend);\n                Statement::from_string_values_tuple(*db_backend, stmt)\n            }\n\n            #[cfg(feature = \"rbac\")]\n            fn audit(&self) -> Result<QueryAccessAudit, AuditError> {\n                AuditTrait::audit(self)\n            }\n        }\n    };\n}\n\nbuild_query_stmt!(sea_query::InsertStatement);\nbuild_query_stmt!(sea_query::SelectStatement);\nbuild_query_stmt!(sea_query::UpdateStatement);\nbuild_query_stmt!(sea_query::DeleteStatement);\nbuild_query_stmt!(sea_query::WithQuery);\n\nmacro_rules! build_schema_stmt {\n    ($stmt: ty) => {\n        impl StatementBuilder for $stmt {\n            fn build(&self, db_backend: &DbBackend) -> Statement {\n                let stmt = build_any_stmt!(self, db_backend);\n                Statement::from_string(*db_backend, stmt)\n            }\n\n            #[cfg(feature = \"rbac\")]\n            fn audit(&self) -> Result<QueryAccessAudit, AuditError> {\n                todo!(\"Audit not supported for {} yet\", stringify!($stmt))\n            }\n        }\n    };\n}\n\nbuild_schema_stmt!(sea_query::TableCreateStatement);\nbuild_schema_stmt!(sea_query::TableDropStatement);\nbuild_schema_stmt!(sea_query::TableAlterStatement);\nbuild_schema_stmt!(sea_query::TableRenameStatement);\nbuild_schema_stmt!(sea_query::TableTruncateStatement);\nbuild_schema_stmt!(sea_query::IndexCreateStatement);\nbuild_schema_stmt!(sea_query::IndexDropStatement);\nbuild_schema_stmt!(sea_query::ForeignKeyCreateStatement);\nbuild_schema_stmt!(sea_query::ForeignKeyDropStatement);\n\nmacro_rules! build_type_stmt {\n    ($stmt: ty) => {\n        impl StatementBuilder for $stmt {\n            fn build(&self, db_backend: &DbBackend) -> Statement {\n                let stmt = build_postgres_stmt!(self, db_backend);\n                Statement::from_string(*db_backend, stmt)\n            }\n\n            #[cfg(feature = \"rbac\")]\n            fn audit(&self) -> Result<QueryAccessAudit, AuditError> {\n                Err(AuditError::UnsupportedQuery)\n            }\n        }\n    };\n}\n\nbuild_type_stmt!(sea_query::extension::postgres::TypeAlterStatement);\nbuild_type_stmt!(sea_query::extension::postgres::TypeCreateStatement);\nbuild_type_stmt!(sea_query::extension::postgres::TypeDropStatement);\n"
  },
  {
    "path": "src/database/stream/metric.rs",
    "content": "use std::{pin::Pin, task::Poll, time::Duration};\n\nuse futures_util::Stream;\n\nuse crate::{DbErr, QueryResult, Statement};\n\n#[cfg(not(feature = \"sync\"))]\ntype PinBoxStream<'a> = Pin<Box<dyn Stream<Item = Result<QueryResult, DbErr>> + 'a + Send>>;\n#[cfg(feature = \"sync\")]\ntype PinBoxStream<'a> = Box<dyn Iterator<Item = Result<QueryResult, DbErr>> + 'a>;\n\npub(crate) struct MetricStream<'a> {\n    metric_callback: &'a Option<crate::metric::Callback>,\n    stmt: &'a Statement,\n    elapsed: Option<Duration>,\n    stream: PinBoxStream<'a>,\n}\n\nimpl<'a> MetricStream<'a> {\n    #[allow(dead_code)]\n    pub(crate) fn new<S>(\n        metric_callback: &'a Option<crate::metric::Callback>,\n        stmt: &'a Statement,\n        elapsed: Option<Duration>,\n        stream: S,\n    ) -> Self\n    where\n        S: Stream<Item = Result<QueryResult, DbErr>> + 'a + Send,\n    {\n        MetricStream {\n            metric_callback,\n            stmt,\n            elapsed,\n            stream: Box::pin(stream),\n        }\n    }\n}\n\n#[cfg(not(feature = \"sync\"))]\nimpl Stream for MetricStream<'_> {\n    type Item = Result<QueryResult, DbErr>;\n\n    fn poll_next(\n        self: Pin<&mut Self>,\n        cx: &mut std::task::Context<'_>,\n    ) -> Poll<Option<Self::Item>> {\n        let this = self.get_mut();\n        let _start = this\n            .metric_callback\n            .is_some()\n            .then(std::time::SystemTime::now);\n        let res = Pin::new(&mut this.stream).poll_next(cx);\n        if let (Some(_start), Some(elapsed)) = (_start, &mut this.elapsed) {\n            *elapsed += _start.elapsed().unwrap_or_default();\n        }\n        res\n    }\n}\n\n#[cfg(feature = \"sync\")]\nimpl Iterator for MetricStream<'_> {\n    type Item = Result<QueryResult, DbErr>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let _start = self\n            .metric_callback\n            .is_some()\n            .then(std::time::SystemTime::now);\n        let res = self.stream.next();\n        if let (Some(_start), Some(elapsed)) = (_start, &mut self.elapsed) {\n            *elapsed += _start.elapsed().unwrap_or_default();\n        }\n        res\n    }\n}\n\nimpl Drop for MetricStream<'_> {\n    fn drop(&mut self) {\n        if let (Some(callback), Some(elapsed)) = (self.metric_callback.as_deref(), self.elapsed) {\n            let info = crate::metric::Info {\n                elapsed,\n                statement: self.stmt,\n                failed: false,\n            };\n            callback(&info);\n        }\n    }\n}\n"
  },
  {
    "path": "src/database/stream/mod.rs",
    "content": "mod metric;\n\nmod query;\nmod transaction;\n\npub use query::*;\npub use transaction::*;\n"
  },
  {
    "path": "src/database/stream/query.rs",
    "content": "#![allow(missing_docs, unreachable_code, unused_variables)]\n\nuse futures_util::Stream;\nuse std::{pin::Pin, task::Poll};\nuse tracing::instrument;\n\n#[cfg(feature = \"sqlx-dep\")]\nuse futures_util::TryStreamExt;\n\n#[cfg(feature = \"sqlx-dep\")]\nuse sqlx::Executor;\n\nuse super::metric::MetricStream;\n#[cfg(feature = \"sqlx-dep\")]\nuse crate::driver::*;\nuse crate::{DbErr, InnerConnection, QueryResult, Statement};\n\n/// Creates a stream from a [QueryResult]\n#[ouroboros::self_referencing]\npub struct QueryStream {\n    stmt: Statement,\n    conn: InnerConnection,\n    metric_callback: Option<crate::metric::Callback>,\n    #[borrows(mut conn, stmt, metric_callback)]\n    #[not_covariant]\n    stream: MetricStream<'this>,\n}\n\nimpl std::fmt::Debug for QueryStream {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"QueryStream\")\n    }\n}\n\nimpl QueryStream {\n    #[allow(dead_code)]\n    #[instrument(level = \"trace\", skip(metric_callback))]\n    pub(crate) fn build(\n        stmt: Statement,\n        conn: InnerConnection,\n        metric_callback: Option<crate::metric::Callback>,\n    ) -> QueryStream {\n        QueryStreamBuilder {\n            stmt,\n            conn,\n            metric_callback,\n            stream_builder: |conn, stmt, _metric_callback| match conn {\n                #[cfg(feature = \"sqlx-mysql\")]\n                InnerConnection::MySql(c) => {\n                    let query = crate::driver::sqlx_mysql::sqlx_query(stmt);\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c\n                        .fetch(query)\n                        .map_ok(Into::into)\n                        .map_err(sqlx_error_to_query_err);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"sqlx-postgres\")]\n                InnerConnection::Postgres(c) => {\n                    let query = crate::driver::sqlx_postgres::sqlx_query(stmt);\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c\n                        .fetch(query)\n                        .map_ok(Into::into)\n                        .map_err(sqlx_error_to_query_err);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"sqlx-sqlite\")]\n                InnerConnection::Sqlite(c) => {\n                    let query = crate::driver::sqlx_sqlite::sqlx_query(stmt);\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c\n                        .fetch(query)\n                        .map_ok(Into::into)\n                        .map_err(sqlx_error_to_query_err);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"rusqlite\")]\n                InnerConnection::Rusqlite(conn) => {\n                    use itertools::Either;\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = match conn.stream(stmt) {\n                        Ok(rows) => Either::Left(rows.into_iter().map(Ok)),\n                        Err(err) => Either::Right(std::iter::once(Err(err))),\n                    };\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"mock\")]\n                InnerConnection::Mock(c) => {\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c.fetch(stmt);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"proxy\")]\n                InnerConnection::Proxy(c) => {\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = futures_util::stream::once(async {\n                        Err(DbErr::BackendNotSupported {\n                            db: \"Proxy\",\n                            ctx: \"QueryStream\",\n                        })\n                    });\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[allow(unreachable_patterns)]\n                _ => unreachable!(),\n            },\n        }\n        .build()\n    }\n}\n\n#[cfg(not(feature = \"sync\"))]\nimpl Stream for QueryStream {\n    type Item = Result<QueryResult, DbErr>;\n\n    fn poll_next(\n        self: Pin<&mut Self>,\n        cx: &mut std::task::Context<'_>,\n    ) -> Poll<Option<Self::Item>> {\n        let this = self.get_mut();\n        this.with_stream_mut(|stream| Pin::new(stream).poll_next(cx))\n    }\n}\n\n#[cfg(feature = \"sync\")]\nimpl Iterator for QueryStream {\n    type Item = Result<QueryResult, DbErr>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.with_stream_mut(|stream| stream.next())\n    }\n}\n"
  },
  {
    "path": "src/database/stream/transaction.rs",
    "content": "#![allow(missing_docs)]\n\nuse std::{ops::DerefMut, pin::Pin, task::Poll};\nuse tracing::instrument;\n\nuse futures_util::Stream;\n#[cfg(feature = \"sqlx-dep\")]\nuse futures_util::TryStreamExt;\n\nuse futures_util::lock::MutexGuard;\n\n#[cfg(feature = \"sqlx-dep\")]\nuse sqlx::Executor;\n\nuse super::metric::MetricStream;\n#[cfg(feature = \"sqlx-dep\")]\nuse crate::driver::*;\nuse crate::{DbErr, InnerConnection, QueryResult, Statement};\n\n/// `TransactionStream` cannot be used in a `transaction` closure as it does not impl `Send`.\n/// It seems to be a Rust limitation right now, and solution to work around this deemed to be extremely hard.\n#[ouroboros::self_referencing]\npub struct TransactionStream<'a> {\n    stmt: Statement,\n    conn: MutexGuard<'a, InnerConnection>,\n    metric_callback: Option<crate::metric::Callback>,\n    #[borrows(mut conn, stmt, metric_callback)]\n    #[not_covariant]\n    stream: MetricStream<'this>,\n}\n\nimpl std::fmt::Debug for TransactionStream<'_> {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"TransactionStream\")\n    }\n}\n\nimpl TransactionStream<'_> {\n    #[instrument(level = \"trace\", skip(metric_callback))]\n    #[allow(unused_variables)]\n    pub(crate) fn build(\n        conn: MutexGuard<'_, InnerConnection>,\n        stmt: Statement,\n        metric_callback: Option<crate::metric::Callback>,\n    ) -> TransactionStream<'_> {\n        TransactionStreamBuilder {\n            stmt,\n            conn,\n            metric_callback,\n            stream_builder: |conn, stmt, _metric_callback| match conn.deref_mut() {\n                #[cfg(feature = \"sqlx-mysql\")]\n                InnerConnection::MySql(c) => {\n                    let query = crate::driver::sqlx_mysql::sqlx_query(stmt);\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c\n                        .fetch(query)\n                        .map_ok(Into::into)\n                        .map_err(sqlx_error_to_query_err);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"sqlx-postgres\")]\n                InnerConnection::Postgres(c) => {\n                    let query = crate::driver::sqlx_postgres::sqlx_query(stmt);\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c\n                        .fetch(query)\n                        .map_ok(Into::into)\n                        .map_err(sqlx_error_to_query_err);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"sqlx-sqlite\")]\n                InnerConnection::Sqlite(c) => {\n                    let query = crate::driver::sqlx_sqlite::sqlx_query(stmt);\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c\n                        .fetch(query)\n                        .map_ok(Into::into)\n                        .map_err(sqlx_error_to_query_err);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"mock\")]\n                InnerConnection::Mock(c) => {\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = c.fetch(stmt);\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[cfg(feature = \"proxy\")]\n                InnerConnection::Proxy(c) => {\n                    let start = _metric_callback.is_some().then(std::time::SystemTime::now);\n                    let stream = futures_util::stream::once(async {\n                        Err(DbErr::BackendNotSupported {\n                            db: \"Proxy\",\n                            ctx: \"TransactionStream\",\n                        })\n                    });\n                    let elapsed = start.map(|s| s.elapsed().unwrap_or_default());\n                    MetricStream::new(_metric_callback, stmt, elapsed, stream)\n                }\n                #[allow(unreachable_patterns)]\n                _ => unreachable!(),\n            },\n        }\n        .build()\n    }\n}\n\n#[cfg(not(feature = \"sync\"))]\nimpl Stream for TransactionStream<'_> {\n    type Item = Result<QueryResult, DbErr>;\n\n    fn poll_next(\n        self: Pin<&mut Self>,\n        cx: &mut std::task::Context<'_>,\n    ) -> Poll<Option<Self::Item>> {\n        let this = self.get_mut();\n        this.with_stream_mut(|stream| Pin::new(stream).poll_next(cx))\n    }\n}\n\n#[cfg(feature = \"sync\")]\nimpl Iterator for TransactionStream<'_> {\n    type Item = Result<QueryResult, DbErr>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.with_stream_mut(|stream| stream.next())\n    }\n}\n"
  },
  {
    "path": "src/database/tracing_spans.rs",
    "content": "//! Tracing support for database operations.\n//!\n//! This module provides utilities for instrumenting database operations\n//! with tracing spans. Enable the `tracing-spans` feature to automatically\n//! generate spans for all database operations.\n//!\n//! # Example\n//!\n//! ```toml\n//! [dependencies]\n//! sea-orm = { version = \"2.0\", features = [\"tracing-spans\"] }\n//! ```\n//!\n//! ```ignore\n//! use sea_orm::Database;\n//!\n//! // Set up a tracing subscriber\n//! tracing_subscriber::fmt()\n//!     .with_max_level(tracing::Level::INFO)\n//!     .init();\n//!\n//! // All database operations will now generate tracing spans\n//! let db = Database::connect(\"sqlite::memory:\").await?;\n//! let cakes = Cake::find().all(&db).await?;  // Generates a span\n//! ```\n\n#[cfg(feature = \"tracing-spans\")]\nmod inner {\n    use crate::DbBackend;\n\n    /// Database operation type, following OpenTelemetry conventions.\n    #[derive(Debug, Clone, Copy, PartialEq, Eq)]\n    pub(crate) enum DbOperation {\n        /// SELECT query\n        Select,\n        /// INSERT statement\n        Insert,\n        /// UPDATE statement\n        Update,\n        /// DELETE statement\n        Delete,\n        /// Other/unknown SQL execution\n        Execute,\n    }\n\n    impl DbOperation {\n        /// Parse the operation type from an SQL query string.\n        ///\n        /// This function is allocation-free and uses case-insensitive comparison.\n        pub fn from_sql(sql: &str) -> Self {\n            let first_word = sql.trim_start().split_whitespace().next().unwrap_or(\"\");\n            if first_word.eq_ignore_ascii_case(\"SELECT\") {\n                DbOperation::Select\n            } else if first_word.eq_ignore_ascii_case(\"INSERT\") {\n                DbOperation::Insert\n            } else if first_word.eq_ignore_ascii_case(\"UPDATE\") {\n                DbOperation::Update\n            } else if first_word.eq_ignore_ascii_case(\"DELETE\") {\n                DbOperation::Delete\n            } else {\n                DbOperation::Execute\n            }\n        }\n    }\n\n    impl std::fmt::Display for DbOperation {\n        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n            match self {\n                DbOperation::Select => write!(f, \"SELECT\"),\n                DbOperation::Insert => write!(f, \"INSERT\"),\n                DbOperation::Update => write!(f, \"UPDATE\"),\n                DbOperation::Delete => write!(f, \"DELETE\"),\n                DbOperation::Execute => write!(f, \"EXECUTE\"),\n            }\n        }\n    }\n\n    /// Get the OpenTelemetry system name from DbBackend.\n    pub(crate) fn db_system_name(backend: DbBackend) -> &'static str {\n        match backend {\n            DbBackend::Postgres => \"postgresql\",\n            DbBackend::MySql => \"mysql\",\n            DbBackend::Sqlite => \"sqlite\",\n        }\n    }\n\n    /// Record query result on a span (success/failure status and error message).\n    pub(crate) fn record_query_result<T, E: std::fmt::Display>(\n        span: &tracing::Span,\n        result: &Result<T, E>,\n    ) {\n        match result {\n            Ok(_) => {\n                span.record(\"otel.status_code\", \"OK\");\n            }\n            Err(e) => {\n                span.record(\"otel.status_code\", \"ERROR\");\n                span.record(\"exception.message\", tracing::field::display(e));\n            }\n        }\n    }\n}\n\n#[cfg(feature = \"tracing-spans\")]\npub(crate) use inner::*;\n\n/// Create a tracing span for database operations.\n///\n/// Arguments:\n/// - `$name`: Span name (e.g., \"sea_orm.execute\", \"sea_orm.query_one\")\n/// - `$backend`: DbBackend value\n/// - `$sql`: SQL statement string (used for operation parsing)\n///\n/// Note: `db.statement` is set to Empty. Call `span.record(\"db.statement\", sql)`\n/// separately if the query is parameterized (safe to log).\n#[cfg(feature = \"tracing-spans\")]\nmacro_rules! db_span {\n    ($name:expr, $backend:expr, $sql:expr) => {{\n        let sql: &str = $sql;\n        let op = $crate::database::tracing_spans::DbOperation::from_sql(sql);\n        ::tracing::info_span!(\n            $name,\n            otel.kind = \"client\",\n            db.system = $crate::database::tracing_spans::db_system_name($backend),\n            db.operation = %op,\n            db.statement = ::tracing::field::Empty,\n            otel.status_code = ::tracing::field::Empty,\n            exception.message = ::tracing::field::Empty,\n        )\n    }};\n}\n\n#[cfg(feature = \"tracing-spans\")]\npub(crate) use db_span;\n\n/// Execute a future and wrap it in a tracing span when `tracing-spans` is enabled.\n///\n/// When the feature is disabled, this macro simply awaits the future with zero overhead.\n///\n/// # Arguments\n/// - `$name`: span name (e.g., \"sea_orm.execute\")\n/// - `$backend`: DbBackend\n/// - `$sql`: &str used for db.operation parsing\n/// - `record_stmt`: whether to record `db.statement`\n/// - `$fut`: the future to execute\nmacro_rules! with_db_span {\n    ($name:expr, $backend:expr, $sql:expr, record_stmt = $record_stmt:expr, $fut:expr) => {{\n        #[cfg(all(feature = \"tracing-spans\", not(feature = \"sync\")))]\n        {\n            let span = $crate::database::tracing_spans::db_span!($name, $backend, $sql);\n            if $record_stmt {\n                span.record(\"db.statement\", $sql);\n            }\n            let result = ::tracing::Instrument::instrument($fut, span.clone()).await;\n            $crate::database::tracing_spans::record_query_result(&span, &result);\n            result\n        }\n        #[cfg(all(feature = \"tracing-spans\", feature = \"sync\"))]\n        {\n            let span = $crate::database::tracing_spans::db_span!($name, $backend, $sql);\n            if $record_stmt {\n                span.record(\"db.statement\", $sql);\n            }\n            span.in_scope($fut)\n        }\n        #[cfg(not(feature = \"tracing-spans\"))]\n        {\n            $fut.await\n        }\n    }};\n}\n\npub(crate) use with_db_span;\n\n#[cfg(feature = \"tracing-spans\")]\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_db_operation_from_sql() {\n        assert_eq!(\n            DbOperation::from_sql(\"SELECT * FROM users\"),\n            DbOperation::Select\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"  SELECT * FROM users\"),\n            DbOperation::Select\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"select * from users\"),\n            DbOperation::Select\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"INSERT INTO users\"),\n            DbOperation::Insert\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"UPDATE users SET\"),\n            DbOperation::Update\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"DELETE FROM users\"),\n            DbOperation::Delete\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"CREATE TABLE users\"),\n            DbOperation::Execute\n        );\n        assert_eq!(\n            DbOperation::from_sql(\"DROP TABLE users\"),\n            DbOperation::Execute\n        );\n    }\n\n    #[test]\n    fn test_db_system_name() {\n        assert_eq!(db_system_name(DbBackend::Postgres), \"postgresql\");\n        assert_eq!(db_system_name(DbBackend::MySql), \"mysql\");\n        assert_eq!(db_system_name(DbBackend::Sqlite), \"sqlite\");\n    }\n\n    #[test]\n    fn test_db_operation_display() {\n        assert_eq!(DbOperation::Select.to_string(), \"SELECT\");\n        assert_eq!(DbOperation::Insert.to_string(), \"INSERT\");\n        assert_eq!(DbOperation::Update.to_string(), \"UPDATE\");\n        assert_eq!(DbOperation::Delete.to_string(), \"DELETE\");\n        assert_eq!(DbOperation::Execute.to_string(), \"EXECUTE\");\n    }\n}\n"
  },
  {
    "path": "src/database/transaction.rs",
    "content": "#![allow(unused_assignments)]\nuse std::{future::Future, pin::Pin, sync::Arc};\n\nuse futures_util::lock::Mutex;\n#[cfg(feature = \"sqlx-dep\")]\nuse sqlx::TransactionManager;\nuse tracing::instrument;\n\nuse crate::{\n    AccessMode, ConnectionTrait, DbBackend, DbErr, ExecResult, InnerConnection, IsolationLevel,\n    QueryResult, SqliteTransactionMode, Statement, StreamTrait, TransactionOptions,\n    TransactionSession, TransactionStream, TransactionTrait, debug_print, error::*,\n};\n#[cfg(feature = \"sqlx-dep\")]\nuse crate::{sqlx_error_to_exec_err, sqlx_error_to_query_err};\n\n/// Defines a database transaction, whether it is an open transaction and the type of\n/// backend to use.\n/// Under the hood, a Transaction is just a wrapper for a connection where\n/// START TRANSACTION has been executed.\npub struct DatabaseTransaction {\n    conn: Arc<Mutex<InnerConnection>>,\n    backend: DbBackend,\n    open: bool,\n    metric_callback: Option<crate::metric::Callback>,\n}\n\nimpl std::fmt::Debug for DatabaseTransaction {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"DatabaseTransaction\")\n    }\n}\n\nimpl DatabaseTransaction {\n    #[instrument(level = \"trace\", skip(metric_callback))]\n    pub(crate) async fn begin(\n        conn: Arc<Mutex<InnerConnection>>,\n        backend: DbBackend,\n        metric_callback: Option<crate::metric::Callback>,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n        sqlite_transaction_mode: Option<SqliteTransactionMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        let res = DatabaseTransaction {\n            conn,\n            backend,\n            open: true,\n            metric_callback,\n        };\n\n        let begin_result: Result<(), DbErr> = super::tracing_spans::with_db_span!(\n            \"sea_orm.begin\",\n            backend,\n            \"BEGIN\",\n            record_stmt = false,\n            async {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *res.conn.lock().await;\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *res.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(c) => {\n                        // in MySQL SET TRANSACTION operations must be executed before transaction start\n                        crate::driver::sqlx_mysql::set_transaction_config(\n                            c,\n                            isolation_level,\n                            access_mode,\n                        )\n                        .await?;\n                        <sqlx::MySql as sqlx::Database>::TransactionManager::begin(c, None)\n                            .await\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(c) => {\n                        <sqlx::Postgres as sqlx::Database>::TransactionManager::begin(c, None)\n                            .await\n                            .map_err(sqlx_error_to_query_err)?;\n                        // in PostgreSQL SET TRANSACTION operations must be executed inside transaction\n                        crate::driver::sqlx_postgres::set_transaction_config(\n                            c,\n                            isolation_level,\n                            access_mode,\n                        )\n                        .await\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(c) => {\n                        crate::driver::sqlx_sqlite::set_transaction_config(\n                            c,\n                            isolation_level,\n                            access_mode,\n                        )\n                        .await?;\n                        let depth = <sqlx::Sqlite as sqlx::Database>::TransactionManager::get_transaction_depth(c);\n                        let statement = if depth == 0 {\n                            sqlite_transaction_mode.map(|mode| {\n                                std::borrow::Cow::from(format!(\"BEGIN {}\", mode.sqlite_keyword()))\n                            })\n                        } else {\n                            // Nested transaction uses SAVEPOINT; the mode only applies to the top-level BEGIN\n                            None\n                        };\n                        <sqlx::Sqlite as sqlx::Database>::TransactionManager::begin(c, statement)\n                            .await\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(c) => c.begin(sqlite_transaction_mode),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(c) => {\n                        c.begin();\n                        Ok(())\n                    }\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(c) => {\n                        c.begin().await;\n                        Ok(())\n                    }\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        );\n\n        begin_result?;\n        Ok(res)\n    }\n\n    /// Runs a transaction to completion passing through the result.\n    /// Rolling back the transaction on encountering an error.\n    #[instrument(level = \"trace\", skip(callback))]\n    pub(crate) async fn run<F, T, E>(self, callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'b> FnOnce(\n                &'b DatabaseTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'b>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        let res = callback(&self).await.map_err(TransactionError::Transaction);\n        if res.is_ok() {\n            self.commit().await.map_err(TransactionError::Connection)?;\n        } else {\n            self.rollback()\n                .await\n                .map_err(TransactionError::Connection)?;\n        }\n        res\n    }\n\n    /// Commit a transaction\n    #[instrument(level = \"trace\")]\n    #[allow(unreachable_code, unused_mut)]\n    pub async fn commit(mut self) -> Result<(), DbErr> {\n        let result: Result<(), DbErr> = super::tracing_spans::with_db_span!(\n            \"sea_orm.commit\",\n            self.backend,\n            \"COMMIT\",\n            record_stmt = false,\n            async {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *self.conn.lock().await;\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(c) => {\n                        <sqlx::MySql as sqlx::Database>::TransactionManager::commit(c)\n                            .await\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(c) => {\n                        <sqlx::Postgres as sqlx::Database>::TransactionManager::commit(c)\n                            .await\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(c) => {\n                        <sqlx::Sqlite as sqlx::Database>::TransactionManager::commit(c)\n                            .await\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(c) => c.commit(),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(c) => {\n                        c.commit();\n                        Ok(())\n                    }\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(c) => {\n                        c.commit().await;\n                        Ok(())\n                    }\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        );\n\n        result?;\n        self.open = false; // read by start_rollback\n        Ok(())\n    }\n\n    /// Rolls back a transaction explicitly\n    #[instrument(level = \"trace\")]\n    #[allow(unreachable_code, unused_mut)]\n    pub async fn rollback(mut self) -> Result<(), DbErr> {\n        let result: Result<(), DbErr> = super::tracing_spans::with_db_span!(\n            \"sea_orm.rollback\",\n            self.backend,\n            \"ROLLBACK\",\n            record_stmt = false,\n            async {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *self.conn.lock().await;\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(c) => {\n                        <sqlx::MySql as sqlx::Database>::TransactionManager::rollback(c)\n                            .await\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(c) => {\n                        <sqlx::Postgres as sqlx::Database>::TransactionManager::rollback(c)\n                            .await\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(c) => {\n                        <sqlx::Sqlite as sqlx::Database>::TransactionManager::rollback(c)\n                            .await\n                            .map_err(sqlx_error_to_query_err)\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(c) => c.rollback(),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(c) => {\n                        c.rollback();\n                        Ok(())\n                    }\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(c) => {\n                        c.rollback().await;\n                        Ok(())\n                    }\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        );\n\n        result?;\n        self.open = false; // read by start_rollback\n        Ok(())\n    }\n\n    // the rollback is queued and will be performed on next async operation, like returning the connection to the pool\n    #[instrument(level = \"trace\")]\n    fn start_rollback(&mut self) -> Result<(), DbErr> {\n        if self.open {\n            if let Some(mut conn) = self.conn.try_lock() {\n                match &mut *conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(c) => {\n                        <sqlx::MySql as sqlx::Database>::TransactionManager::start_rollback(c);\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(c) => {\n                        <sqlx::Postgres as sqlx::Database>::TransactionManager::start_rollback(c);\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(c) => {\n                        <sqlx::Sqlite as sqlx::Database>::TransactionManager::start_rollback(c);\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(c) => {\n                        c.start_rollback()?;\n                    }\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(c) => {\n                        c.rollback();\n                    }\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(c) => {\n                        c.start_rollback();\n                    }\n                    #[allow(unreachable_patterns)]\n                    _ => return Err(conn_err(\"Disconnected\")),\n                }\n            } else {\n                //this should never happen\n                return Err(conn_err(\"Dropping a locked Transaction\"));\n            }\n        }\n        Ok(())\n    }\n}\n\n#[async_trait::async_trait]\nimpl TransactionSession for DatabaseTransaction {\n    async fn commit(self) -> Result<(), DbErr> {\n        self.commit().await\n    }\n\n    async fn rollback(self) -> Result<(), DbErr> {\n        self.rollback().await\n    }\n}\n\nimpl Drop for DatabaseTransaction {\n    fn drop(&mut self) {\n        self.start_rollback().expect(\"Fail to rollback transaction\");\n    }\n}\n\n#[async_trait::async_trait]\nimpl ConnectionTrait for DatabaseTransaction {\n    fn get_database_backend(&self) -> DbBackend {\n        // this way we don't need to lock just to know the backend\n        self.backend\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    async fn execute_raw(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.execute\",\n            self.backend,\n            stmt.sql.as_str(),\n            record_stmt = true,\n            async {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *self.conn.lock().await;\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(conn) => {\n                        let query = crate::driver::sqlx_mysql::sqlx_query(&stmt);\n                        let conn: &mut sqlx::MySqlConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            query.execute(conn).await.map(Into::into)\n                        })\n                        .map_err(sqlx_error_to_exec_err)\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(conn) => {\n                        let query = crate::driver::sqlx_postgres::sqlx_query(&stmt);\n                        let conn: &mut sqlx::PgConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            query.execute(conn).await.map(Into::into)\n                        })\n                        .map_err(sqlx_error_to_exec_err)\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(conn) => {\n                        let query = crate::driver::sqlx_sqlite::sqlx_query(&stmt);\n                        let conn: &mut sqlx::SqliteConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            query.execute(conn).await.map(Into::into)\n                        })\n                        .map_err(sqlx_error_to_exec_err)\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(conn) => conn.execute(stmt, &self.metric_callback),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(conn) => conn.execute(stmt),\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(conn) => conn.execute(stmt).await,\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    async fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", sql);\n\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.execute_unprepared\",\n            self.backend,\n            sql,\n            record_stmt = false,\n            async {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *self.conn.lock().await;\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(conn) => {\n                        let conn: &mut sqlx::MySqlConnection = &mut *conn;\n                        sqlx::Executor::execute(conn, sql)\n                            .await\n                            .map(Into::into)\n                            .map_err(sqlx_error_to_exec_err)\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(conn) => {\n                        let conn: &mut sqlx::PgConnection = &mut *conn;\n                        sqlx::Executor::execute(conn, sql)\n                            .await\n                            .map(Into::into)\n                            .map_err(sqlx_error_to_exec_err)\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(conn) => {\n                        let conn: &mut sqlx::SqliteConnection = &mut *conn;\n                        sqlx::Executor::execute(conn, sql)\n                            .await\n                            .map(Into::into)\n                            .map_err(sqlx_error_to_exec_err)\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(conn) => conn.execute_unprepared(sql),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(conn) => {\n                        let db_backend = conn.get_database_backend();\n                        let stmt = Statement::from_string(db_backend, sql);\n                        conn.execute(stmt)\n                    }\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(conn) => {\n                        let db_backend = conn.get_database_backend();\n                        let stmt = Statement::from_string(db_backend, sql);\n                        conn.execute(stmt).await\n                    }\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    async fn query_one_raw(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.query_one\",\n            self.backend,\n            stmt.sql.as_str(),\n            record_stmt = true,\n            async {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *self.conn.lock().await;\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(conn) => {\n                        let query = crate::driver::sqlx_mysql::sqlx_query(&stmt);\n                        let conn: &mut sqlx::MySqlConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            crate::sqlx_map_err_ignore_not_found(\n                                query.fetch_one(conn).await.map(|row| Some(row.into())),\n                            )\n                        })\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(conn) => {\n                        let query = crate::driver::sqlx_postgres::sqlx_query(&stmt);\n                        let conn: &mut sqlx::PgConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            crate::sqlx_map_err_ignore_not_found(\n                                query.fetch_one(conn).await.map(|row| Some(row.into())),\n                            )\n                        })\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(conn) => {\n                        let query = crate::driver::sqlx_sqlite::sqlx_query(&stmt);\n                        let conn: &mut sqlx::SqliteConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            crate::sqlx_map_err_ignore_not_found(\n                                query.fetch_one(conn).await.map(|row| Some(row.into())),\n                            )\n                        })\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(conn) => conn.query_one(stmt, &self.metric_callback),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(conn) => conn.query_one(stmt),\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(conn) => conn.query_one(stmt).await,\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n\n    #[instrument(level = \"trace\")]\n    #[allow(unused_variables)]\n    async fn query_all_raw(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        super::tracing_spans::with_db_span!(\n            \"sea_orm.query_all\",\n            self.backend,\n            stmt.sql.as_str(),\n            record_stmt = true,\n            async {\n                #[cfg(not(feature = \"sync\"))]\n                let conn = &mut *self.conn.lock().await;\n                #[cfg(feature = \"sync\")]\n                let conn = &mut *self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n\n                match conn {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    InnerConnection::MySql(conn) => {\n                        let query = crate::driver::sqlx_mysql::sqlx_query(&stmt);\n                        let conn: &mut sqlx::MySqlConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            query\n                                .fetch_all(conn)\n                                .await\n                                .map(|rows| rows.into_iter().map(|r| r.into()).collect())\n                                .map_err(sqlx_error_to_query_err)\n                        })\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    InnerConnection::Postgres(conn) => {\n                        let query = crate::driver::sqlx_postgres::sqlx_query(&stmt);\n                        let conn: &mut sqlx::PgConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            query\n                                .fetch_all(conn)\n                                .await\n                                .map(|rows| rows.into_iter().map(|r| r.into()).collect())\n                                .map_err(sqlx_error_to_query_err)\n                        })\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    InnerConnection::Sqlite(conn) => {\n                        let query = crate::driver::sqlx_sqlite::sqlx_query(&stmt);\n                        let conn: &mut sqlx::SqliteConnection = &mut *conn;\n                        crate::metric::metric!(self.metric_callback, &stmt, {\n                            query\n                                .fetch_all(conn)\n                                .await\n                                .map(|rows| rows.into_iter().map(|r| r.into()).collect())\n                                .map_err(sqlx_error_to_query_err)\n                        })\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    InnerConnection::Rusqlite(conn) => conn.query_all(stmt, &self.metric_callback),\n                    #[cfg(feature = \"mock\")]\n                    InnerConnection::Mock(conn) => conn.query_all(stmt),\n                    #[cfg(feature = \"proxy\")]\n                    InnerConnection::Proxy(conn) => conn.query_all(stmt).await,\n                    #[allow(unreachable_patterns)]\n                    _ => Err(conn_err(\"Disconnected\")),\n                }\n            }\n        )\n    }\n}\n\nimpl StreamTrait for DatabaseTransaction {\n    type Stream<'a> = TransactionStream<'a>;\n\n    fn get_database_backend(&self) -> DbBackend {\n        self.backend\n    }\n\n    #[instrument(level = \"trace\")]\n    fn stream_raw<'a>(\n        &'a self,\n        stmt: Statement,\n    ) -> Pin<Box<dyn Future<Output = Result<Self::Stream<'a>, DbErr>> + 'a + Send>> {\n        Box::pin(async move {\n            #[cfg(not(feature = \"sync\"))]\n            let conn = self.conn.lock().await;\n            #[cfg(feature = \"sync\")]\n            let conn = self.conn.lock().map_err(|_| DbErr::MutexPoisonError)?;\n            Ok(crate::TransactionStream::build(\n                conn,\n                stmt,\n                self.metric_callback.clone(),\n            ))\n        })\n    }\n}\n\n#[async_trait::async_trait]\nimpl TransactionTrait for DatabaseTransaction {\n    type Transaction = DatabaseTransaction;\n\n    #[instrument(level = \"trace\")]\n    async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {\n        DatabaseTransaction::begin(\n            Arc::clone(&self.conn),\n            self.backend,\n            self.metric_callback.clone(),\n            None,\n            None,\n            None,\n        )\n        .await\n    }\n\n    #[instrument(level = \"trace\")]\n    async fn begin_with_config(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        DatabaseTransaction::begin(\n            Arc::clone(&self.conn),\n            self.backend,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n            None,\n        )\n        .await\n    }\n\n    #[instrument(level = \"trace\")]\n    async fn begin_with_options(\n        &self,\n        options: TransactionOptions,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        DatabaseTransaction::begin(\n            Arc::clone(&self.conn),\n            self.backend,\n            self.metric_callback.clone(),\n            options.isolation_level,\n            options.access_mode,\n            options.sqlite_transaction_mode,\n        )\n        .await\n    }\n\n    /// Execute the async function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back.\n    /// Otherwise, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(_callback))]\n    async fn transaction<F, T, E>(&self, _callback: F) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(\n                &'c DatabaseTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        let transaction = self.begin().await.map_err(TransactionError::Connection)?;\n        transaction.run(_callback).await\n    }\n\n    /// Execute the async function inside a transaction.\n    /// If the function returns an error, the transaction will be rolled back.\n    /// Otherwise, the transaction will be committed.\n    #[instrument(level = \"trace\", skip(_callback))]\n    async fn transaction_with_config<F, T, E>(\n        &self,\n        _callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'c> FnOnce(\n                &'c DatabaseTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'c>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        let transaction = self\n            .begin_with_config(isolation_level, access_mode)\n            .await\n            .map_err(TransactionError::Connection)?;\n        transaction.run(_callback).await\n    }\n}\n\n/// Defines errors for handling transaction failures\n#[derive(Debug)]\npub enum TransactionError<E> {\n    /// A Database connection error\n    Connection(DbErr),\n    /// An error occurring when doing database transactions\n    Transaction(E),\n}\n\nimpl<E> std::fmt::Display for TransactionError<E>\nwhere\n    E: std::fmt::Display + std::fmt::Debug,\n{\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            TransactionError::Connection(e) => std::fmt::Display::fmt(e, f),\n            TransactionError::Transaction(e) => std::fmt::Display::fmt(e, f),\n        }\n    }\n}\n\nimpl<E> std::error::Error for TransactionError<E> where E: std::fmt::Display + std::fmt::Debug {}\n\nimpl<E> From<DbErr> for TransactionError<E>\nwhere\n    E: std::fmt::Display + std::fmt::Debug,\n{\n    fn from(e: DbErr) -> Self {\n        Self::Connection(e)\n    }\n}\n"
  },
  {
    "path": "src/docs.rs",
    "content": "//! 1. Async\n//!\n//!     Relying on [SQLx](https://github.com/launchbadge/sqlx), SeaORM is a new library with async support from day 1.\n//!\n//! ```\n//! # use sea_orm::{error::*, tests_cfg::*, *};\n//! #\n//! # #[smol_potat::main]\n//! # #[cfg(all(feature = \"mock\", not(feature = \"sync\")))]\n//! # pub async fn main() -> Result<(), DbErr> {\n//! #\n//! # let db = MockDatabase::new(DbBackend::Postgres)\n//! #     .append_query_results([\n//! #         [cake::Model {\n//! #             id: 1,\n//! #             name: \"New York Cheese\".to_owned(),\n//! #         }\n//! #         .into_mock_row()],\n//! #         [fruit::Model {\n//! #             id: 1,\n//! #             name: \"Apple\".to_owned(),\n//! #             cake_id: Some(1),\n//! #         }\n//! #         .into_mock_row()],\n//! #     ])\n//! #     .into_connection();\n//! #\n//! // execute multiple queries in parallel\n//! let cakes_and_fruits: (Vec<cake::Model>, Vec<fruit::Model>) =\n//!     futures_util::future::try_join(Cake::find().all(&db), Fruit::find().all(&db)).await?;\n//! # assert_eq!(\n//! #     cakes_and_fruits,\n//! #     (\n//! #         vec![cake::Model {\n//! #             id: 1,\n//! #             name: \"New York Cheese\".to_owned(),\n//! #         }],\n//! #         vec![fruit::Model {\n//! #             id: 1,\n//! #             name: \"Apple\".to_owned(),\n//! #             cake_id: Some(1),\n//! #         }]\n//! #     )\n//! # );\n//! # assert_eq!(\n//! #     db.into_transaction_log(),\n//! #     [\n//! #         Transaction::from_sql_and_values(\n//! #             DbBackend::Postgres,\n//! #             r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n//! #             []\n//! #         ),\n//! #         Transaction::from_sql_and_values(\n//! #             DbBackend::Postgres,\n//! #             r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\"\"#,\n//! #             []\n//! #         ),\n//! #     ]\n//! # );\n//! # Ok(())\n//! # }\n//! # #[cfg(all(feature = \"mock\", feature = \"sync\"))]\n//! # fn main() {}\n//! ```\n//!\n//! 2. Dynamic\n//!\n//!     Built upon [SeaQuery](https://github.com/SeaQL/sea-query), SeaORM allows you to build complex queries without 'fighting the ORM'.\n//!\n//! ```\n//! # use sea_query::Query;\n//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*};\n//! # async fn function(db: DbConn) -> Result<(), DbErr> {\n//! // build subquery with ease\n//! let cakes_with_filling: Vec<cake::Model> = cake::Entity::find()\n//!     .filter(\n//!         Condition::any().add(\n//!             cake::Column::Id.in_subquery(\n//!                 Query::select()\n//!                     .column(cake_filling::Column::CakeId)\n//!                     .from(cake_filling::Entity)\n//!                     .to_owned(),\n//!             ),\n//!         ),\n//!     )\n//!     .all(&db)\n//!     .await?;\n//!\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! 3. Testable\n//!\n//!     Use mock connections to write unit tests for your logic.\n//!\n//! ```\n//! # use sea_orm::{error::*, entity::*, query::*, tests_cfg::*, DbConn, MockDatabase, Transaction, DbBackend};\n//! # async fn function(db: DbConn) -> Result<(), DbErr> {\n//! // Setup mock connection\n//! let db = MockDatabase::new(DbBackend::Postgres)\n//!     .append_query_results([\n//!         [\n//!             cake::Model {\n//!                 id: 1,\n//!                 name: \"New York Cheese\".to_owned(),\n//!             },\n//!         ],\n//!     ])\n//!     .into_connection();\n//!\n//! // Perform your application logic\n//! assert_eq!(\n//!     cake::Entity::find().one(&db).await?,\n//!     Some(cake::Model {\n//!         id: 1,\n//!         name: \"New York Cheese\".to_owned(),\n//!     })\n//! );\n//!\n//! // Compare it against the expected transaction log\n//! assert_eq!(\n//!     db.into_transaction_log(),\n//!     [\n//!         Transaction::from_sql_and_values(\n//!             DbBackend::Postgres,\n//!             r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" LIMIT $1\"#,\n//!             [1u64.into()]\n//!         ),\n//!     ]\n//! );\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! 4. Service Oriented\n//!\n//!     Quickly build services that join, filter, sort and paginate data in APIs.\n//!\n//! ```ignore\n//! #[get(\"/?<page>&<posts_per_page>\")]\n//! async fn list(\n//!     conn: Connection<Db>,\n//!     page: Option<usize>,\n//!     per_page: Option<usize>,\n//! ) -> Template {\n//!     // Set page number and items per page\n//!     let page = page.unwrap_or(1);\n//!     let per_page = per_page.unwrap_or(10);\n//!\n//!     // Setup paginator\n//!     let paginator = Post::find()\n//!         .order_by_asc(post::Column::Id)\n//!         .paginate(&conn, per_page);\n//!     let num_pages = paginator.num_pages().await.unwrap();\n//!\n//!     // Fetch paginated posts\n//!     let posts = paginator\n//!         .fetch_page(page - 1)\n//!         .await\n//!         .expect(\"could not retrieve posts\");\n//!\n//!     Template::render(\n//!         \"index\",\n//!         context! {\n//!             page: page,\n//!             per_page: per_page,\n//!             posts: posts,\n//!             num_pages: num_pages,\n//!         },\n//!     )\n//! }\n//! ```\n"
  },
  {
    "path": "src/driver/mock.rs",
    "content": "use crate::{\n    DatabaseConnection, DatabaseConnectionType, DbBackend, ExecResult, MockDatabase, QueryResult,\n    Statement, Transaction, debug_print, error::*,\n};\nuse futures_util::Stream;\nuse std::{\n    fmt::Debug,\n    pin::Pin,\n    sync::{\n        Arc, Mutex,\n        atomic::{AtomicUsize, Ordering},\n    },\n};\nuse tracing::instrument;\n\n#[cfg(not(feature = \"sync\"))]\ntype PinBoxStream = Pin<Box<dyn Stream<Item = Result<QueryResult, DbErr>> + Send>>;\n#[cfg(feature = \"sync\")]\ntype PinBoxStream = Box<dyn Iterator<Item = Result<QueryResult, DbErr>>>;\n\n/// Defines a database driver for the [MockDatabase]\n#[derive(Debug)]\npub struct MockDatabaseConnector;\n\n/// Defines a connection for the [MockDatabase]\n#[derive(Debug)]\npub struct MockDatabaseConnection {\n    execute_counter: AtomicUsize,\n    query_counter: AtomicUsize,\n    mocker: Mutex<Box<dyn MockDatabaseTrait>>,\n}\n\n/// A Trait for any type wanting to perform operations on the [MockDatabase]\npub trait MockDatabaseTrait: Send + Debug {\n    /// Execute a statement in the [MockDatabase]\n    fn execute(&mut self, counter: usize, stmt: Statement) -> Result<ExecResult, DbErr>;\n\n    /// Execute a SQL query in the [MockDatabase]\n    fn query(&mut self, counter: usize, stmt: Statement) -> Result<Vec<QueryResult>, DbErr>;\n\n    /// Create a transaction that can be committed atomically\n    fn begin(&mut self);\n\n    /// Commit a successful transaction atomically into the [MockDatabase]\n    fn commit(&mut self);\n\n    /// Roll back a transaction since errors were encountered\n    fn rollback(&mut self);\n\n    /// Get all logs from a [MockDatabase] and return a [Transaction]\n    fn drain_transaction_log(&mut self) -> Vec<Transaction>;\n\n    /// Get the backend being used in the [MockDatabase]\n    fn get_database_backend(&self) -> DbBackend;\n\n    /// Ping the [MockDatabase]\n    fn ping(&self) -> Result<(), DbErr>;\n}\n\nimpl MockDatabaseConnector {\n    /// Check if the database URI given and the [DatabaseBackend](crate::DatabaseBackend) selected are the same\n    #[allow(unused_variables)]\n    pub fn accepts(string: &str) -> bool {\n        #[cfg(feature = \"sqlx-mysql\")]\n        if DbBackend::MySql.is_prefix_of(string) {\n            return true;\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        if DbBackend::Postgres.is_prefix_of(string) {\n            return true;\n        }\n        #[cfg(feature = \"sqlx-sqlite\")]\n        if DbBackend::Sqlite.is_prefix_of(string) {\n            return true;\n        }\n        #[cfg(feature = \"rusqlite\")]\n        if DbBackend::Sqlite.is_prefix_of(string) {\n            return true;\n        }\n        false\n    }\n\n    /// Connect to the [MockDatabase]\n    #[allow(unused_variables)]\n    #[instrument(level = \"trace\")]\n    pub async fn connect(string: &str) -> Result<DatabaseConnection, DbErr> {\n        macro_rules! connect_mock_db {\n            ( $syntax: expr ) => {\n                Ok(DatabaseConnectionType::MockDatabaseConnection(Arc::new(\n                    MockDatabaseConnection::new(MockDatabase::new($syntax)),\n                ))\n                .into())\n            };\n        }\n\n        #[cfg(feature = \"sqlx-mysql\")]\n        if crate::SqlxMySqlConnector::accepts(string) {\n            return connect_mock_db!(DbBackend::MySql);\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        if crate::SqlxPostgresConnector::accepts(string) {\n            return connect_mock_db!(DbBackend::Postgres);\n        }\n        #[cfg(feature = \"sqlx-sqlite\")]\n        if crate::SqlxSqliteConnector::accepts(string) {\n            return connect_mock_db!(DbBackend::Sqlite);\n        }\n        #[cfg(feature = \"rusqlite\")]\n        if crate::driver::rusqlite::RusqliteConnector::accepts(string) {\n            return connect_mock_db!(DbBackend::Sqlite);\n        }\n        connect_mock_db!(DbBackend::Postgres)\n    }\n}\n\nimpl MockDatabaseConnection {\n    /// Create a connection to the [MockDatabase]\n    pub fn new<M>(m: M) -> Self\n    where\n        M: MockDatabaseTrait,\n        M: 'static,\n    {\n        Self {\n            execute_counter: AtomicUsize::new(0),\n            query_counter: AtomicUsize::new(0),\n            mocker: Mutex::new(Box::new(m)),\n        }\n    }\n\n    pub(crate) fn get_mocker_mutex(&self) -> &Mutex<Box<dyn MockDatabaseTrait>> {\n        &self.mocker\n    }\n\n    /// Get the [DatabaseBackend](crate::DatabaseBackend) being used by the [MockDatabase]\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the lock cannot be acquired.\n    pub fn get_database_backend(&self) -> DbBackend {\n        self.mocker\n            .lock()\n            .expect(\"Fail to acquire mocker\")\n            .get_database_backend()\n    }\n\n    /// Execute the SQL statement in the [MockDatabase]\n    #[instrument(level = \"trace\")]\n    pub fn execute(&self, statement: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", statement);\n        let counter = self.execute_counter.fetch_add(1, Ordering::SeqCst);\n        self.mocker\n            .lock()\n            .map_err(exec_err)?\n            .execute(counter, statement)\n    }\n\n    /// Return one [QueryResult] if the query was successful\n    #[instrument(level = \"trace\")]\n    pub fn query_one(&self, statement: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", statement);\n        let counter = self.query_counter.fetch_add(1, Ordering::SeqCst);\n        let result = self\n            .mocker\n            .lock()\n            .map_err(query_err)?\n            .query(counter, statement)?;\n        Ok(result.into_iter().next())\n    }\n\n    /// Return all [QueryResult]s if the query was successful\n    #[instrument(level = \"trace\")]\n    pub fn query_all(&self, statement: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug_print!(\"{}\", statement);\n        let counter = self.query_counter.fetch_add(1, Ordering::SeqCst);\n        self.mocker\n            .lock()\n            .map_err(query_err)?\n            .query(counter, statement)\n    }\n\n    /// Return [QueryResult]s  from a multi-query operation\n    #[instrument(level = \"trace\")]\n    pub fn fetch(&self, statement: &Statement) -> PinBoxStream {\n        #[cfg(not(feature = \"sync\"))]\n        {\n            match self.query_all(statement.clone()) {\n                Ok(v) => Box::pin(futures_util::stream::iter(v.into_iter().map(Ok))),\n                Err(e) => Box::pin(futures_util::stream::iter(Some(Err(e)).into_iter())),\n            }\n        }\n        #[cfg(feature = \"sync\")]\n        {\n            match self.query_all(statement.clone()) {\n                Ok(v) => Box::new(v.into_iter().map(Ok)),\n                Err(e) => Box::new(Some(Err(e)).into_iter()),\n            }\n        }\n    }\n\n    /// Create a statement block  of SQL statements that execute together.\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the lock cannot be acquired.\n    #[instrument(level = \"trace\")]\n    pub fn begin(&self) {\n        self.mocker\n            .lock()\n            .expect(\"Failed to acquire mocker\")\n            .begin()\n    }\n\n    /// Commit a transaction atomically to the database\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the lock cannot be acquired.\n    #[instrument(level = \"trace\")]\n    pub fn commit(&self) {\n        self.mocker\n            .lock()\n            .expect(\"Failed to acquire mocker\")\n            .commit()\n    }\n\n    /// Roll back a faulty transaction\n    ///\n    /// # Panics\n    ///\n    /// Will panic if the lock cannot be acquired.\n    #[instrument(level = \"trace\")]\n    pub fn rollback(&self) {\n        self.mocker\n            .lock()\n            .expect(\"Failed to acquire mocker\")\n            .rollback()\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub fn ping(&self) -> Result<(), DbErr> {\n        self.mocker.lock().map_err(query_err)?.ping()\n    }\n}\n\nimpl\n    From<(\n        Arc<crate::MockDatabaseConnection>,\n        Statement,\n        Option<crate::metric::Callback>,\n    )> for crate::QueryStream\n{\n    fn from(\n        (conn, stmt, metric_callback): (\n            Arc<crate::MockDatabaseConnection>,\n            Statement,\n            Option<crate::metric::Callback>,\n        ),\n    ) -> Self {\n        crate::QueryStream::build(stmt, crate::InnerConnection::Mock(conn), metric_callback)\n    }\n}\n\nimpl crate::DatabaseTransaction {\n    pub(crate) async fn new_mock(\n        inner: Arc<crate::MockDatabaseConnection>,\n        metric_callback: Option<crate::metric::Callback>,\n    ) -> Result<crate::DatabaseTransaction, DbErr> {\n        use futures_util::lock::Mutex;\n        let backend = inner.get_database_backend();\n        Self::begin(\n            Arc::new(Mutex::new(crate::InnerConnection::Mock(inner))),\n            backend,\n            metric_callback,\n            None,\n            None,\n            None,\n        )\n        .await\n    }\n}\n"
  },
  {
    "path": "src/driver/mod.rs",
    "content": "#[cfg(feature = \"mock\")]\nmod mock;\n#[cfg(feature = \"proxy\")]\nmod proxy;\n#[cfg(feature = \"rusqlite\")]\npub(crate) mod rusqlite;\n#[cfg(any(feature = \"sqlx-sqlite\", feature = \"rusqlite\"))]\nmod sqlite;\n#[cfg(feature = \"sqlx-dep\")]\nmod sqlx_common;\n#[cfg(feature = \"sqlx-mysql\")]\npub(crate) mod sqlx_mysql;\n#[cfg(feature = \"sqlx-postgres\")]\npub(crate) mod sqlx_postgres;\n#[cfg(feature = \"sqlx-sqlite\")]\npub(crate) mod sqlx_sqlite;\n\n#[cfg(feature = \"mock\")]\npub use mock::*;\n#[cfg(feature = \"proxy\")]\npub use proxy::*;\n#[cfg(feature = \"sqlx-dep\")]\npub(crate) use sqlx_common::*;\n#[cfg(feature = \"sqlx-mysql\")]\npub use sqlx_mysql::*;\n#[cfg(feature = \"sqlx-postgres\")]\npub use sqlx_postgres::*;\n#[cfg(feature = \"sqlx-sqlite\")]\npub use sqlx_sqlite::*;\n"
  },
  {
    "path": "src/driver/proxy.rs",
    "content": "use crate::{\n    DatabaseConnection, DatabaseConnectionType, DbBackend, ExecResult, ProxyDatabaseTrait,\n    QueryResult, Statement, debug_print, error::*,\n};\nuse std::{fmt::Debug, sync::Arc};\nuse tracing::instrument;\n\n/// Defines a database driver for the [ProxyDatabase]\n#[derive(Debug)]\npub struct ProxyDatabaseConnector;\n\n/// Defines a connection for the [ProxyDatabase]\n#[derive(Debug)]\npub struct ProxyDatabaseConnection {\n    db_backend: DbBackend,\n    proxy: Arc<Box<dyn ProxyDatabaseTrait>>,\n}\n\nimpl ProxyDatabaseConnector {\n    /// Check if the database URI given and the [DatabaseBackend](crate::DatabaseBackend) selected are the same\n    #[allow(unused_variables)]\n    pub fn accepts(string: &str) -> bool {\n        // As this is a proxy database, it accepts any URI\n        true\n    }\n\n    /// Connect to the [ProxyDatabase]\n    #[allow(unused_variables)]\n    #[instrument(level = \"trace\")]\n    pub fn connect(\n        db_type: DbBackend,\n        func: Arc<Box<dyn ProxyDatabaseTrait>>,\n    ) -> Result<DatabaseConnection, DbErr> {\n        Ok(\n            DatabaseConnectionType::ProxyDatabaseConnection(Arc::new(\n                ProxyDatabaseConnection::new(db_type, func),\n            ))\n            .into(),\n        )\n    }\n}\n\nimpl ProxyDatabaseConnection {\n    /// Create a connection to the [ProxyDatabase]\n    pub fn new(db_backend: DbBackend, funcs: Arc<Box<dyn ProxyDatabaseTrait>>) -> Self {\n        Self {\n            db_backend,\n            proxy: funcs.to_owned(),\n        }\n    }\n\n    /// Get the [DatabaseBackend](crate::DatabaseBackend) being used by the [ProxyDatabase]\n    pub fn get_database_backend(&self) -> DbBackend {\n        self.db_backend\n    }\n\n    /// Execute the SQL statement in the [ProxyDatabase]\n    #[instrument(level = \"trace\")]\n    pub async fn execute(&self, statement: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", statement);\n        Ok(self.proxy.execute(statement).await?.into())\n    }\n\n    /// Return one [QueryResult] if the query was successful\n    #[instrument(level = \"trace\")]\n    pub async fn query_one(&self, statement: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", statement);\n        let result = self.proxy.query(statement).await?;\n\n        if let Some(first) = result.first() {\n            return Ok(Some(QueryResult {\n                row: crate::QueryResultRow::Proxy(first.to_owned()),\n            }));\n        } else {\n            return Ok(None);\n        }\n    }\n\n    /// Return all [QueryResult]s if the query was successful\n    #[instrument(level = \"trace\")]\n    pub async fn query_all(&self, statement: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug_print!(\"{}\", statement);\n        let result = self.proxy.query(statement).await?;\n\n        Ok(result\n            .into_iter()\n            .map(|row| QueryResult {\n                row: crate::QueryResultRow::Proxy(row),\n            })\n            .collect())\n    }\n\n    /// Create a statement block  of SQL statements that execute together.\n    #[instrument(level = \"trace\")]\n    pub async fn begin(&self) {\n        self.proxy.begin().await\n    }\n\n    /// Commit a transaction atomically to the database\n    #[instrument(level = \"trace\")]\n    pub async fn commit(&self) {\n        self.proxy.commit().await\n    }\n\n    /// Roll back a faulty transaction\n    #[instrument(level = \"trace\")]\n    pub async fn rollback(&self) {\n        self.proxy.rollback().await\n    }\n\n    /// Start rollback a transaction\n    #[instrument(level = \"trace\")]\n    pub fn start_rollback(&self) {\n        self.proxy.start_rollback()\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub async fn ping(&self) -> Result<(), DbErr> {\n        self.proxy.ping().await\n    }\n}\n\nimpl\n    From<(\n        Arc<crate::ProxyDatabaseConnection>,\n        Statement,\n        Option<crate::metric::Callback>,\n    )> for crate::QueryStream\n{\n    fn from(\n        (conn, stmt, metric_callback): (\n            Arc<crate::ProxyDatabaseConnection>,\n            Statement,\n            Option<crate::metric::Callback>,\n        ),\n    ) -> Self {\n        crate::QueryStream::build(stmt, crate::InnerConnection::Proxy(conn), metric_callback)\n    }\n}\n\nimpl crate::DatabaseTransaction {\n    pub(crate) async fn new_proxy(\n        inner: Arc<crate::ProxyDatabaseConnection>,\n        metric_callback: Option<crate::metric::Callback>,\n    ) -> Result<crate::DatabaseTransaction, DbErr> {\n        use futures_util::lock::Mutex;\n        let backend = inner.get_database_backend();\n        Self::begin(\n            Arc::new(Mutex::new(crate::InnerConnection::Proxy(inner))),\n            backend,\n            metric_callback,\n            None,\n            None,\n            None,\n        )\n        .await\n    }\n}\n"
  },
  {
    "path": "src/driver/rusqlite.rs",
    "content": "use std::{\n    ops::Deref,\n    sync::{Arc, Mutex, MutexGuard, TryLockError},\n    time::{Duration, Instant},\n};\nuse tracing::{debug, instrument, warn};\n\npub use OwnedRow as RusqliteRow;\nuse rusqlite::{\n    CachedStatement, OpenFlags, Row,\n    types::{FromSql, FromSqlError, Value},\n};\npub use rusqlite::{\n    Connection as RusqliteConnection, Error as RusqliteError, types::Value as RusqliteOwnedValue,\n};\nuse sea_query_rusqlite::{RusqliteValue, RusqliteValues, rusqlite};\n\nuse crate::{\n    AccessMode, ColIdx, ConnectOptions, DatabaseConnection, DatabaseConnectionType,\n    DatabaseTransaction, InnerConnection, IsolationLevel, QueryStream, SqliteTransactionMode,\n    Statement, TransactionError, error::*, executor::*,\n};\n\n/// A helper class to connect to Rusqlite\n#[derive(Debug)]\npub struct RusqliteConnector;\n\nconst DEFAULT_ACQUIRE_TIMEOUT: Duration = Duration::from_secs(60);\n\n/// A shared SQLite connection for synchronous contexts.\n///\n/// Unlike sqlx's connection pool, which maintains multiple connections that can\n/// be checked out concurrently by different async tasks, this holds a single\n/// [`RusqliteConnection`] behind an `Arc<Mutex<State>>`. All callers contend on\n/// the same mutex; [`acquire`](Self::acquire) spins with `try_lock` until the\n/// mutex is available or the `acquire_timeout` deadline expires.\n///\n/// The connection can also be *loaned* out (via [`State::Loaned`]) for the\n/// duration of a transaction or streaming query, during which `acquire` will\n/// keep retrying until the loan is returned.\n#[derive(Clone)]\npub struct RusqliteSharedConnection {\n    pub(crate) conn: Arc<Mutex<State>>,\n    acquire_timeout: Duration,\n    metric_callback: Option<crate::metric::Callback>,\n}\n\n/// A loaned connection that supports nested transactions.\n///\n/// Created by [`RusqliteSharedConnection::loan`], which moves the underlying\n/// [`RusqliteConnection`] out of the shared mutex (leaving it in\n/// [`State::Loaned`]) so that a transaction or streaming query can hold it\n/// without blocking other callers on the mutex itself - they will still wait\n/// via `acquire`, but the mutex is not held for the entire duration.\n///\n/// On [`Drop`], the connection is returned to the shared mutex so that\n/// subsequent callers can acquire it again.\n///\n/// ## Transaction semantics\n///\n/// Nested transactions follow the same model as sqlx's SQLite driver:\n///\n/// | Depth | `begin`            | `commit`              | `rollback`              |\n/// |-------|--------------------|-----------------------|-------------------------|\n/// | 0     | `BEGIN`            | -                     | -                       |\n/// | 1     | `SAVEPOINT sp1`    | `COMMIT`              | `ROLLBACK`              |\n/// | 2     | `SAVEPOINT sp2`    | `RELEASE SAVEPOINT sp1` | `ROLLBACK TO sp1`     |\n/// | *n*   | `SAVEPOINT sp`*n*  | `RELEASE SAVEPOINT sp`*n-1* | `ROLLBACK TO sp`*n-1* |\n///\n/// ## Comparison with rusqlite's native `Transaction`\n///\n/// rusqlite's [`rusqlite::Transaction`] borrows `&mut Connection` for its\n/// entire lifetime. This makes it difficult to pass around, store in structs,\n/// or nest - each nested [`rusqlite::Savepoint`] borrows `&mut Transaction`,\n/// creating a tower of coupled lifetimes that the borrow checker enforces\n/// strictly.\n///\n/// Here, the connection is *moved* (loaned) into this struct as owned state,\n/// and nesting is tracked with a simple `transaction_depth` counter. This\n/// means transactions and savepoints can be started, committed, or rolled back\n/// through the same flat API without lifetime gymnastics. The connection is\n/// returned to the shared pool on [`Drop`], rather than relying on the borrow\n/// ending.\npub struct RusqliteInnerConnection {\n    conn: State,\n    loan: Arc<Mutex<State>>,\n    transaction_depth: u32,\n}\n\n#[derive(Debug)]\npub struct RusqliteExecResult {\n    pub(crate) rows_affected: u64,\n    pub(crate) last_insert_rowid: i64,\n}\n\n#[derive(Debug)]\npub struct OwnedRow {\n    pub columns: Vec<Arc<str>>,\n    pub values: Vec<Value>,\n}\n\n#[derive(Debug, Default)]\npub enum State {\n    Idle(RusqliteConnection),\n    Loaned,\n    #[default]\n    Disconnected,\n}\n\nimpl OwnedRow {\n    pub fn columns(&self) -> &[Arc<str>] {\n        &self.columns\n    }\n\n    pub fn from_row(columns: Vec<Arc<str>>, row: &Row) -> OwnedRow {\n        let mut values = Vec::new();\n\n        for i in 0..columns.len() {\n            let v: Value = row.get_unwrap(i);\n            values.push(v);\n        }\n\n        OwnedRow { columns, values }\n    }\n\n    pub fn try_get<T: FromSql, I: ColIdx>(&self, idx: I) -> Result<T, TryGetError> {\n        let (idx, col, value) = if let Some(idx) = idx.as_usize() {\n            (*idx, None, &self.values[*idx])\n        } else if let Some(name) = idx.as_str() {\n            if let Some(idx) = self.columns.iter().position(|c| c.deref() == name) {\n                (idx, Some(name), &self.values[idx])\n            } else {\n                return Err(TryGetError::Null(format!(\n                    \"column `{name}` does not exist in row\"\n                )));\n            }\n        } else {\n            unreachable!(\"ColIdx must be either usize or str\")\n        };\n        FromSql::column_result(value.into())\n            .map_err(|err| match err {\n                FromSqlError::OutOfRange(i) => RusqliteError::IntegralValueOutOfRange(idx, i),\n                FromSqlError::Other(err) => {\n                    RusqliteError::FromSqlConversionFailure(idx, value.data_type(), err)\n                }\n                FromSqlError::InvalidBlobSize { .. } => {\n                    RusqliteError::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))\n                }\n                // FromSqlError::InvalidType\n                _ => RusqliteError::InvalidColumnType(\n                    idx,\n                    col.map(|c| c.to_owned()).unwrap_or_default(),\n                    value.data_type(),\n                ),\n            })\n            .map_err(|err| TryGetError::DbErr(query_err(err)))\n    }\n}\n\nimpl std::fmt::Debug for RusqliteSharedConnection {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"RusqliteSharedConnection {{ conn: {:?} }}\", self.conn)\n    }\n}\n\nimpl std::fmt::Debug for RusqliteInnerConnection {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"RusqliteInnerConnection {{ conn: {:?} }}\", self.conn)\n    }\n}\n\nimpl From<RusqliteConnection> for RusqliteSharedConnection {\n    fn from(conn: RusqliteConnection) -> Self {\n        RusqliteSharedConnection {\n            conn: Arc::new(Mutex::new(State::Idle(conn))),\n            acquire_timeout: DEFAULT_ACQUIRE_TIMEOUT,\n            metric_callback: None,\n        }\n    }\n}\n\nimpl From<RusqliteSharedConnection> for DatabaseConnection {\n    fn from(conn: RusqliteSharedConnection) -> Self {\n        DatabaseConnectionType::RusqliteSharedConnection(conn).into()\n    }\n}\n\nimpl RusqliteConnector {\n    #[cfg(feature = \"mock\")]\n    /// Check if the URI provided corresponds to `sqlite:` for a SQLite database\n    pub fn accepts(string: &str) -> bool {\n        string.starts_with(\"sqlite:\")\n    }\n\n    /// Add configuration options for the SQLite database\n    #[instrument(level = \"trace\")]\n    pub fn connect(options: ConnectOptions) -> Result<DatabaseConnection, DbErr> {\n        let acquire_timeout = options.acquire_timeout.unwrap_or(DEFAULT_ACQUIRE_TIMEOUT);\n        // TODO handle disable_statement_logging\n        let after_conn = options.after_connect;\n\n        let raw = options\n            .url\n            .trim_start_matches(\"sqlite://\")\n            .trim_start_matches(\"sqlite:\");\n\n        let (path, mode) = match raw.find('?') {\n            Some(q) => {\n                let query = &raw[q + 1..];\n                let mut mode = None;\n                for kv in query.split('&') {\n                    if let Some(val) = kv.strip_prefix(\"mode=\") {\n                        mode = Some(val);\n                    } else if !kv.is_empty() {\n                        return Err(DbErr::Conn(RuntimeErr::Internal(format!(\n                            \"unsupported SQLite connection parameter: {kv}\"\n                        ))));\n                    }\n                }\n                (&raw[..q], mode)\n            }\n            None => (raw, None),\n        };\n\n        let conn = match mode {\n            None | Some(\"rwc\") => RusqliteConnection::open(path),\n            Some(\"ro\") => RusqliteConnection::open_with_flags(\n                path,\n                OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_NO_MUTEX,\n            ),\n            Some(\"rw\") => RusqliteConnection::open_with_flags(\n                path,\n                OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_NO_MUTEX,\n            ),\n            Some(other) => {\n                return Err(DbErr::Conn(RuntimeErr::Internal(format!(\n                    \"unknown SQLite mode: {other}\"\n                ))));\n            }\n        }\n        .map_err(conn_err)?;\n\n        let conn = RusqliteSharedConnection {\n            conn: Arc::new(Mutex::new(State::Idle(conn))),\n            acquire_timeout,\n            metric_callback: None,\n        };\n\n        #[cfg(feature = \"sqlite-use-returning-for-3_35\")]\n        {\n            let version = get_version(&conn)?;\n            super::sqlite::ensure_returning_version(&version)?;\n        }\n\n        // SQLx also enables this by default\n        conn.execute_unprepared(\"PRAGMA foreign_keys = ON\")?;\n        let conn: DatabaseConnection = conn.into();\n\n        if let Some(cb) = after_conn {\n            cb(conn.clone())?;\n        }\n\n        Ok(conn)\n    }\n}\n\n// impl RusqliteConnector {\n//     /// Convert a Rusqlite connection to a [DatabaseConnection]\n//     pub fn from_rusqlite_connection(conn: RusqliteConnection) -> DatabaseConnection {\n//         let conn: RusqliteSharedConnection = conn.into();\n//         conn.into()\n//     }\n// }\n\nimpl RusqliteSharedConnection {\n    pub fn acquire(&self) -> Result<MutexGuard<'_, State>, DbErr> {\n        let deadline = Instant::now() + self.acquire_timeout;\n        loop {\n            match self.conn.try_lock() {\n                Ok(state) => match *state {\n                    State::Idle(_) => return Ok(state),\n                    State::Loaned => (), // borrowed for streaming or transaction\n                    State::Disconnected => {\n                        return Err(DbErr::ConnectionAcquire(ConnAcquireErr::ConnectionClosed));\n                    }\n                },\n                Err(TryLockError::WouldBlock) => (),\n                Err(TryLockError::Poisoned(_)) => {\n                    return Err(DbErr::ConnectionAcquire(ConnAcquireErr::ConnectionClosed));\n                }\n            }\n            if Instant::now() >= deadline {\n                return Err(DbErr::ConnectionAcquire(ConnAcquireErr::Timeout));\n            }\n            std::thread::yield_now();\n        }\n    }\n\n    fn loan(&self) -> Result<RusqliteInnerConnection, DbErr> {\n        let conn = {\n            let mut conn = self.acquire()?;\n            conn.loan()\n        };\n        Ok(RusqliteInnerConnection {\n            conn: State::Idle(conn),\n            loan: self.conn.clone(),\n            transaction_depth: 0,\n        })\n    }\n\n    /// Execute a [Statement] on a SQLite backend\n    #[instrument(level = \"trace\")]\n    pub fn execute(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(&stmt);\n        let conn = self.acquire()?;\n        let conn = conn.conn();\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match conn.execute(&stmt.sql, &*values.as_params()) {\n                Ok(rows_affected) => Ok(RusqliteExecResult {\n                    rows_affected: rows_affected as u64,\n                    last_insert_rowid: conn.last_insert_rowid(),\n                }\n                .into()),\n                Err(err) => Err(exec_err(err)),\n            }\n        })\n    }\n\n    /// Execute an unprepared SQL statement on a SQLite backend\n    #[instrument(level = \"trace\")]\n    pub fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        debug!(\"{}\", sql);\n\n        let conn = self.acquire()?;\n        let conn = conn.conn();\n        match conn.execute_batch(sql) {\n            Ok(()) => Ok(RusqliteExecResult {\n                rows_affected: conn.changes(),\n                last_insert_rowid: conn.last_insert_rowid(),\n            }\n            .into()),\n            Err(err) => Err(exec_err(err)),\n        }\n    }\n\n    /// Get one result from a SQL query. Returns [Option::None] if no match was found\n    #[instrument(level = \"trace\")]\n    pub fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(&stmt);\n        let conn = self.acquire()?;\n        let conn = conn.conn();\n        let mut sql = conn.prepare_cached(&stmt.sql).map_err(query_err)?;\n        let columns: Vec<Arc<str>> = column_names(&sql);\n\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match sql.query(&*values.as_params()) {\n                Ok(mut rows) => {\n                    let mut out = None;\n                    if let Some(row) = rows.next().map_err(query_err)? {\n                        out = Some(OwnedRow::from_row(columns.clone(), row).into());\n                    }\n                    Ok(out)\n                }\n                Err(err) => Err(query_err(err)),\n            }\n        })\n    }\n\n    /// Get the results of a query returning them as a Vec<[QueryResult]>\n    #[instrument(level = \"trace\")]\n    pub fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(&stmt);\n        let conn = self.acquire()?;\n        let conn = conn.conn();\n        let mut sql = conn.prepare_cached(&stmt.sql).map_err(query_err)?;\n        let columns: Vec<Arc<str>> = column_names(&sql);\n\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match sql.query(&*values.as_params()) {\n                Ok(mut rows) => {\n                    let mut out = Vec::new();\n                    while let Some(row) = rows.next().map_err(query_err)? {\n                        out.push(OwnedRow::from_row(columns.clone(), row).into());\n                    }\n                    Ok(out)\n                }\n                Err(err) => Err(query_err(err)),\n            }\n        })\n    }\n\n    /// Stream the results of executing a SQL query\n    #[instrument(level = \"trace\")]\n    pub fn stream(&self, stmt: Statement) -> Result<QueryStream, DbErr> {\n        debug!(\"{}\", stmt);\n\n        Ok(QueryStream::build(\n            stmt,\n            InnerConnection::Rusqlite(self.loan()?),\n            self.metric_callback.clone(),\n        ))\n    }\n\n    /// Bundle a set of SQL statements that execute together.\n    #[instrument(level = \"trace\")]\n    pub fn begin(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n        sqlite_transaction_mode: Option<SqliteTransactionMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        let conn = self.loan()?;\n        DatabaseTransaction::begin(\n            Arc::new(Mutex::new(InnerConnection::Rusqlite(conn))),\n            crate::DbBackend::Sqlite,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n            sqlite_transaction_mode,\n        )\n    }\n\n    /// Create a SQLite transaction\n    #[instrument(level = \"trace\", skip(callback))]\n    pub fn transaction<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'b> FnOnce(&'b DatabaseTransaction) -> Result<T, E>,\n        E: std::fmt::Display + std::fmt::Debug,\n    {\n        self.begin(isolation_level, access_mode, None)\n            .map_err(|e| TransactionError::Connection(e))?\n            .run(callback)\n    }\n\n    pub(crate) fn set_metric_callback<F>(&mut self, callback: F)\n    where\n        F: Fn(&crate::metric::Info<'_>) + 'static,\n    {\n        self.metric_callback = Some(Arc::new(callback));\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub fn ping(&self) -> Result<(), DbErr> {\n        let conn = self.acquire()?;\n        let conn = conn.conn();\n        let mut stmt = conn.prepare(\"SELECT 1\").map_err(conn_err)?;\n        match stmt.query([]) {\n            Ok(_) => Ok(()),\n            Err(err) => Err(conn_err(err)),\n        }\n    }\n\n    /// Explicitly close the SQLite connection.\n    /// See [`Self::close_by_ref`] for usage with references.\n    pub fn close(self) -> Result<(), DbErr> {\n        self.close_by_ref()\n    }\n\n    /// Explicitly close the SQLite connection\n    pub fn close_by_ref(&self) -> Result<(), DbErr> {\n        let mut conn = self.acquire()?;\n        *conn = State::Disconnected;\n        Ok(())\n    }\n}\n\nimpl RusqliteInnerConnection {\n    #[instrument(level = \"trace\", skip(metric_callback))]\n    pub fn execute(\n        &self,\n        stmt: Statement,\n        metric_callback: &Option<crate::metric::Callback>,\n    ) -> Result<ExecResult, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(&stmt);\n        let conn = self.conn.conn();\n        crate::metric::metric!(metric_callback, &stmt, {\n            match conn.execute(&stmt.sql, &*values.as_params()) {\n                Ok(rows_affected) => Ok(RusqliteExecResult {\n                    rows_affected: rows_affected as u64,\n                    last_insert_rowid: conn.last_insert_rowid(),\n                }\n                .into()),\n                Err(err) => Err(exec_err(err)),\n            }\n        })\n    }\n\n    #[instrument(level = \"trace\")]\n    pub(crate) fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        debug!(\"{}\", sql);\n\n        let conn = self.conn.conn();\n        match conn.execute_batch(sql) {\n            Ok(()) => Ok(RusqliteExecResult {\n                rows_affected: conn.changes(),\n                last_insert_rowid: conn.last_insert_rowid(),\n            }\n            .into()),\n            Err(err) => Err(exec_err(err)),\n        }\n    }\n\n    #[instrument(level = \"trace\", skip(metric_callback))]\n    pub fn query_one(\n        &self,\n        stmt: Statement,\n        metric_callback: &Option<crate::metric::Callback>,\n    ) -> Result<Option<QueryResult>, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(&stmt);\n        let conn = self.conn.conn();\n        let mut sql = conn.prepare_cached(&stmt.sql).map_err(query_err)?;\n        let columns: Vec<Arc<str>> = column_names(&sql);\n\n        crate::metric::metric!(metric_callback, &stmt, {\n            match sql.query(&*values.as_params()) {\n                Ok(mut rows) => {\n                    let mut out = None;\n                    if let Some(row) = rows.next().map_err(query_err)? {\n                        out = Some(OwnedRow::from_row(columns.clone(), row).into());\n                    }\n                    Ok(out)\n                }\n                Err(err) => Err(query_err(err)),\n            }\n        })\n    }\n\n    #[instrument(level = \"trace\", skip(metric_callback))]\n    pub fn query_all(\n        &self,\n        stmt: Statement,\n        metric_callback: &Option<crate::metric::Callback>,\n    ) -> Result<Vec<QueryResult>, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(&stmt);\n        let conn = self.conn.conn();\n        let mut sql = conn.prepare_cached(&stmt.sql).map_err(query_err)?;\n        let columns: Vec<Arc<str>> = column_names(&sql);\n\n        crate::metric::metric!(metric_callback, &stmt, {\n            match sql.query(&*values.as_params()) {\n                Ok(mut rows) => {\n                    let mut out = Vec::new();\n                    while let Some(row) = rows.next().map_err(query_err)? {\n                        out.push(OwnedRow::from_row(columns.clone(), row).into());\n                    }\n                    Ok(out)\n                }\n                Err(err) => Err(query_err(err)),\n            }\n        })\n    }\n\n    #[instrument(level = \"trace\")]\n    pub(crate) fn stream(&self, stmt: &Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug!(\"{}\", stmt);\n\n        let values = sql_values(stmt);\n        let conn = self.conn.conn();\n        let mut sql = conn.prepare_cached(&stmt.sql).map_err(query_err)?;\n        let columns: Vec<Arc<str>> = column_names(&sql);\n\n        let rows = match sql.query(&*values.as_params()) {\n            Ok(mut rows) => {\n                let mut out = Vec::new();\n                while let Some(row) = rows.next().map_err(query_err)? {\n                    out.push(OwnedRow::from_row(columns.clone(), row).into());\n                }\n                out\n            }\n            Err(err) => return Err(query_err(err)),\n        };\n\n        Ok(rows)\n    }\n\n    #[instrument(level = \"trace\")]\n    pub(crate) fn begin(\n        &mut self,\n        sqlite_transaction_mode: Option<SqliteTransactionMode>,\n    ) -> Result<(), DbErr> {\n        if self.transaction_depth == 0 {\n            match sqlite_transaction_mode {\n                Some(mode) => {\n                    self.execute_unprepared(&format!(\"BEGIN {}\", mode.sqlite_keyword()))?\n                }\n                None => self.execute_unprepared(\"BEGIN\")?,\n            };\n        } else {\n            self.execute_unprepared(&format!(\"SAVEPOINT sp{}\", self.transaction_depth))?;\n        }\n        self.transaction_depth += 1;\n        Ok(())\n    }\n\n    #[instrument(level = \"trace\")]\n    pub(crate) fn commit(&mut self) -> Result<(), DbErr> {\n        if self.transaction_depth == 1 {\n            self.execute_unprepared(\"COMMIT\")?;\n        } else {\n            self.execute_unprepared(&format!(\n                \"RELEASE SAVEPOINT sp{}\",\n                self.transaction_depth - 1\n            ))?;\n        }\n        self.transaction_depth -= 1;\n        Ok(())\n    }\n\n    #[instrument(level = \"trace\")]\n    pub(crate) fn rollback(&mut self) -> Result<(), DbErr> {\n        if self.transaction_depth == 1 {\n            self.execute_unprepared(\"ROLLBACK\")?;\n        } else {\n            self.execute_unprepared(&format!(\"ROLLBACK TO sp{}\", self.transaction_depth - 1))?;\n        }\n        self.transaction_depth -= 1;\n        Ok(())\n    }\n\n    #[instrument(level = \"trace\")]\n    pub(crate) fn start_rollback(&mut self) -> Result<(), DbErr> {\n        if self.transaction_depth > 0 {\n            self.rollback()?;\n        }\n        Ok(())\n    }\n}\n\nimpl Drop for RusqliteInnerConnection {\n    fn drop(&mut self) {\n        let mut loan = self.loan.lock().unwrap();\n        loan.return_(self.conn.loan());\n    }\n}\n\nimpl State {\n    fn conn(&self) -> &RusqliteConnection {\n        match self {\n            State::Idle(conn) => conn,\n            _ => panic!(\"No connection\"),\n        }\n    }\n\n    fn loan(&mut self) -> RusqliteConnection {\n        let mut conn = State::Loaned;\n        std::mem::swap(&mut conn, self);\n        match conn {\n            State::Idle(conn) => conn,\n            _ => panic!(\"No connection\"),\n        }\n    }\n\n    fn return_(&mut self, conn: RusqliteConnection) {\n        *self = State::Idle(conn);\n    }\n}\n\nimpl From<OwnedRow> for QueryResult {\n    fn from(row: OwnedRow) -> QueryResult {\n        QueryResult {\n            row: QueryResultRow::Rusqlite(row),\n        }\n    }\n}\n\nimpl From<RusqliteExecResult> for ExecResult {\n    fn from(result: RusqliteExecResult) -> ExecResult {\n        ExecResult {\n            result: ExecResultHolder::Rusqlite(result),\n        }\n    }\n}\n\npub(crate) fn sql_values(stmt: &Statement) -> RusqliteValues {\n    let values = match &stmt.values {\n        Some(values) => values.iter().cloned().map(RusqliteValue).collect(),\n        None => Vec::new(),\n    };\n    RusqliteValues(values)\n}\n\nfn column_names(sql: &CachedStatement) -> Vec<Arc<str>> {\n    sql.column_names()\n        .into_iter()\n        .map(|r| Arc::from(r))\n        .collect()\n}\n\n#[cfg(feature = \"sqlite-use-returning-for-3_35\")]\nfn get_version(conn: &RusqliteSharedConnection) -> Result<String, DbErr> {\n    let stmt = Statement {\n        sql: \"SELECT sqlite_version()\".to_string(),\n        values: None,\n        db_backend: crate::DbBackend::Sqlite,\n    };\n    conn.query_one(stmt)?\n        .ok_or_else(|| {\n            DbErr::Conn(RuntimeErr::Internal(\n                \"Error reading SQLite version\".to_string(),\n            ))\n        })?\n        .try_get_by(0)\n}\n\nfn conn_err(err: RusqliteError) -> DbErr {\n    DbErr::Conn(RuntimeErr::Rusqlite(err.into()))\n}\n\nfn exec_err(err: RusqliteError) -> DbErr {\n    DbErr::Exec(RuntimeErr::Rusqlite(err.into()))\n}\n\nfn query_err(err: RusqliteError) -> DbErr {\n    DbErr::Query(RuntimeErr::Rusqlite(err.into()))\n}\n"
  },
  {
    "path": "src/driver/sqlite.rs",
    "content": "use crate::error::{DbErr, RuntimeErr};\n\n#[cfg(feature = \"sqlite-use-returning-for-3_35\")]\npub fn ensure_returning_version(version: &str) -> Result<(), DbErr> {\n    let mut parts = version.trim().split('.').map(|part| {\n        part.parse::<u32>().map_err(|_| {\n            DbErr::Conn(RuntimeErr::Internal(\n                \"Error parsing SQLite version\".to_string(),\n            ))\n        })\n    });\n\n    let mut extract_next = || {\n        parts.next().transpose().and_then(|part| {\n            part.ok_or_else(|| {\n                DbErr::Conn(RuntimeErr::Internal(\"SQLite version too short\".to_string()))\n            })\n        })\n    };\n\n    let major = extract_next()?;\n    let minor = extract_next()?;\n\n    if major > 3 || (major == 3 && minor >= 35) {\n        Ok(())\n    } else {\n        Err(DbErr::BackendNotSupported {\n            db: \"SQLite\",\n            ctx: \"SQLite version does not support returning\",\n        })\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[cfg(feature = \"sqlite-use-returning-for-3_35\")]\n    #[test]\n    fn test_ensure_returning_version() {\n        assert!(ensure_returning_version(\"\").is_err());\n        assert!(ensure_returning_version(\".\").is_err());\n        assert!(ensure_returning_version(\".a\").is_err());\n        assert!(ensure_returning_version(\".4.9\").is_err());\n        assert!(ensure_returning_version(\"a\").is_err());\n        assert!(ensure_returning_version(\"1.\").is_err());\n        assert!(ensure_returning_version(\"1.a\").is_err());\n\n        assert!(ensure_returning_version(\"1.1\").is_err());\n        assert!(ensure_returning_version(\"1.0.\").is_err());\n        assert!(ensure_returning_version(\"1.0.0\").is_err());\n        assert!(ensure_returning_version(\"2.0.0\").is_err());\n        assert!(ensure_returning_version(\"3.34.0\").is_err());\n        assert!(ensure_returning_version(\"3.34.999\").is_err());\n\n        // valid version\n        assert!(ensure_returning_version(\"3.35.0\").is_ok());\n        assert!(ensure_returning_version(\"3.35.1\").is_ok());\n        assert!(ensure_returning_version(\"3.36.0\").is_ok());\n        assert!(ensure_returning_version(\"4.0.0\").is_ok());\n        assert!(ensure_returning_version(\"99.0.0\").is_ok());\n    }\n}\n"
  },
  {
    "path": "src/driver/sqlx_common.rs",
    "content": "use crate::{ConnAcquireErr, ConnectOptions, DbErr, RuntimeErr};\n\n/// Converts an [sqlx::error] execution error to a [DbErr]\npub fn sqlx_error_to_exec_err(err: sqlx::Error) -> DbErr {\n    DbErr::Exec(RuntimeErr::SqlxError(err.into()))\n}\n\n/// Converts an [sqlx::error] query error to a [DbErr]\npub fn sqlx_error_to_query_err(err: sqlx::Error) -> DbErr {\n    DbErr::Query(RuntimeErr::SqlxError(err.into()))\n}\n\n/// Converts an [sqlx::error] connection error to a [DbErr]\npub fn sqlx_error_to_conn_err(err: sqlx::Error) -> DbErr {\n    DbErr::Conn(RuntimeErr::SqlxError(err.into()))\n}\n\n/// Converts an [sqlx::error] error to a [DbErr]\npub fn sqlx_map_err_ignore_not_found<T: std::fmt::Debug>(\n    err: Result<Option<T>, sqlx::Error>,\n) -> Result<Option<T>, DbErr> {\n    if let Err(sqlx::Error::RowNotFound) = err {\n        Ok(None)\n    } else {\n        err.map_err(sqlx_error_to_query_err)\n    }\n}\n\n/// Converts an [sqlx::error] error to a [DbErr]\npub fn sqlx_conn_acquire_err(sqlx_err: sqlx::Error) -> DbErr {\n    match sqlx_err {\n        sqlx::Error::PoolTimedOut => DbErr::ConnectionAcquire(ConnAcquireErr::Timeout),\n        sqlx::Error::PoolClosed => DbErr::ConnectionAcquire(ConnAcquireErr::ConnectionClosed),\n        _ => DbErr::Conn(RuntimeErr::SqlxError(sqlx_err.into())),\n    }\n}\n\nimpl ConnectOptions {\n    /// Convert [ConnectOptions] into [sqlx::pool::PoolOptions]\n    pub fn sqlx_pool_options<DB>(self) -> sqlx::pool::PoolOptions<DB>\n    where\n        DB: sqlx::Database,\n    {\n        let mut opt = sqlx::pool::PoolOptions::new();\n        if let Some(max_connections) = self.max_connections {\n            opt = opt.max_connections(max_connections);\n        }\n        if let Some(min_connections) = self.min_connections {\n            opt = opt.min_connections(min_connections);\n        }\n        if let Some(connect_timeout) = self.connect_timeout {\n            opt = opt.acquire_timeout(connect_timeout);\n        }\n        if let Some(idle_timeout) = self.idle_timeout {\n            opt = opt.idle_timeout(idle_timeout);\n        }\n        if let Some(acquire_timeout) = self.acquire_timeout {\n            opt = opt.acquire_timeout(acquire_timeout);\n        }\n        if let Some(max_lifetime) = self.max_lifetime {\n            opt = opt.max_lifetime(max_lifetime);\n        }\n        opt = opt.test_before_acquire(self.test_before_acquire);\n        opt\n    }\n}\n"
  },
  {
    "path": "src/driver/sqlx_mysql.rs",
    "content": "use futures_util::lock::Mutex;\nuse log::LevelFilter;\nuse sea_query::Values;\nuse std::{future::Future, pin::Pin, sync::Arc};\n\nuse sqlx::{\n    Connection, Executor, MySql, MySqlPool,\n    mysql::{MySqlConnectOptions, MySqlQueryResult, MySqlRow},\n    pool::PoolConnection,\n};\n\nuse sea_query_sqlx::SqlxValues;\nuse tracing::instrument;\n\nuse crate::{\n    AccessMode, ConnectOptions, DatabaseConnection, DatabaseConnectionType, DatabaseTransaction,\n    DbBackend, IsolationLevel, QueryStream, Statement, TransactionError, debug_print, error::*,\n    executor::*,\n};\n\nuse super::sqlx_common::*;\n\n/// Defines the [sqlx::mysql] connector\n#[derive(Debug)]\npub struct SqlxMySqlConnector;\n\n/// Defines a sqlx MySQL pool\n#[derive(Clone)]\npub struct SqlxMySqlPoolConnection {\n    pub(crate) pool: MySqlPool,\n    metric_callback: Option<crate::metric::Callback>,\n}\n\nimpl std::fmt::Debug for SqlxMySqlPoolConnection {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"SqlxMySqlPoolConnection {{ pool: {:?} }}\", self.pool)\n    }\n}\n\nimpl From<MySqlPool> for SqlxMySqlPoolConnection {\n    fn from(pool: MySqlPool) -> Self {\n        SqlxMySqlPoolConnection {\n            pool,\n            metric_callback: None,\n        }\n    }\n}\n\nimpl From<MySqlPool> for DatabaseConnection {\n    fn from(pool: MySqlPool) -> Self {\n        DatabaseConnectionType::SqlxMySqlPoolConnection(pool.into()).into()\n    }\n}\n\nimpl SqlxMySqlConnector {\n    /// Check if the URI provided corresponds to `mysql://` for a MySQL database\n    pub fn accepts(string: &str) -> bool {\n        string.starts_with(\"mysql://\") && string.parse::<MySqlConnectOptions>().is_ok()\n    }\n\n    /// Add configuration options for the MySQL database\n    #[instrument(level = \"trace\")]\n    pub async fn connect(options: ConnectOptions) -> Result<DatabaseConnection, DbErr> {\n        let mut sqlx_opts = options\n            .url\n            .parse::<MySqlConnectOptions>()\n            .map_err(sqlx_error_to_conn_err)?;\n        use sqlx::ConnectOptions;\n        if !options.sqlx_logging {\n            sqlx_opts = sqlx_opts.disable_statement_logging();\n        } else {\n            sqlx_opts = sqlx_opts.log_statements(options.sqlx_logging_level);\n            if options.sqlx_slow_statements_logging_level != LevelFilter::Off {\n                sqlx_opts = sqlx_opts.log_slow_statements(\n                    options.sqlx_slow_statements_logging_level,\n                    options.sqlx_slow_statements_logging_threshold,\n                );\n            }\n        }\n\n        if let Some(f) = &options.mysql_opts_fn {\n            sqlx_opts = f(sqlx_opts);\n        }\n\n        let after_connect = options.after_connect.clone();\n\n        let pool = if options.connect_lazy {\n            options.sqlx_pool_options().connect_lazy_with(sqlx_opts)\n        } else {\n            options\n                .sqlx_pool_options()\n                .connect_with(sqlx_opts)\n                .await\n                .map_err(sqlx_error_to_conn_err)?\n        };\n\n        let conn: DatabaseConnection =\n            DatabaseConnectionType::SqlxMySqlPoolConnection(SqlxMySqlPoolConnection {\n                pool,\n                metric_callback: None,\n            })\n            .into();\n\n        if let Some(cb) = after_connect {\n            cb(conn.clone()).await?;\n        }\n\n        Ok(conn)\n    }\n}\n\nimpl SqlxMySqlConnector {\n    /// Instantiate a sqlx pool connection to a [DatabaseConnection]\n    pub fn from_sqlx_mysql_pool(pool: MySqlPool) -> DatabaseConnection {\n        DatabaseConnectionType::SqlxMySqlPoolConnection(SqlxMySqlPoolConnection {\n            pool,\n            metric_callback: None,\n        })\n        .into()\n    }\n}\n\nimpl SqlxMySqlPoolConnection {\n    /// Execute a [Statement] on a MySQL backend\n    #[instrument(level = \"trace\")]\n    pub async fn execute(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.execute(&mut *conn).await {\n                Ok(res) => Ok(res.into()),\n                Err(err) => Err(sqlx_error_to_exec_err(err)),\n            }\n        })\n    }\n\n    /// Execute an unprepared SQL statement on a MySQL backend\n    #[instrument(level = \"trace\")]\n    pub async fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", sql);\n\n        let conn = &mut self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        match conn.execute(sql).await {\n            Ok(res) => Ok(res.into()),\n            Err(err) => Err(sqlx_error_to_exec_err(err)),\n        }\n    }\n\n    /// Get one result from a SQL query. Returns [Option::None] if no match was found\n    #[instrument(level = \"trace\")]\n    pub async fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.fetch_one(&mut *conn).await {\n                Ok(row) => Ok(Some(row.into())),\n                Err(err) => match err {\n                    sqlx::Error::RowNotFound => Ok(None),\n                    _ => Err(sqlx_error_to_query_err(err)),\n                },\n            }\n        })\n    }\n\n    /// Get the results of a query returning them as a Vec<[QueryResult]>\n    #[instrument(level = \"trace\")]\n    pub async fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.fetch_all(&mut *conn).await {\n                Ok(rows) => Ok(rows.into_iter().map(|r| r.into()).collect()),\n                Err(err) => Err(sqlx_error_to_query_err(err)),\n            }\n        })\n    }\n\n    /// Stream the results of executing a SQL query\n    #[instrument(level = \"trace\")]\n    pub async fn stream(&self, stmt: Statement) -> Result<QueryStream, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        Ok(QueryStream::from((\n            conn,\n            stmt,\n            self.metric_callback.clone(),\n        )))\n    }\n\n    /// Bundle a set of SQL statements that execute together.\n    #[instrument(level = \"trace\")]\n    pub async fn begin(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        let conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        DatabaseTransaction::new_mysql(\n            conn,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n        )\n        .await\n    }\n\n    /// Create a MySQL transaction\n    #[instrument(level = \"trace\", skip(callback))]\n    pub async fn transaction<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'b> FnOnce(\n                &'b DatabaseTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'b>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        let conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        let transaction = DatabaseTransaction::new_mysql(\n            conn,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n        )\n        .await\n        .map_err(|e| TransactionError::Connection(e))?;\n        transaction.run(callback).await\n    }\n\n    pub(crate) fn set_metric_callback<F>(&mut self, callback: F)\n    where\n        F: Fn(&crate::metric::Info<'_>) + Send + Sync + 'static,\n    {\n        self.metric_callback = Some(Arc::new(callback));\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub async fn ping(&self) -> Result<(), DbErr> {\n        let conn = &mut self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        match conn.ping().await {\n            Ok(_) => Ok(()),\n            Err(err) => Err(sqlx_error_to_conn_err(err)),\n        }\n    }\n\n    /// Explicitly close the MySQL connection.\n    /// See [`Self::close_by_ref`] for usage with references.\n    pub async fn close(self) -> Result<(), DbErr> {\n        self.close_by_ref().await\n    }\n\n    /// Explicitly close the MySQL connection\n    pub async fn close_by_ref(&self) -> Result<(), DbErr> {\n        self.pool.close().await;\n        Ok(())\n    }\n}\n\nimpl From<MySqlRow> for QueryResult {\n    fn from(row: MySqlRow) -> QueryResult {\n        QueryResult {\n            row: QueryResultRow::SqlxMySql(row),\n        }\n    }\n}\n\nimpl From<MySqlQueryResult> for ExecResult {\n    fn from(result: MySqlQueryResult) -> ExecResult {\n        ExecResult {\n            result: ExecResultHolder::SqlxMySql(result),\n        }\n    }\n}\n\npub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, MySql, SqlxValues> {\n    let values = stmt\n        .values\n        .as_ref()\n        .map_or(Values(Vec::new()), |values| values.clone());\n    sqlx::query_with(&stmt.sql, SqlxValues(values))\n}\n\npub(crate) async fn set_transaction_config(\n    conn: &mut PoolConnection<MySql>,\n    isolation_level: Option<IsolationLevel>,\n    access_mode: Option<AccessMode>,\n) -> Result<(), DbErr> {\n    let mut settings = Vec::new();\n\n    if let Some(isolation_level) = isolation_level {\n        settings.push(format!(\"ISOLATION LEVEL {isolation_level}\"));\n    }\n\n    if let Some(access_mode) = access_mode {\n        settings.push(access_mode.to_string());\n    }\n\n    if !settings.is_empty() {\n        let stmt = Statement {\n            sql: format!(\"SET TRANSACTION {}\", settings.join(\", \")),\n            values: None,\n            db_backend: DbBackend::MySql,\n        };\n        let query = sqlx_query(&stmt);\n        conn.execute(query).await.map_err(sqlx_error_to_exec_err)?;\n    }\n    Ok(())\n}\n\nimpl\n    From<(\n        PoolConnection<sqlx::MySql>,\n        Statement,\n        Option<crate::metric::Callback>,\n    )> for crate::QueryStream\n{\n    fn from(\n        (conn, stmt, metric_callback): (\n            PoolConnection<sqlx::MySql>,\n            Statement,\n            Option<crate::metric::Callback>,\n        ),\n    ) -> Self {\n        crate::QueryStream::build(stmt, crate::InnerConnection::MySql(conn), metric_callback)\n    }\n}\n\nimpl crate::DatabaseTransaction {\n    pub(crate) async fn new_mysql(\n        inner: PoolConnection<sqlx::MySql>,\n        metric_callback: Option<crate::metric::Callback>,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<crate::DatabaseTransaction, DbErr> {\n        Self::begin(\n            Arc::new(Mutex::new(crate::InnerConnection::MySql(inner))),\n            crate::DbBackend::MySql,\n            metric_callback,\n            isolation_level,\n            access_mode,\n            None,\n        )\n        .await\n    }\n}\n\n#[cfg(feature = \"proxy\")]\npub(crate) fn from_sqlx_mysql_row_to_proxy_row(row: &sqlx::mysql::MySqlRow) -> crate::ProxyRow {\n    // https://docs.rs/sqlx-mysql/0.7.2/src/sqlx_mysql/protocol/text/column.rs.html\n    // https://docs.rs/sqlx-mysql/0.7.2/sqlx_mysql/types/index.html\n    use sea_query::Value;\n    use sqlx::{Column, Row, TypeInfo};\n    crate::ProxyRow {\n        values: row\n            .columns()\n            .iter()\n            .map(|c| {\n                (\n                    c.name().to_string(),\n                    match c.type_info().name() {\n                        \"TINYINT(1)\" | \"BOOLEAN\" => {\n                            Value::Bool(row.try_get(c.ordinal()).expect(\"Failed to get boolean\"))\n                        }\n                        \"TINYINT UNSIGNED\" => Value::TinyUnsigned(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get unsigned tiny integer\"),\n                        ),\n                        \"SMALLINT UNSIGNED\" => Value::SmallUnsigned(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get unsigned small integer\"),\n                        ),\n                        \"INT UNSIGNED\" => Value::Unsigned(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get unsigned integer\"),\n                        ),\n                        \"MEDIUMINT UNSIGNED\" | \"BIGINT UNSIGNED\" => Value::BigUnsigned(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get unsigned big integer\"),\n                        ),\n                        \"TINYINT\" => Value::TinyInt(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get tiny integer\"),\n                        ),\n                        \"SMALLINT\" => Value::SmallInt(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get small integer\"),\n                        ),\n                        \"INT\" => {\n                            Value::Int(row.try_get(c.ordinal()).expect(\"Failed to get integer\"))\n                        }\n                        \"MEDIUMINT\" | \"BIGINT\" => Value::BigInt(\n                            row.try_get(c.ordinal()).expect(\"Failed to get big integer\"),\n                        ),\n                        \"FLOAT\" => {\n                            Value::Float(row.try_get(c.ordinal()).expect(\"Failed to get float\"))\n                        }\n                        \"DOUBLE\" => {\n                            Value::Double(row.try_get(c.ordinal()).expect(\"Failed to get double\"))\n                        }\n\n                        \"BIT\" | \"BINARY\" | \"VARBINARY\" | \"TINYBLOB\" | \"BLOB\" | \"MEDIUMBLOB\"\n                        | \"LONGBLOB\" => Value::Bytes(\n                            row.try_get::<Option<Vec<u8>>, _>(c.ordinal())\n                                .expect(\"Failed to get bytes\")\n                                .map(Box::new),\n                        ),\n\n                        \"CHAR\" | \"VARCHAR\" | \"TINYTEXT\" | \"TEXT\" | \"MEDIUMTEXT\" | \"LONGTEXT\" => {\n                            Value::String(\n                                row.try_get::<Option<String>, _>(c.ordinal())\n                                    .expect(\"Failed to get string\")\n                                    .map(Box::new),\n                            )\n                        }\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIMESTAMP\" => Value::ChronoDateTimeUtc(\n                            row.try_get::<Option<chrono::DateTime<chrono::Utc>>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamp\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIMESTAMP\" => Value::TimeDateTime(\n                            row.try_get::<Option<time::PrimitiveDateTime>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamp\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"DATE\" => Value::ChronoDate(\n                            row.try_get::<Option<chrono::NaiveDate>, _>(c.ordinal())\n                                .expect(\"Failed to get date\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"DATE\" => Value::TimeDate(\n                            row.try_get::<Option<time::Date>, _>(c.ordinal())\n                                .expect(\"Failed to get date\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIME\" => Value::ChronoTime(\n                            row.try_get::<Option<chrono::NaiveTime>, _>(c.ordinal())\n                                .expect(\"Failed to get time\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIME\" => Value::TimeTime(\n                            row.try_get::<Option<time::Time>, _>(c.ordinal())\n                                .expect(\"Failed to get time\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"DATETIME\" => Value::ChronoDateTime(\n                            row.try_get::<Option<chrono::NaiveDateTime>, _>(c.ordinal())\n                                .expect(\"Failed to get datetime\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"DATETIME\" => Value::TimeDateTime(\n                            row.try_get::<Option<time::PrimitiveDateTime>, _>(c.ordinal())\n                                .expect(\"Failed to get datetime\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"YEAR\" => Value::ChronoDate(\n                            row.try_get::<Option<chrono::NaiveDate>, _>(c.ordinal())\n                                .expect(\"Failed to get year\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"YEAR\" => Value::TimeDate(\n                            row.try_get::<Option<time::Date>, _>(c.ordinal())\n                                .expect(\"Failed to get year\")\n                                .map(Box::new),\n                        ),\n\n                        \"ENUM\" | \"SET\" | \"GEOMETRY\" => Value::String(\n                            row.try_get::<Option<String>, _>(c.ordinal())\n                                .expect(\"Failed to get serialized string\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-bigdecimal\")]\n                        \"DECIMAL\" => Value::BigDecimal(\n                            row.try_get::<Option<bigdecimal::BigDecimal>, _>(c.ordinal())\n                                .expect(\"Failed to get decimal\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-rust_decimal\",\n                            not(feature = \"with-bigdecimal\")\n                        ))]\n                        \"DECIMAL\" => Value::Decimal(\n                            row.try_get::<Option<rust_decimal::Decimal>, _>(c.ordinal())\n                                .expect(\"Failed to get decimal\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-json\")]\n                        \"JSON\" => Value::Json(\n                            row.try_get::<Option<serde_json::Value>, _>(c.ordinal())\n                                .expect(\"Failed to get json\")\n                                .map(Box::new),\n                        ),\n\n                        _ => unreachable!(\"Unknown column type: {}\", c.type_info().name()),\n                    },\n                )\n            })\n            .collect(),\n    }\n}\n"
  },
  {
    "path": "src/driver/sqlx_postgres.rs",
    "content": "use futures_util::lock::Mutex;\nuse log::LevelFilter;\nuse sea_query::Values;\nuse std::{fmt::Write, future::Future, pin::Pin, sync::Arc};\n\nuse sqlx::{\n    Connection, Executor, PgPool, Postgres,\n    pool::PoolConnection,\n    postgres::{PgConnectOptions, PgQueryResult, PgRow},\n};\n\nuse sea_query_sqlx::SqlxValues;\nuse tracing::instrument;\n\nuse crate::{\n    AccessMode, ConnectOptions, DatabaseConnection, DatabaseConnectionType, DatabaseTransaction,\n    IsolationLevel, QueryStream, Statement, TransactionError, debug_print, error::*, executor::*,\n};\n\nuse super::sqlx_common::*;\n\n/// Defines the [sqlx::postgres] connector\n#[derive(Debug)]\npub struct SqlxPostgresConnector;\n\n/// Defines a sqlx PostgreSQL pool\n#[derive(Clone)]\npub struct SqlxPostgresPoolConnection {\n    pub(crate) pool: PgPool,\n    metric_callback: Option<crate::metric::Callback>,\n}\n\nimpl std::fmt::Debug for SqlxPostgresPoolConnection {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"SqlxPostgresPoolConnection {{ pool: {:?} }}\", self.pool)\n    }\n}\n\nimpl From<PgPool> for SqlxPostgresPoolConnection {\n    fn from(pool: PgPool) -> Self {\n        SqlxPostgresPoolConnection {\n            pool,\n            metric_callback: None,\n        }\n    }\n}\n\nimpl From<PgPool> for DatabaseConnection {\n    fn from(pool: PgPool) -> Self {\n        DatabaseConnectionType::SqlxPostgresPoolConnection(pool.into()).into()\n    }\n}\n\nimpl SqlxPostgresConnector {\n    /// Check if the URI provided corresponds to `postgres://` for a PostgreSQL database\n    pub fn accepts(string: &str) -> bool {\n        string.starts_with(\"postgres://\") && string.parse::<PgConnectOptions>().is_ok()\n    }\n\n    /// Add configuration options for the PostgreSQL database\n    #[instrument(level = \"trace\")]\n    pub async fn connect(options: ConnectOptions) -> Result<DatabaseConnection, DbErr> {\n        let mut sqlx_opts = options\n            .url\n            .parse::<PgConnectOptions>()\n            .map_err(sqlx_error_to_conn_err)?;\n        use sqlx::ConnectOptions;\n        if !options.sqlx_logging {\n            sqlx_opts = sqlx_opts.disable_statement_logging();\n        } else {\n            sqlx_opts = sqlx_opts.log_statements(options.sqlx_logging_level);\n            if options.sqlx_slow_statements_logging_level != LevelFilter::Off {\n                sqlx_opts = sqlx_opts.log_slow_statements(\n                    options.sqlx_slow_statements_logging_level,\n                    options.sqlx_slow_statements_logging_threshold,\n                );\n            }\n        }\n\n        if let Some(application_name) = &options.application_name {\n            sqlx_opts = sqlx_opts.application_name(application_name);\n        }\n\n        if let Some(timeout) = options.statement_timeout {\n            sqlx_opts = sqlx_opts.options([(\"statement_timeout\", timeout.as_millis().to_string())]);\n        }\n\n        if let Some(f) = &options.pg_opts_fn {\n            sqlx_opts = f(sqlx_opts);\n        }\n\n        let set_search_path_sql = options.schema_search_path.as_ref().map(|schema| {\n            let mut string = \"SET search_path = \".to_owned();\n            if schema.starts_with('\"') {\n                write!(&mut string, \"{schema}\").expect(\"Infallible\");\n            } else {\n                for (i, schema) in schema.split(',').enumerate() {\n                    if i > 0 {\n                        write!(&mut string, \",\").expect(\"Infallible\");\n                    }\n                    if schema.starts_with('\"') {\n                        write!(&mut string, \"{schema}\").expect(\"Infallible\");\n                    } else {\n                        write!(&mut string, \"\\\"{schema}\\\"\").expect(\"Infallible\");\n                    }\n                }\n            }\n            string\n        });\n\n        let lazy = options.connect_lazy;\n        let after_connect = options.after_connect.clone();\n        let mut pool_options = options.sqlx_pool_options();\n\n        if let Some(sql) = set_search_path_sql {\n            pool_options = pool_options.after_connect(move |conn, _| {\n                let sql = sql.clone();\n                Box::pin(async move {\n                    sqlx::Executor::execute(conn, sql.as_str())\n                        .await\n                        .map(|_| ())\n                })\n            });\n        }\n\n        let pool = if lazy {\n            pool_options.connect_lazy_with(sqlx_opts)\n        } else {\n            pool_options\n                .connect_with(sqlx_opts)\n                .await\n                .map_err(sqlx_error_to_conn_err)?\n        };\n\n        let conn: DatabaseConnection =\n            DatabaseConnectionType::SqlxPostgresPoolConnection(SqlxPostgresPoolConnection {\n                pool,\n                metric_callback: None,\n            })\n            .into();\n\n        if let Some(cb) = after_connect {\n            cb(conn.clone()).await?;\n        }\n\n        Ok(conn)\n    }\n}\n\nimpl SqlxPostgresConnector {\n    /// Instantiate a sqlx pool connection to a [DatabaseConnection]\n    pub fn from_sqlx_postgres_pool(pool: PgPool) -> DatabaseConnection {\n        DatabaseConnectionType::SqlxPostgresPoolConnection(SqlxPostgresPoolConnection {\n            pool,\n            metric_callback: None,\n        })\n        .into()\n    }\n}\n\nimpl SqlxPostgresPoolConnection {\n    /// Execute a [Statement] on a PostgreSQL backend\n    #[instrument(level = \"trace\")]\n    pub async fn execute(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.execute(&mut *conn).await {\n                Ok(res) => Ok(res.into()),\n                Err(err) => Err(sqlx_error_to_exec_err(err)),\n            }\n        })\n    }\n\n    /// Execute an unprepared SQL statement on a PostgreSQL backend\n    #[instrument(level = \"trace\")]\n    pub async fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", sql);\n\n        let conn = &mut self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        match conn.execute(sql).await {\n            Ok(res) => Ok(res.into()),\n            Err(err) => Err(sqlx_error_to_exec_err(err)),\n        }\n    }\n\n    /// Get one result from a SQL query. Returns [Option::None] if no match was found\n    #[instrument(level = \"trace\")]\n    pub async fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.fetch_one(&mut *conn).await {\n                Ok(row) => Ok(Some(row.into())),\n                Err(err) => match err {\n                    sqlx::Error::RowNotFound => Ok(None),\n                    _ => Err(sqlx_error_to_query_err(err)),\n                },\n            }\n        })\n    }\n\n    /// Get the results of a query returning them as a Vec<[QueryResult]>\n    #[instrument(level = \"trace\")]\n    pub async fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.fetch_all(&mut *conn).await {\n                Ok(rows) => Ok(rows.into_iter().map(|r| r.into()).collect()),\n                Err(err) => Err(sqlx_error_to_query_err(err)),\n            }\n        })\n    }\n\n    /// Stream the results of executing a SQL query\n    #[instrument(level = \"trace\")]\n    pub async fn stream(&self, stmt: Statement) -> Result<QueryStream, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        Ok(QueryStream::from((\n            conn,\n            stmt,\n            self.metric_callback.clone(),\n        )))\n    }\n\n    /// Bundle a set of SQL statements that execute together.\n    #[instrument(level = \"trace\")]\n    pub async fn begin(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        let conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        DatabaseTransaction::new_postgres(\n            conn,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n        )\n        .await\n    }\n\n    /// Create a PostgreSQL transaction\n    #[instrument(level = \"trace\", skip(callback))]\n    pub async fn transaction<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'b> FnOnce(\n                &'b DatabaseTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'b>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        let conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        let transaction = DatabaseTransaction::new_postgres(\n            conn,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n        )\n        .await\n        .map_err(|e| TransactionError::Connection(e))?;\n        transaction.run(callback).await\n    }\n\n    pub(crate) fn set_metric_callback<F>(&mut self, callback: F)\n    where\n        F: Fn(&crate::metric::Info<'_>) + Send + Sync + 'static,\n    {\n        self.metric_callback = Some(Arc::new(callback));\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub async fn ping(&self) -> Result<(), DbErr> {\n        let conn = &mut self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        match conn.ping().await {\n            Ok(_) => Ok(()),\n            Err(err) => Err(sqlx_error_to_conn_err(err)),\n        }\n    }\n\n    /// Explicitly close the Postgres connection.\n    /// See [`Self::close_by_ref`] for usage with references.\n    pub async fn close(self) -> Result<(), DbErr> {\n        self.close_by_ref().await\n    }\n\n    /// Explicitly close the Postgres connection\n    pub async fn close_by_ref(&self) -> Result<(), DbErr> {\n        self.pool.close().await;\n        Ok(())\n    }\n}\n\nimpl From<PgRow> for QueryResult {\n    fn from(row: PgRow) -> QueryResult {\n        QueryResult {\n            row: QueryResultRow::SqlxPostgres(row),\n        }\n    }\n}\n\nimpl From<PgQueryResult> for ExecResult {\n    fn from(result: PgQueryResult) -> ExecResult {\n        ExecResult {\n            result: ExecResultHolder::SqlxPostgres(result),\n        }\n    }\n}\n\npub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Postgres, SqlxValues> {\n    let values = stmt\n        .values\n        .as_ref()\n        .map_or(Values(Vec::new()), |values| values.clone());\n    sqlx::query_with(&stmt.sql, SqlxValues(values))\n}\n\npub(crate) async fn set_transaction_config(\n    conn: &mut PoolConnection<Postgres>,\n    isolation_level: Option<IsolationLevel>,\n    access_mode: Option<AccessMode>,\n) -> Result<(), DbErr> {\n    let mut settings = Vec::new();\n\n    if let Some(isolation_level) = isolation_level {\n        settings.push(format!(\"ISOLATION LEVEL {isolation_level}\"));\n    }\n\n    if let Some(access_mode) = access_mode {\n        settings.push(access_mode.to_string());\n    }\n\n    if !settings.is_empty() {\n        let sql = format!(\"SET TRANSACTION {}\", settings.join(\" \"));\n        sqlx::query(&sql)\n            .execute(&mut **conn)\n            .await\n            .map_err(sqlx_error_to_exec_err)?;\n    }\n    Ok(())\n}\n\nimpl\n    From<(\n        PoolConnection<sqlx::Postgres>,\n        Statement,\n        Option<crate::metric::Callback>,\n    )> for crate::QueryStream\n{\n    fn from(\n        (conn, stmt, metric_callback): (\n            PoolConnection<sqlx::Postgres>,\n            Statement,\n            Option<crate::metric::Callback>,\n        ),\n    ) -> Self {\n        crate::QueryStream::build(\n            stmt,\n            crate::InnerConnection::Postgres(conn),\n            metric_callback,\n        )\n    }\n}\n\nimpl crate::DatabaseTransaction {\n    pub(crate) async fn new_postgres(\n        inner: PoolConnection<sqlx::Postgres>,\n        metric_callback: Option<crate::metric::Callback>,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<crate::DatabaseTransaction, DbErr> {\n        Self::begin(\n            Arc::new(Mutex::new(crate::InnerConnection::Postgres(inner))),\n            crate::DbBackend::Postgres,\n            metric_callback,\n            isolation_level,\n            access_mode,\n            None,\n        )\n        .await\n    }\n}\n\n#[cfg(feature = \"proxy\")]\npub(crate) fn from_sqlx_postgres_row_to_proxy_row(row: &sqlx::postgres::PgRow) -> crate::ProxyRow {\n    // https://docs.rs/sqlx-postgres/0.7.2/src/sqlx_postgres/type_info.rs.html\n    // https://docs.rs/sqlx-postgres/0.7.2/sqlx_postgres/types/index.html\n    use sea_query::Value;\n    use sqlx::{Column, Row, TypeInfo};\n    crate::ProxyRow {\n        values: row\n            .columns()\n            .iter()\n            .map(|c| {\n                (\n                    c.name().to_string(),\n                    match c.type_info().name() {\n                        \"BOOL\" => {\n                            Value::Bool(row.try_get(c.ordinal()).expect(\"Failed to get boolean\"))\n                        }\n                        #[cfg(feature = \"postgres-array\")]\n                        \"BOOL[]\" => Value::Array(\n                            sea_query::ArrayType::Bool,\n                            row.try_get::<Option<Vec<bool>>, _>(c.ordinal())\n                                .expect(\"Failed to get boolean array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Bool(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"\\\"CHAR\\\"\" => Value::TinyInt(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get small integer\"),\n                        ),\n                        #[cfg(feature = \"postgres-array\")]\n                        \"\\\"CHAR\\\"[]\" => Value::Array(\n                            sea_query::ArrayType::TinyInt,\n                            row.try_get::<Option<Vec<i8>>, _>(c.ordinal())\n                                .expect(\"Failed to get small integer array\")\n                                .map(|vals: Vec<i8>| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::TinyInt(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"SMALLINT\" | \"SMALLSERIAL\" | \"INT2\" => Value::SmallInt(\n                            row.try_get(c.ordinal())\n                                .expect(\"Failed to get small integer\"),\n                        ),\n                        #[cfg(feature = \"postgres-array\")]\n                        \"SMALLINT[]\" | \"SMALLSERIAL[]\" | \"INT2[]\" => Value::Array(\n                            sea_query::ArrayType::SmallInt,\n                            row.try_get::<Option<Vec<i16>>, _>(c.ordinal())\n                                .expect(\"Failed to get small integer array\")\n                                .map(|vals: Vec<i16>| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::SmallInt(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"INT\" | \"SERIAL\" | \"INT4\" => {\n                            Value::Int(row.try_get(c.ordinal()).expect(\"Failed to get integer\"))\n                        }\n                        #[cfg(feature = \"postgres-array\")]\n                        \"INT[]\" | \"SERIAL[]\" | \"INT4[]\" => Value::Array(\n                            sea_query::ArrayType::Int,\n                            row.try_get::<Option<Vec<i32>>, _>(c.ordinal())\n                                .expect(\"Failed to get integer array\")\n                                .map(|vals: Vec<i32>| {\n                                    Box::new(\n                                        vals.into_iter().map(|val| Value::Int(Some(val))).collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"BIGINT\" | \"BIGSERIAL\" | \"INT8\" => Value::BigInt(\n                            row.try_get(c.ordinal()).expect(\"Failed to get big integer\"),\n                        ),\n                        #[cfg(feature = \"postgres-array\")]\n                        \"BIGINT[]\" | \"BIGSERIAL[]\" | \"INT8[]\" => Value::Array(\n                            sea_query::ArrayType::BigInt,\n                            row.try_get::<Option<Vec<i64>>, _>(c.ordinal())\n                                .expect(\"Failed to get big integer array\")\n                                .map(|vals: Vec<i64>| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::BigInt(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"FLOAT4\" | \"REAL\" => {\n                            Value::Float(row.try_get(c.ordinal()).expect(\"Failed to get float\"))\n                        }\n                        #[cfg(feature = \"postgres-array\")]\n                        \"FLOAT4[]\" | \"REAL[]\" => Value::Array(\n                            sea_query::ArrayType::Float,\n                            row.try_get::<Option<Vec<f32>>, _>(c.ordinal())\n                                .expect(\"Failed to get float array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Float(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"FLOAT8\" | \"DOUBLE PRECISION\" => {\n                            Value::Double(row.try_get(c.ordinal()).expect(\"Failed to get double\"))\n                        }\n                        #[cfg(feature = \"postgres-array\")]\n                        \"FLOAT8[]\" | \"DOUBLE PRECISION[]\" => Value::Array(\n                            sea_query::ArrayType::Double,\n                            row.try_get::<Option<Vec<f64>>, _>(c.ordinal())\n                                .expect(\"Failed to get double array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Double(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"VARCHAR\" | \"CHAR\" | \"TEXT\" | \"NAME\" => Value::String(\n                            row.try_get::<Option<String>, _>(c.ordinal())\n                                .expect(\"Failed to get string\"),\n                        ),\n                        #[cfg(feature = \"postgres-array\")]\n                        \"VARCHAR[]\" | \"CHAR[]\" | \"TEXT[]\" | \"NAME[]\" => Value::Array(\n                            sea_query::ArrayType::String,\n                            row.try_get::<Option<Vec<String>>, _>(c.ordinal())\n                                .expect(\"Failed to get string array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::String(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"BYTEA\" => Value::Bytes(\n                            row.try_get::<Option<Vec<u8>>, _>(c.ordinal())\n                                .expect(\"Failed to get bytes\"),\n                        ),\n                        #[cfg(feature = \"postgres-array\")]\n                        \"BYTEA[]\" => Value::Array(\n                            sea_query::ArrayType::Bytes,\n                            row.try_get::<Option<Vec<Vec<u8>>>, _>(c.ordinal())\n                                .expect(\"Failed to get bytes array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Bytes(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-bigdecimal\")]\n                        \"NUMERIC\" => Value::BigDecimal(\n                            row.try_get::<Option<bigdecimal::BigDecimal>, _>(c.ordinal())\n                                .expect(\"Failed to get numeric\"),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-rust_decimal\",\n                            not(feature = \"with-bigdecimal\")\n                        ))]\n                        \"NUMERIC\" => {\n                            Value::Decimal(row.try_get(c.ordinal()).expect(\"Failed to get numeric\"))\n                        }\n\n                        #[cfg(all(feature = \"with-bigdecimal\", feature = \"postgres-array\"))]\n                        \"NUMERIC[]\" => Value::Array(\n                            sea_query::ArrayType::BigDecimal,\n                            row.try_get::<Option<Vec<bigdecimal::BigDecimal>>, _>(c.ordinal())\n                                .expect(\"Failed to get numeric array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::BigDecimal(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-rust_decimal\",\n                            not(feature = \"with-bigdecimal\"),\n                            feature = \"postgres-array\"\n                        ))]\n                        \"NUMERIC[]\" => Value::Array(\n                            sea_query::ArrayType::Decimal,\n                            row.try_get::<Option<Vec<rust_decimal::Decimal>>, _>(c.ordinal())\n                                .expect(\"Failed to get numeric array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Decimal(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        \"OID\" => {\n                            Value::BigInt(row.try_get(c.ordinal()).expect(\"Failed to get oid\"))\n                        }\n                        #[cfg(feature = \"postgres-array\")]\n                        \"OID[]\" => Value::Array(\n                            sea_query::ArrayType::BigInt,\n                            row.try_get::<Option<Vec<i64>>, _>(c.ordinal())\n                                .expect(\"Failed to get oid array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::BigInt(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-json\")]\n                        \"JSON\" | \"JSONB\" => Value::Json(\n                            row.try_get::<Option<serde_json::Value>, _>(c.ordinal())\n                                .expect(\"Failed to get json\")\n                                .map(Box::new),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-json\",\n                            any(feature = \"json-array\", feature = \"postgres-array\")\n                        ))]\n                        \"JSON[]\" | \"JSONB[]\" => Value::Array(\n                            sea_query::ArrayType::Json,\n                            row.try_get::<Option<Vec<serde_json::Value>>, _>(c.ordinal())\n                                .expect(\"Failed to get json array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Json(Some(Box::new(val))))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-ipnetwork\")]\n                        \"INET\" | \"CIDR\" => Value::IpNetwork(\n                            row.try_get::<Option<ipnetwork::IpNetwork>, _>(c.ordinal())\n                                .expect(\"Failed to get ip address\"),\n                        ),\n                        #[cfg(feature = \"with-ipnetwork\")]\n                        \"INET[]\" | \"CIDR[]\" => Value::Array(\n                            sea_query::ArrayType::IpNetwork,\n                            row.try_get::<Option<Vec<ipnetwork::IpNetwork>>, _>(c.ordinal())\n                                .expect(\"Failed to get ip address array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::IpNetwork(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-mac_address\")]\n                        \"MACADDR\" | \"MACADDR8\" => Value::MacAddress(\n                            row.try_get::<Option<mac_address::MacAddress>, _>(c.ordinal())\n                                .expect(\"Failed to get mac address\"),\n                        ),\n                        #[cfg(all(feature = \"with-mac_address\", feature = \"postgres-array\"))]\n                        \"MACADDR[]\" | \"MACADDR8[]\" => Value::Array(\n                            sea_query::ArrayType::MacAddress,\n                            row.try_get::<Option<Vec<mac_address::MacAddress>>, _>(c.ordinal())\n                                .expect(\"Failed to get mac address array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::MacAddress(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIMESTAMP\" => Value::ChronoDateTime(\n                            row.try_get::<Option<chrono::NaiveDateTime>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamp\"),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIMESTAMP\" => Value::TimeDateTime(\n                            row.try_get::<Option<time::PrimitiveDateTime>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamp\"),\n                        ),\n\n                        #[cfg(all(feature = \"with-chrono\", feature = \"postgres-array\"))]\n                        \"TIMESTAMP[]\" => Value::Array(\n                            sea_query::ArrayType::ChronoDateTime,\n                            row.try_get::<Option<Vec<chrono::NaiveDateTime>>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamp array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::ChronoDateTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-time\",\n                            not(feature = \"with-chrono\"),\n                            feature = \"postgres-array\"\n                        ))]\n                        \"TIMESTAMP[]\" => Value::Array(\n                            sea_query::ArrayType::TimeDateTime,\n                            row.try_get::<Option<Vec<time::PrimitiveDateTime>>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamp array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::TimeDateTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"DATE\" => Value::ChronoDate(\n                            row.try_get::<Option<chrono::NaiveDate>, _>(c.ordinal())\n                                .expect(\"Failed to get date\"),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"DATE\" => Value::TimeDate(\n                            row.try_get::<Option<time::Date>, _>(c.ordinal())\n                                .expect(\"Failed to get date\"),\n                        ),\n\n                        #[cfg(all(feature = \"with-chrono\", feature = \"postgres-array\"))]\n                        \"DATE[]\" => Value::Array(\n                            sea_query::ArrayType::ChronoDate,\n                            row.try_get::<Option<Vec<chrono::NaiveDate>>, _>(c.ordinal())\n                                .expect(\"Failed to get date array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::ChronoDate(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-time\",\n                            not(feature = \"with-chrono\"),\n                            feature = \"postgres-array\"\n                        ))]\n                        \"DATE[]\" => Value::Array(\n                            sea_query::ArrayType::TimeDate,\n                            row.try_get::<Option<Vec<time::Date>>, _>(c.ordinal())\n                                .expect(\"Failed to get date array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::TimeDate(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIME\" => Value::ChronoTime(\n                            row.try_get::<Option<chrono::NaiveTime>, _>(c.ordinal())\n                                .expect(\"Failed to get time\"),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIME\" => Value::TimeTime(\n                            row.try_get::<Option<time::Time>, _>(c.ordinal())\n                                .expect(\"Failed to get time\"),\n                        ),\n\n                        #[cfg(all(feature = \"with-chrono\", feature = \"postgres-array\"))]\n                        \"TIME[]\" => Value::Array(\n                            sea_query::ArrayType::ChronoTime,\n                            row.try_get::<Option<Vec<chrono::NaiveTime>>, _>(c.ordinal())\n                                .expect(\"Failed to get time array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::ChronoTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-time\",\n                            not(feature = \"with-chrono\"),\n                            feature = \"postgres-array\"\n                        ))]\n                        \"TIME[]\" => Value::Array(\n                            sea_query::ArrayType::TimeTime,\n                            row.try_get::<Option<Vec<time::Time>>, _>(c.ordinal())\n                                .expect(\"Failed to get time array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::TimeTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIMESTAMPTZ\" => Value::ChronoDateTimeUtc(\n                            row.try_get::<Option<chrono::DateTime<chrono::Utc>>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamptz\"),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIMESTAMPTZ\" => Value::TimeDateTimeWithTimeZone(\n                            row.try_get::<Option<time::OffsetDateTime>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamptz\"),\n                        ),\n\n                        #[cfg(all(feature = \"with-chrono\", feature = \"postgres-array\"))]\n                        \"TIMESTAMPTZ[]\" => Value::Array(\n                            sea_query::ArrayType::ChronoDateTimeUtc,\n                            row.try_get::<Option<Vec<chrono::DateTime<chrono::Utc>>>, _>(\n                                c.ordinal(),\n                            )\n                            .expect(\"Failed to get timestamptz array\")\n                            .map(|vals| {\n                                Box::new(\n                                    vals.into_iter()\n                                        .map(|val| Value::ChronoDateTimeUtc(Some(val)))\n                                        .collect(),\n                                )\n                            }),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-time\",\n                            not(feature = \"with-chrono\"),\n                            feature = \"postgres-array\"\n                        ))]\n                        \"TIMESTAMPTZ[]\" => Value::Array(\n                            sea_query::ArrayType::TimeDateTimeWithTimeZone,\n                            row.try_get::<Option<Vec<time::OffsetDateTime>>, _>(c.ordinal())\n                                .expect(\"Failed to get timestamptz array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::TimeDateTimeWithTimeZone(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIMETZ\" => Value::ChronoTime(\n                            row.try_get::<Option<chrono::NaiveTime>, _>(c.ordinal())\n                                .expect(\"Failed to get timetz\"),\n                        ),\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIMETZ\" => {\n                            Value::TimeTime(row.try_get(c.ordinal()).expect(\"Failed to get timetz\"))\n                        }\n\n                        #[cfg(all(feature = \"with-chrono\", feature = \"postgres-array\"))]\n                        \"TIMETZ[]\" => Value::Array(\n                            sea_query::ArrayType::ChronoTime,\n                            row.try_get::<Option<Vec<chrono::NaiveTime>>, _>(c.ordinal())\n                                .expect(\"Failed to get timetz array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::ChronoTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n                        #[cfg(all(\n                            feature = \"with-time\",\n                            not(feature = \"with-chrono\"),\n                            feature = \"postgres-array\"\n                        ))]\n                        \"TIMETZ[]\" => Value::Array(\n                            sea_query::ArrayType::TimeTime,\n                            row.try_get::<Option<Vec<time::Time>>, _>(c.ordinal())\n                                .expect(\"Failed to get timetz array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::TimeTime(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        #[cfg(feature = \"with-uuid\")]\n                        \"UUID\" => Value::Uuid(\n                            row.try_get::<Option<uuid::Uuid>, _>(c.ordinal())\n                                .expect(\"Failed to get uuid\"),\n                        ),\n\n                        #[cfg(all(feature = \"with-uuid\", feature = \"postgres-array\"))]\n                        \"UUID[]\" => Value::Array(\n                            sea_query::ArrayType::Uuid,\n                            row.try_get::<Option<Vec<uuid::Uuid>>, _>(c.ordinal())\n                                .expect(\"Failed to get uuid array\")\n                                .map(|vals| {\n                                    Box::new(\n                                        vals.into_iter()\n                                            .map(|val| Value::Uuid(Some(val)))\n                                            .collect(),\n                                    )\n                                }),\n                        ),\n\n                        _ => unreachable!(\"Unknown column type: {}\", c.type_info().name()),\n                    },\n                )\n            })\n            .collect(),\n    }\n}\n"
  },
  {
    "path": "src/driver/sqlx_sqlite.rs",
    "content": "use futures_util::lock::Mutex;\nuse log::LevelFilter;\nuse sea_query::Values;\nuse std::{future::Future, pin::Pin, sync::Arc};\n\nuse sqlx::{\n    Connection, Executor, Sqlite, SqlitePool,\n    pool::PoolConnection,\n    sqlite::{SqliteConnectOptions, SqliteQueryResult, SqliteRow},\n};\n\nuse sea_query_sqlx::SqlxValues;\nuse tracing::{instrument, warn};\n\nuse crate::{\n    AccessMode, ConnectOptions, DatabaseConnection, DatabaseConnectionType, DatabaseTransaction,\n    IsolationLevel, QueryStream, SqliteTransactionMode, Statement, TransactionError, debug_print,\n    error::*, executor::*, sqlx_error_to_exec_err,\n};\n\nuse super::sqlx_common::*;\n\n/// Defines the [sqlx::sqlite] connector\n#[derive(Debug)]\npub struct SqlxSqliteConnector;\n\n/// Defines a sqlx SQLite pool\n#[derive(Clone)]\npub struct SqlxSqlitePoolConnection {\n    pub(crate) pool: SqlitePool,\n    metric_callback: Option<crate::metric::Callback>,\n}\n\nimpl std::fmt::Debug for SqlxSqlitePoolConnection {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"SqlxSqlitePoolConnection {{ pool: {:?} }}\", self.pool)\n    }\n}\n\nimpl From<SqlitePool> for SqlxSqlitePoolConnection {\n    fn from(pool: SqlitePool) -> Self {\n        SqlxSqlitePoolConnection {\n            pool,\n            metric_callback: None,\n        }\n    }\n}\n\nimpl From<SqlitePool> for DatabaseConnection {\n    fn from(pool: SqlitePool) -> Self {\n        DatabaseConnectionType::SqlxSqlitePoolConnection(pool.into()).into()\n    }\n}\n\nimpl SqlxSqliteConnector {\n    /// Check if the URI provided corresponds to `sqlite:` for a SQLite database\n    pub fn accepts(string: &str) -> bool {\n        string.starts_with(\"sqlite:\") && string.parse::<SqliteConnectOptions>().is_ok()\n    }\n\n    /// Add configuration options for the SQLite database\n    #[instrument(level = \"trace\")]\n    pub async fn connect(options: ConnectOptions) -> Result<DatabaseConnection, DbErr> {\n        let mut options = options;\n        let mut sqlx_opts = options\n            .url\n            .parse::<SqliteConnectOptions>()\n            .map_err(sqlx_error_to_conn_err)?;\n        if let Some(sqlcipher_key) = &options.sqlcipher_key {\n            sqlx_opts = sqlx_opts.pragma(\"key\", sqlcipher_key.clone());\n        }\n        use sqlx::ConnectOptions;\n        if !options.sqlx_logging {\n            sqlx_opts = sqlx_opts.disable_statement_logging();\n        } else {\n            sqlx_opts = sqlx_opts.log_statements(options.sqlx_logging_level);\n            if options.sqlx_slow_statements_logging_level != LevelFilter::Off {\n                sqlx_opts = sqlx_opts.log_slow_statements(\n                    options.sqlx_slow_statements_logging_level,\n                    options.sqlx_slow_statements_logging_threshold,\n                );\n            }\n        }\n\n        if options.get_max_connections().is_none() {\n            options.max_connections(1);\n        }\n\n        if let Some(f) = &options.sqlite_opts_fn {\n            sqlx_opts = f(sqlx_opts);\n        }\n\n        let after_conn = options.after_connect.clone();\n\n        let pool = if options.connect_lazy {\n            options.sqlx_pool_options().connect_lazy_with(sqlx_opts)\n        } else {\n            options\n                .sqlx_pool_options()\n                .connect_with(sqlx_opts)\n                .await\n                .map_err(sqlx_error_to_conn_err)?\n        };\n\n        let pool = SqlxSqlitePoolConnection {\n            pool,\n            metric_callback: None,\n        };\n\n        #[cfg(feature = \"sqlite-use-returning-for-3_35\")]\n        {\n            let version = get_version(&pool).await?;\n            super::sqlite::ensure_returning_version(&version)?;\n        }\n\n        let conn: DatabaseConnection =\n            DatabaseConnectionType::SqlxSqlitePoolConnection(pool).into();\n\n        if let Some(cb) = after_conn {\n            cb(conn.clone()).await?;\n        }\n\n        Ok(conn)\n    }\n}\n\nimpl SqlxSqliteConnector {\n    /// Instantiate a sqlx pool connection to a [DatabaseConnection]\n    pub fn from_sqlx_sqlite_pool(pool: SqlitePool) -> DatabaseConnection {\n        DatabaseConnectionType::SqlxSqlitePoolConnection(SqlxSqlitePoolConnection {\n            pool,\n            metric_callback: None,\n        })\n        .into()\n    }\n}\n\nimpl SqlxSqlitePoolConnection {\n    /// Execute a [Statement] on a SQLite backend\n    #[instrument(level = \"trace\")]\n    pub async fn execute(&self, stmt: Statement) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.execute(&mut *conn).await {\n                Ok(res) => Ok(res.into()),\n                Err(err) => Err(sqlx_error_to_exec_err(err)),\n            }\n        })\n    }\n\n    /// Execute an unprepared SQL statement on a SQLite backend\n    #[instrument(level = \"trace\")]\n    pub async fn execute_unprepared(&self, sql: &str) -> Result<ExecResult, DbErr> {\n        debug_print!(\"{}\", sql);\n\n        let conn = &mut self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        match conn.execute(sql).await {\n            Ok(res) => Ok(res.into()),\n            Err(err) => Err(sqlx_error_to_exec_err(err)),\n        }\n    }\n\n    /// Get one result from a SQL query. Returns [Option::None] if no match was found\n    #[instrument(level = \"trace\")]\n    pub async fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.fetch_one(&mut *conn).await {\n                Ok(row) => Ok(Some(row.into())),\n                Err(err) => match err {\n                    sqlx::Error::RowNotFound => Ok(None),\n                    _ => Err(sqlx_error_to_query_err(err)),\n                },\n            }\n        })\n    }\n\n    /// Get the results of a query returning them as a Vec<[QueryResult]>\n    #[instrument(level = \"trace\")]\n    pub async fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let query = sqlx_query(&stmt);\n        let mut conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        crate::metric::metric!(self.metric_callback, &stmt, {\n            match query.fetch_all(&mut *conn).await {\n                Ok(rows) => Ok(rows.into_iter().map(|r| r.into()).collect()),\n                Err(err) => Err(sqlx_error_to_query_err(err)),\n            }\n        })\n    }\n\n    /// Stream the results of executing a SQL query\n    #[instrument(level = \"trace\")]\n    pub async fn stream(&self, stmt: Statement) -> Result<QueryStream, DbErr> {\n        debug_print!(\"{}\", stmt);\n\n        let conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        Ok(QueryStream::from((\n            conn,\n            stmt,\n            self.metric_callback.clone(),\n        )))\n    }\n\n    /// Bundle a set of SQL statements that execute together.\n    #[instrument(level = \"trace\")]\n    pub async fn begin(\n        &self,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n        sqlite_transaction_mode: Option<SqliteTransactionMode>,\n    ) -> Result<DatabaseTransaction, DbErr> {\n        let conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        DatabaseTransaction::new_sqlite(\n            conn,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n            sqlite_transaction_mode,\n        )\n        .await\n    }\n\n    /// Create a SQLite transaction\n    #[instrument(level = \"trace\", skip(callback))]\n    pub async fn transaction<F, T, E>(\n        &self,\n        callback: F,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n    ) -> Result<T, TransactionError<E>>\n    where\n        F: for<'b> FnOnce(\n                &'b DatabaseTransaction,\n            ) -> Pin<Box<dyn Future<Output = Result<T, E>> + Send + 'b>>\n            + Send,\n        T: Send,\n        E: std::fmt::Display + std::fmt::Debug + Send,\n    {\n        let conn = self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        let transaction = DatabaseTransaction::new_sqlite(\n            conn,\n            self.metric_callback.clone(),\n            isolation_level,\n            access_mode,\n            None,\n        )\n        .await\n        .map_err(|e| TransactionError::Connection(e))?;\n        transaction.run(callback).await\n    }\n\n    pub(crate) fn set_metric_callback<F>(&mut self, callback: F)\n    where\n        F: Fn(&crate::metric::Info<'_>) + Send + Sync + 'static,\n    {\n        self.metric_callback = Some(Arc::new(callback));\n    }\n\n    /// Checks if a connection to the database is still valid.\n    pub async fn ping(&self) -> Result<(), DbErr> {\n        let conn = &mut self.pool.acquire().await.map_err(sqlx_conn_acquire_err)?;\n        match conn.ping().await {\n            Ok(_) => Ok(()),\n            Err(err) => Err(sqlx_error_to_conn_err(err)),\n        }\n    }\n\n    /// Explicitly close the SQLite connection.\n    /// See [`Self::close_by_ref`] for usage with references.\n    pub async fn close(self) -> Result<(), DbErr> {\n        self.close_by_ref().await\n    }\n\n    /// Explicitly close the SQLite connection\n    pub async fn close_by_ref(&self) -> Result<(), DbErr> {\n        self.pool.close().await;\n        Ok(())\n    }\n}\n\nimpl From<SqliteRow> for QueryResult {\n    fn from(row: SqliteRow) -> QueryResult {\n        QueryResult {\n            row: QueryResultRow::SqlxSqlite(row),\n        }\n    }\n}\n\nimpl From<SqliteQueryResult> for ExecResult {\n    fn from(result: SqliteQueryResult) -> ExecResult {\n        ExecResult {\n            result: ExecResultHolder::SqlxSqlite(result),\n        }\n    }\n}\n\npub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Sqlite, SqlxValues> {\n    let values = stmt\n        .values\n        .as_ref()\n        .map_or(Values(Vec::new()), |values| values.clone());\n    sqlx::query_with(&stmt.sql, SqlxValues(values))\n}\n\npub(crate) async fn set_transaction_config(\n    _conn: &mut PoolConnection<Sqlite>,\n    isolation_level: Option<IsolationLevel>,\n    access_mode: Option<AccessMode>,\n) -> Result<(), DbErr> {\n    if isolation_level.is_some() {\n        warn!(\"Setting isolation level in a SQLite transaction isn't supported\");\n    }\n    if access_mode.is_some() {\n        warn!(\"Setting access mode in a SQLite transaction isn't supported\");\n    }\n    Ok(())\n}\n\n#[cfg(feature = \"sqlite-use-returning-for-3_35\")]\nasync fn get_version(conn: &SqlxSqlitePoolConnection) -> Result<String, DbErr> {\n    let stmt = Statement {\n        sql: \"SELECT sqlite_version()\".to_string(),\n        values: None,\n        db_backend: crate::DbBackend::Sqlite,\n    };\n    conn.query_one(stmt)\n        .await?\n        .ok_or_else(|| {\n            DbErr::Conn(RuntimeErr::Internal(\n                \"Error reading SQLite version\".to_string(),\n            ))\n        })?\n        .try_get_by(0)\n}\n\nimpl\n    From<(\n        PoolConnection<sqlx::Sqlite>,\n        Statement,\n        Option<crate::metric::Callback>,\n    )> for crate::QueryStream\n{\n    fn from(\n        (conn, stmt, metric_callback): (\n            PoolConnection<sqlx::Sqlite>,\n            Statement,\n            Option<crate::metric::Callback>,\n        ),\n    ) -> Self {\n        crate::QueryStream::build(stmt, crate::InnerConnection::Sqlite(conn), metric_callback)\n    }\n}\n\nimpl crate::DatabaseTransaction {\n    pub(crate) async fn new_sqlite(\n        inner: PoolConnection<sqlx::Sqlite>,\n        metric_callback: Option<crate::metric::Callback>,\n        isolation_level: Option<IsolationLevel>,\n        access_mode: Option<AccessMode>,\n        sqlite_transaction_mode: Option<SqliteTransactionMode>,\n    ) -> Result<crate::DatabaseTransaction, DbErr> {\n        Self::begin(\n            Arc::new(Mutex::new(crate::InnerConnection::Sqlite(inner))),\n            crate::DbBackend::Sqlite,\n            metric_callback,\n            isolation_level,\n            access_mode,\n            sqlite_transaction_mode,\n        )\n        .await\n    }\n}\n\n#[cfg(feature = \"proxy\")]\npub(crate) fn from_sqlx_sqlite_row_to_proxy_row(row: &sqlx::sqlite::SqliteRow) -> crate::ProxyRow {\n    // https://docs.rs/sqlx-sqlite/0.7.2/src/sqlx_sqlite/type_info.rs.html\n    // https://docs.rs/sqlx-sqlite/0.7.2/sqlx_sqlite/types/index.html\n    use sea_query::Value;\n    use sqlx::{Column, Row, TypeInfo};\n    crate::ProxyRow {\n        values: row\n            .columns()\n            .iter()\n            .map(|c| {\n                (\n                    c.name().to_string(),\n                    match c.type_info().name() {\n                        \"BOOLEAN\" => {\n                            Value::Bool(row.try_get(c.ordinal()).expect(\"Failed to get boolean\"))\n                        }\n\n                        \"INTEGER\" => {\n                            Value::Int(row.try_get(c.ordinal()).expect(\"Failed to get integer\"))\n                        }\n\n                        \"BIGINT\" | \"INT8\" => Value::BigInt(\n                            row.try_get(c.ordinal()).expect(\"Failed to get big integer\"),\n                        ),\n\n                        \"REAL\" => {\n                            Value::Double(row.try_get(c.ordinal()).expect(\"Failed to get double\"))\n                        }\n\n                        \"TEXT\" => Value::String(\n                            row.try_get::<Option<String>, _>(c.ordinal())\n                                .expect(\"Failed to get string\")\n                                .map(Box::new),\n                        ),\n\n                        \"BLOB\" => Value::Bytes(\n                            row.try_get::<Option<Vec<u8>>, _>(c.ordinal())\n                                .expect(\"Failed to get bytes\")\n                                .map(Box::new),\n                        ),\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"DATETIME\" => {\n                            use chrono::{DateTime, Utc};\n\n                            Value::ChronoDateTimeUtc(\n                                row.try_get::<Option<DateTime<Utc>>, _>(c.ordinal())\n                                    .expect(\"Failed to get timestamp\")\n                                    .map(Box::new),\n                            )\n                        }\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"DATETIME\" => {\n                            use time::OffsetDateTime;\n                            Value::TimeDateTimeWithTimeZone(\n                                row.try_get::<Option<OffsetDateTime>, _>(c.ordinal())\n                                    .expect(\"Failed to get timestamp\")\n                                    .map(Box::new),\n                            )\n                        }\n                        #[cfg(feature = \"with-chrono\")]\n                        \"DATE\" => {\n                            use chrono::NaiveDate;\n                            Value::ChronoDate(\n                                row.try_get::<Option<NaiveDate>, _>(c.ordinal())\n                                    .expect(\"Failed to get date\")\n                                    .map(Box::new),\n                            )\n                        }\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"DATE\" => {\n                            use time::Date;\n                            Value::TimeDate(\n                                row.try_get::<Option<Date>, _>(c.ordinal())\n                                    .expect(\"Failed to get date\")\n                                    .map(Box::new),\n                            )\n                        }\n\n                        #[cfg(feature = \"with-chrono\")]\n                        \"TIME\" => {\n                            use chrono::NaiveTime;\n                            Value::ChronoTime(\n                                row.try_get::<Option<NaiveTime>, _>(c.ordinal())\n                                    .expect(\"Failed to get time\")\n                                    .map(Box::new),\n                            )\n                        }\n                        #[cfg(all(feature = \"with-time\", not(feature = \"with-chrono\")))]\n                        \"TIME\" => {\n                            use time::Time;\n                            Value::TimeTime(\n                                row.try_get::<Option<Time>, _>(c.ordinal())\n                                    .expect(\"Failed to get time\")\n                                    .map(Box::new),\n                            )\n                        }\n\n                        _ => unreachable!(\"Unknown column type: {}\", c.type_info().name()),\n                    },\n                )\n            })\n            .collect(),\n    }\n}\n"
  },
  {
    "path": "src/dynamic/entity.rs",
    "content": "use super::{FieldType, ModelType};\nuse crate::{ColumnDef, ColumnTrait, DbBackend, EntityTrait, Iterable, ModelTrait, Value};\nuse sea_query::{\n    ArrayType, BinOper, DynIden, Expr, ExprTrait, IntoColumnRef, IntoIden, IntoLikeExpr,\n    IntoTableRef, SelectStatement, SimpleExpr, TableRef,\n};\nuse std::sync::Arc;\n\n#[derive(Debug)]\npub struct Entity {\n    schema_name: Option<Arc<str>>,\n    table_name: Arc<str>,\n    columns: Vec<Column>,\n}\n\n#[derive(Debug)]\npub struct Column {\n    table_name: Arc<str>,\n    column_name: Arc<str>,\n    column_def: ColumnDef,\n    value_type: ArrayType,\n    enum_type_name: Option<Arc<str>>,\n}\n\nimpl Entity {\n    pub fn schema_name(&self) -> Option<&str> {\n        self.schema_name.as_deref()\n    }\n\n    pub fn table_name(&self) -> &str {\n        &self.table_name\n    }\n\n    pub fn table_ref(&self) -> TableRef {\n        match self.schema_name() {\n            Some(schema) => (schema.to_owned(), self.table_name().to_owned()).into_table_ref(),\n            None => self.table_name().to_owned().into_table_ref(),\n        }\n    }\n\n    pub fn iter_columns(&self) -> impl Iterator<Item = &Column> {\n        self.columns.iter()\n    }\n}\n\nimpl Entity {\n    pub fn from_entity<E: EntityTrait>(entity: E) -> Self {\n        Self {\n            schema_name: entity.schema_name().map(Arc::from),\n            table_name: Arc::from(entity.table_name()),\n            columns: <E::Column as Iterable>::iter()\n                .map(|c| {\n                    let (tbl, col) = c.as_column_ref();\n                    Column {\n                        table_name: Arc::from(tbl.inner()),\n                        column_name: Arc::from(col.inner()),\n                        column_def: c.def(),\n                        value_type: <E::Model as ModelTrait>::get_value_type(c),\n                        enum_type_name: c.enum_type_name().map(Arc::from),\n                    }\n                })\n                .collect(),\n        }\n    }\n\n    pub fn to_model_type(&self) -> ModelType {\n        ModelType {\n            fields: self\n                .columns\n                .iter()\n                .map(|c| FieldType {\n                    field: c.column_name.clone(),\n                    type_: c.value_type.clone(),\n                })\n                .collect(),\n        }\n    }\n}\n\nimpl Column {\n    pub fn def(&self) -> ColumnDef {\n        self.column_def.clone()\n    }\n\n    pub fn column_name(&self) -> &str {\n        &self.column_name\n    }\n\n    pub fn enum_type_name(&self) -> Option<&str> {\n        self.enum_type_name.as_deref()\n    }\n\n    pub fn entity_name(&self) -> DynIden {\n        self.table_name.to_string().into_iden()\n    }\n\n    pub fn as_column_ref(&self) -> (DynIden, DynIden) {\n        (\n            self.entity_name(),\n            self.column_name().to_owned().into_iden(),\n        )\n    }\n\n    crate::entity::column::macros::bind_oper!(pub eq, Equal);\n    crate::entity::column::macros::bind_oper!(pub ne, NotEqual);\n    crate::entity::column::macros::bind_oper!(pub gt, GreaterThan);\n    crate::entity::column::macros::bind_oper!(pub gte, GreaterThanOrEqual);\n    crate::entity::column::macros::bind_oper!(pub lt, SmallerThan);\n    crate::entity::column::macros::bind_oper!(pub lte, SmallerThanOrEqual);\n\n    pub fn between<V>(&self, a: V, b: V) -> SimpleExpr\n    where\n        V: Into<Value>,\n    {\n        Expr::col(self.as_column_ref()).between(a, b)\n    }\n\n    pub fn not_between<V>(&self, a: V, b: V) -> SimpleExpr\n    where\n        V: Into<Value>,\n    {\n        Expr::col(self.as_column_ref()).not_between(a, b)\n    }\n\n    pub fn like<T>(&self, s: T) -> SimpleExpr\n    where\n        T: IntoLikeExpr,\n    {\n        Expr::col(self.as_column_ref()).like(s)\n    }\n\n    pub fn not_like<T>(&self, s: T) -> SimpleExpr\n    where\n        T: IntoLikeExpr,\n    {\n        Expr::col(self.as_column_ref()).not_like(s)\n    }\n\n    pub fn starts_with<T>(&self, s: T) -> SimpleExpr\n    where\n        T: Into<String>,\n    {\n        let pattern = format!(\"{}%\", s.into());\n        Expr::col(self.as_column_ref()).like(pattern)\n    }\n\n    pub fn ends_with<T>(&self, s: T) -> SimpleExpr\n    where\n        T: Into<String>,\n    {\n        let pattern = format!(\"%{}\", s.into());\n        Expr::col(self.as_column_ref()).like(pattern)\n    }\n\n    pub fn contains<T>(&self, s: T) -> SimpleExpr\n    where\n        T: Into<String>,\n    {\n        let pattern = format!(\"%{}%\", s.into());\n        Expr::col(self.as_column_ref()).like(pattern)\n    }\n\n    crate::entity::column::macros::bind_func_no_params!(pub max);\n    crate::entity::column::macros::bind_func_no_params!(pub min);\n    crate::entity::column::macros::bind_func_no_params!(pub sum);\n    crate::entity::column::macros::bind_func_no_params!(pub count);\n    crate::entity::column::macros::bind_func_no_params!(pub is_null);\n    crate::entity::column::macros::bind_func_no_params!(pub is_not_null);\n\n    pub fn if_null<V>(&self, v: V) -> SimpleExpr\n    where\n        V: Into<Value>,\n    {\n        Expr::col(self.as_column_ref()).if_null(v)\n    }\n\n    crate::entity::column::macros::bind_vec_func!(pub is_in);\n    crate::entity::column::macros::bind_vec_func!(pub is_not_in);\n\n    crate::entity::column::macros::bind_subquery_func!(pub in_subquery);\n    crate::entity::column::macros::bind_subquery_func!(pub not_in_subquery);\n\n    pub fn into_expr(self) -> Expr {\n        SimpleExpr::Column(self.as_column_ref().into_column_ref())\n    }\n\n    #[allow(clippy::match_single_binding)]\n    pub fn into_returning_expr(self, db_backend: DbBackend) -> Expr {\n        match db_backend {\n            _ => Expr::col(self.column_name().to_owned()),\n        }\n    }\n\n    pub fn select_as(&self, expr: Expr) -> SimpleExpr {\n        crate::entity::column::cast_enum_as(\n            expr,\n            &self.def(),\n            crate::entity::column::select_enum_as,\n        )\n    }\n\n    pub fn save_as(&self, val: Expr) -> SimpleExpr {\n        crate::entity::column::cast_enum_as(val, &self.def(), crate::entity::column::save_enum_as)\n    }\n}\n"
  },
  {
    "path": "src/dynamic/execute.rs",
    "content": "use crate::{\n    ConnectionTrait, DbBackend, DbErr, EntityTrait, FromQueryResult, QueryResult, Select,\n    Statement, dynamic,\n};\nuse itertools::Itertools;\nuse sea_query::{DynIden, Expr, IntoIden, SelectStatement};\nuse std::marker::PhantomData;\n\n#[derive(Debug)]\npub struct SelectModelAndDynModel<M>\nwhere\n    M: FromQueryResult,\n{\n    model: PhantomData<M>,\n    dyn_model: dynamic::ModelType,\n}\n\n#[derive(Clone, Debug)]\npub struct DynSelector<S>\nwhere\n    S: DynSelectorTrait,\n{\n    pub(crate) query: SelectStatement,\n    selector: S,\n}\n\npub trait DynSelectorTrait {\n    type Item: Sized;\n\n    #[allow(clippy::wrong_self_convention)]\n    fn from_raw_query_result(&self, res: QueryResult) -> Result<Self::Item, DbErr>;\n}\n\nimpl<M> DynSelectorTrait for SelectModelAndDynModel<M>\nwhere\n    M: FromQueryResult + Sized,\n{\n    type Item = (M, dynamic::Model);\n\n    fn from_raw_query_result(&self, res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, \"\")?,\n            self.dyn_model.from_query_result(&res, \"\")?,\n        ))\n    }\n}\n\nimpl<E> Select<E>\nwhere\n    E: EntityTrait,\n{\n    pub fn select_also_dyn_model(\n        mut self,\n        table: DynIden,\n        dyn_model: dynamic::ModelType,\n    ) -> DynSelector<SelectModelAndDynModel<E::Model>> {\n        for field in dyn_model.fields.iter() {\n            self.query.expr(Expr::col((\n                table.clone(),\n                field.field().to_owned().into_iden(),\n            )));\n        }\n        DynSelector {\n            query: self.query,\n            selector: SelectModelAndDynModel {\n                model: PhantomData,\n                dyn_model,\n            },\n        }\n    }\n}\n\nimpl<S> DynSelector<S>\nwhere\n    S: DynSelectorTrait,\n{\n    /// Get the SQL statement\n    pub fn into_statement(self, builder: DbBackend) -> Statement {\n        builder.build(&self.query)\n    }\n\n    /// Get an item from the Select query\n    pub async fn one<C>(mut self, db: &C) -> Result<Option<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.query.limit(1);\n        let row = db.query_one(&self.query).await?;\n        match row {\n            Some(row) => Ok(Some(self.selector.from_raw_query_result(row)?)),\n            None => Ok(None),\n        }\n    }\n\n    /// Get all items from the Select query\n    pub async fn all<C>(self, db: &C) -> Result<Vec<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        db.query_all(&self.query)\n            .await?\n            .into_iter()\n            .map(|row| self.selector.from_raw_query_result(row))\n            .try_collect()\n    }\n}\n"
  },
  {
    "path": "src/dynamic/mod.rs",
    "content": "//! The API of this module is not yet stable, and may have breaking changes between minor versions.\n#![allow(missing_docs)]\n\nmod entity;\nmod execute;\nmod model;\n\npub use entity::*;\npub use execute::*;\npub use model::*;\n"
  },
  {
    "path": "src/dynamic/model.rs",
    "content": "use crate::{DbErr, QueryResult};\nuse sea_query::{ArrayType, DynIden, Value};\nuse std::sync::Arc;\n\n#[derive(Debug, Clone, PartialEq, Eq)]\npub struct ModelType {\n    pub fields: Vec<FieldType>,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, Hash)]\npub struct FieldType {\n    pub(super) field: Arc<str>,\n    pub(super) type_: ArrayType,\n}\n\n#[derive(Debug, Clone, PartialEq)]\npub struct Model {\n    pub fields: Vec<FieldValue>,\n}\n\n#[derive(Debug, Clone, PartialEq)]\npub struct FieldValue {\n    pub(super) field: Arc<str>,\n    pub value: Value,\n}\n\nimpl FieldType {\n    pub fn new(iden: DynIden, type_: ArrayType) -> Self {\n        Self {\n            field: Arc::from(iden.inner()),\n            type_,\n        }\n    }\n\n    pub fn field(&self) -> &str {\n        &self.field\n    }\n}\n\nimpl FieldValue {\n    pub fn field(&self) -> &str {\n        &self.field\n    }\n}\n\nimpl ModelType {\n    pub fn from_query_result(&self, res: &QueryResult, pre: &str) -> Result<Model, DbErr> {\n        let mut fields = Vec::new();\n        for f in self.fields.iter() {\n            fields.push(FieldValue {\n                field: f.field.clone(),\n                value: try_get(res, pre, f.field(), &f.type_)?,\n            });\n        }\n        Ok(Model { fields })\n    }\n}\n\nimpl Model {\n    pub fn try_get(&self, col: &str) -> Result<&Value, DbErr> {\n        for field in &self.fields {\n            if field.field() == col {\n                return Ok(&field.value);\n            }\n        }\n        Err(DbErr::Type(format!(\"{col} not exist\")))\n    }\n}\n\nfn try_get(res: &QueryResult, pre: &str, col: &str, ty: &ArrayType) -> Result<Value, DbErr> {\n    // how to handle postgres-array?\n    Ok(match ty {\n        ArrayType::Bool => Value::Bool(res.try_get(pre, col)?),\n        ArrayType::TinyInt => Value::TinyInt(res.try_get(pre, col)?),\n        ArrayType::SmallInt => Value::SmallInt(res.try_get(pre, col)?),\n        ArrayType::Int => Value::Int(res.try_get(pre, col)?),\n        ArrayType::BigInt => Value::BigInt(res.try_get(pre, col)?),\n        ArrayType::TinyUnsigned => Value::TinyUnsigned(res.try_get(pre, col)?),\n        ArrayType::SmallUnsigned => Value::SmallUnsigned(res.try_get(pre, col)?),\n        ArrayType::Unsigned => Value::Unsigned(res.try_get(pre, col)?),\n        ArrayType::BigUnsigned => Value::BigUnsigned(res.try_get(pre, col)?),\n        ArrayType::Float => Value::Float(res.try_get(pre, col)?),\n        ArrayType::Double => Value::Double(res.try_get(pre, col)?),\n        ArrayType::String => Value::String(res.try_get(pre, col)?),\n        ArrayType::Char => return Err(DbErr::Type(\"Unsupported type: char\".into())),\n        ArrayType::Bytes => Value::Bytes(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-json\")]\n        ArrayType::Json => Value::Json(res.try_get::<Option<_>>(pre, col)?.map(Box::new)),\n\n        #[cfg(feature = \"with-chrono\")]\n        ArrayType::ChronoDate => Value::ChronoDate(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-chrono\")]\n        ArrayType::ChronoTime => Value::ChronoTime(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-chrono\")]\n        ArrayType::ChronoDateTime => Value::ChronoDateTime(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-chrono\")]\n        ArrayType::ChronoDateTimeUtc => Value::ChronoDateTimeUtc(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-chrono\")]\n        ArrayType::ChronoDateTimeLocal => Value::ChronoDateTimeLocal(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-chrono\")]\n        ArrayType::ChronoDateTimeWithTimeZone => {\n            Value::ChronoDateTimeWithTimeZone(res.try_get(pre, col)?)\n        }\n\n        #[cfg(feature = \"with-time\")]\n        ArrayType::TimeDate => Value::TimeDate(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-time\")]\n        ArrayType::TimeTime => Value::TimeTime(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-time\")]\n        ArrayType::TimeDateTime => Value::TimeDateTime(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-time\")]\n        ArrayType::TimeDateTimeWithTimeZone => {\n            Value::TimeDateTimeWithTimeZone(res.try_get(pre, col)?)\n        }\n\n        #[cfg(feature = \"with-uuid\")]\n        ArrayType::Uuid => Value::Uuid(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-rust_decimal\")]\n        ArrayType::Decimal => Value::Decimal(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-bigdecimal\")]\n        ArrayType::BigDecimal => {\n            Value::BigDecimal(res.try_get::<Option<_>>(pre, col)?.map(Box::new))\n        }\n\n        #[cfg(feature = \"with-ipnetwork\")]\n        ArrayType::IpNetwork => Value::IpNetwork(res.try_get(pre, col)?),\n\n        #[cfg(feature = \"with-mac_address\")]\n        ArrayType::MacAddress => Value::MacAddress(res.try_get(pre, col)?),\n    })\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::{QueryResultRow, database::IntoMockRow, dynamic::Entity};\n\n    #[test]\n    fn test_from_query_result() {\n        let result = QueryResult {\n            row: QueryResultRow::Mock(\n                crate::tests_cfg::cake::Model {\n                    id: 12,\n                    name: \"hello\".into(),\n                }\n                .into_mock_row(),\n            ),\n        };\n        let model_ty = Entity::from_entity(crate::tests_cfg::cake::Entity).to_model_type();\n        assert_eq!(\n            model_ty,\n            ModelType {\n                fields: vec![\n                    FieldType {\n                        field: Arc::from(\"id\"),\n                        type_: ArrayType::Int,\n                    },\n                    FieldType {\n                        field: Arc::from(\"name\"),\n                        type_: ArrayType::String,\n                    },\n                ],\n            }\n        );\n        assert_eq!(\n            model_ty.from_query_result(&result, \"\").unwrap(),\n            Model {\n                fields: vec![\n                    FieldValue {\n                        field: Arc::from(\"id\"),\n                        value: 12i32.into(),\n                    },\n                    FieldValue {\n                        field: Arc::from(\"name\"),\n                        value: \"hello\".into(),\n                    }\n                ],\n            }\n        );\n    }\n}\n"
  },
  {
    "path": "src/entity/ARROW.md",
    "content": "# Apache Arrow Type Support in SeaORM\n\nThis document explains Apache Arrow's decimal and timestamp formats and their integration with SeaORM.\n\n## Arrow Decimal Types Overview\n\nApache Arrow provides fixed-point decimal types for representing precise numeric values with a specific precision and scale:\n\n### 1. **Decimal64**\n- **Storage**: 64-bit (8 bytes) fixed-point decimal\n- **Precision**: Up to 18 decimal digits\n- **Format**: `DataType::Decimal64(precision, scale)`\n  - `precision` (u8): Total number of decimal digits (1-18)\n  - `scale` (i8): Number of digits after decimal point (can be negative)\n- **Use case**: Compact precision decimals that fit in an i64 (e.g., prices, exchange rates)\n- **Example**: `Decimal64(10, 2)` represents numbers like `12345678.90`\n\n### 2. **Decimal128**\n- **Storage**: 128-bit (16 bytes) fixed-point decimal\n- **Precision**: Up to 38 decimal digits\n- **Format**: `DataType::Decimal128(precision, scale)`\n  - `precision` (u8): Total number of decimal digits (1-38)\n  - `scale` (i8): Number of digits after decimal point (can be negative)\n- **Use case**: Standard precision decimals (e.g., financial calculations requiring > 18 digits)\n- **Example**: `Decimal128(20, 4)` represents numbers like `9999999999999999.9999`\n\n### 3. **Decimal256**\n- **Storage**: 256-bit (32 bytes) fixed-point decimal\n- **Precision**: Up to 76 decimal digits\n- **Format**: `DataType::Decimal256(precision, scale)`\n  - `precision` (u8): Total number of decimal digits (1-76)\n  - `scale` (i8): Number of digits after decimal point (can be negative)\n- **Use case**: High-precision scientific calculations, very large numbers\n- **Example**: `Decimal256(76, 20)` for extreme precision requirements\n\n### Precision vs Scale\n\n- **Precision**: Total number of significant digits (before + after decimal point)\n- **Scale**: Number of digits after the decimal point\n  - Positive scale: digits after decimal (e.g., scale=2 → `123.45`)\n  - Zero scale: integer (e.g., scale=0 → `12345`)\n  - Negative scale: multiplier (e.g., scale=-2 → `12300` stored as `123`)\n\n**Examples**:\n```\nDecimal64(10, 2)   → Can store: -99999999.99 to 99999999.99 (compact, i64)\nDecimal64(5, 0)    → Can store: -99999 to 99999 (integers, compact)\nDecimal128(20, 4)  → Can store: -9999999999999999.9999 to 9999999999999999.9999\nDecimal128(10, 4)  → Can store: -999999.9999 to 999999.9999\nDecimal256(38, 10) → High precision: up to 28 digits before, 10 after decimal\n```\n\n## SeaORM Decimal Support\n\nSeaORM supports two Rust decimal libraries:\n\n### 1. **rust_decimal** (feature: `with-rust_decimal`)\n- Type: `rust_decimal::Decimal`\n- Precision: 28-29 significant digits\n- Scale: 0-28\n- Storage: 128-bit\n- Value type: `Value::Decimal`\n- Best for: Most business applications, financial calculations\n\n### 2. **bigdecimal** (feature: `with-bigdecimal`)\n- Type: `bigdecimal::BigDecimal`\n- Precision: Arbitrary (limited by memory)\n- Scale: Arbitrary\n- Storage: Variable (uses BigInt internally)\n- Value type: `Value::BigDecimal`\n- Best for: Arbitrary precision requirements, scientific computing\n\n## Arrow → SeaORM Mapping\n\n### Decimal64Array → rust_decimal::Decimal\n- **When**: Feature `with-rust_decimal` is enabled\n- **Limitation**: Precision ≤ 18 (fits in i64)\n- **Conversion**: Cast i64 to i128, then `Decimal::from_i128_with_scale()`\n- **Column Type**: `ColumnType::Decimal(Some((precision, scale)))`\n\n### Decimal64Array → bigdecimal::BigDecimal\n- **When**: Feature `with-bigdecimal` is enabled (fallback if rust_decimal not available)\n- **Conversion**: Convert i64 via BigInt\n- **Column Type**: `ColumnType::Decimal(Some((precision, scale)))`\n\n### Decimal128Array → rust_decimal::Decimal\n- **When**: Feature `with-rust_decimal` is enabled\n- **Limitation**: Precision ≤ 28, Scale ≤ 28\n- **Conversion**: Direct mapping using `i128` to `Decimal::from_i128_with_scale()`\n- **Column Type**: `ColumnType::Decimal(Some((precision, scale)))`\n\n### Decimal128Array → bigdecimal::BigDecimal\n- **When**: Feature `with-bigdecimal` is enabled (fallback if rust_decimal fails or not available)\n- **Limitation**: None (arbitrary precision)\n- **Conversion**: Convert via BigInt\n- **Column Type**: `ColumnType::Decimal(Some((precision, scale)))` or `ColumnType::Money(_)`\n\n### Decimal256Array → bigdecimal::BigDecimal\n- **When**: Feature `with-bigdecimal` is enabled\n- **Required**: BigDecimal for precision > 38\n- **Conversion**: Convert via byte array to BigInt, then apply scale\n- **Column Type**: `ColumnType::Decimal(Some((precision, scale)))`\n\n## Implementation Strategy\n\n1. **Decimal64Array**:\n   - Try `with-rust_decimal` first (always fits, precision ≤ 18)\n   - Fallback to `with-bigdecimal` if needed\n   - Return type error if neither feature is enabled\n\n2. **Decimal128Array**:\n   - Try `with-rust_decimal` first (if precision/scale fit)\n   - Fallback to `with-bigdecimal` if needed\n   - Return type error if neither feature is enabled\n\n3. **Decimal256Array**:\n   - Requires `with-bigdecimal` (rust_decimal can't handle precision > 28)\n   - Convert byte representation to BigInt\n   - Apply scale to create BigDecimal\n\n4. **Null Handling**:\n   - Return `Value::Decimal(None)` or `Value::BigDecimal(None)` for null values\n\n---\n\n# Apache Arrow Timestamp Types Support\n\nArrow provides several temporal types for representing dates, times, and timestamps with varying precision.\n\n## Arrow Temporal Types Overview\n\n### Date Types\n\n#### 1. **Date32**\n- **Storage**: 32-bit signed integer\n- **Unit**: Days since Unix epoch (1970-01-01)\n- **Format**: `DataType::Date32`\n- **Range**: Approximately ±5.8 million years from epoch\n- **Use case**: Calendar dates without time component\n\n#### 2. **Date64**\n- **Storage**: 64-bit signed integer\n- **Unit**: Milliseconds since Unix epoch\n- **Format**: `DataType::Date64`\n- **Range**: Much larger than Date32\n- **Use case**: Dates with millisecond precision (though time is typically zeroed)\n\n### Time Types\n\n#### 1. **Time32**\n- **Storage**: 32-bit signed integer\n- **Units**: Second or Millisecond\n- **Variants**:\n  - `Time32(TimeUnit::Second)` - seconds since midnight\n  - `Time32(TimeUnit::Millisecond)` - milliseconds since midnight\n- **Range**: 0 to 86,399 seconds (00:00:00 to 23:59:59)\n- **Use case**: Time of day without date\n\n#### 2. **Time64**\n- **Storage**: 64-bit signed integer\n- **Units**: Microsecond or Nanosecond\n- **Variants**:\n  - `Time64(TimeUnit::Microsecond)` - microseconds since midnight\n  - `Time64(TimeUnit::Nanosecond)` - nanoseconds since midnight\n- **Range**: 0 to 86,399,999,999,999 nanoseconds\n- **Use case**: High-precision time of day\n\n### Timestamp Types\n\n**Timestamp** types represent absolute points in time with optional timezone.\n\n- **Storage**: 64-bit signed integer\n- **Units**: Second, Millisecond, Microsecond, or Nanosecond\n- **Timezone**: Optional timezone string (e.g., \"UTC\", \"America/New_York\")\n- **Format**: `Timestamp(TimeUnit, Option<String>)`\n\n**Variants**:\n```rust\nDataType::Timestamp(TimeUnit::Second, None)        // No timezone\nDataType::Timestamp(TimeUnit::Millisecond, None)   // No timezone\nDataType::Timestamp(TimeUnit::Microsecond, None)   // No timezone\nDataType::Timestamp(TimeUnit::Nanosecond, None)    // No timezone\n\nDataType::Timestamp(TimeUnit::Second, Some(\"UTC\".into()))      // With timezone\nDataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into())) // With timezone\nDataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into()))  // With timezone\n```\n\n**TimeUnit Precision**:\n- **Second**: 1 second precision (1,000,000,000 ns)\n- **Millisecond**: 1 millisecond precision (1,000,000 ns)\n- **Microsecond**: 1 microsecond precision (1,000 ns)\n- **Nanosecond**: 1 nanosecond precision (highest)\n\n## SeaORM Temporal Type Support\n\nSeaORM supports two Rust datetime libraries for temporal types:\n\n### 1. **chrono** (feature: `with-chrono`) - Preferred\n- Type Mappings:\n  - `chrono::NaiveDate` - Date without timezone\n  - `chrono::NaiveTime` - Time without date/timezone\n  - `chrono::NaiveDateTime` - DateTime without timezone\n  - `chrono::DateTime<Utc>` - DateTime with UTC timezone\n- Value types:\n  - `Value::ChronoDate(Option<NaiveDate>)`\n  - `Value::ChronoTime(Option<NaiveTime>)`\n  - `Value::ChronoDateTime(Option<NaiveDateTime>)`\n  - `Value::ChronoDateTimeUtc(Option<DateTime<Utc>>)`\n- Best for: Most applications needing date/time support\n\n### 2. **time** (feature: `with-time`) - Alternative\n- Type Mappings:\n  - `time::Date` - Date without timezone\n  - `time::Time` - Time without date/timezone\n  - `time::PrimitiveDateTime` - DateTime without timezone\n  - `time::OffsetDateTime` - DateTime with timezone offset\n- Value types:\n  - `Value::TimeDate(Option<Date>)`\n  - `Value::TimeTime(Option<Time>)`\n  - `Value::TimeDateTime(Option<PrimitiveDateTime>)`\n  - `Value::TimeDateTimeWithTimeZone(Option<OffsetDateTime>)`\n- Best for: Projects preferring the `time` crate ecosystem\n\n### Feature Priority\n- **Both enabled**: Prefers `chrono`, with automatic fallback to `time` if type mismatch\n- **Only chrono**: Uses chrono types exclusively\n- **Only time**: Uses time crate types exclusively\n\n## Arrow → SeaORM Timestamp Mapping\n\n### Date32/Date64Array → Date\n\n**chrono**:\n```rust\nDate32Array → chrono::NaiveDate\nDate64Array → chrono::NaiveDate\n```\n- Conversion: Calculate days from epoch (1970-01-01) and add/subtract\n\n**time**:\n```rust\nDate32Array → time::Date\nDate64Array → time::Date\n```\n- Conversion: Julian day calculation (Unix epoch = Julian day 2,440,588)\n\n### Time32/Time64Array → Time\n\n**chrono**:\n```rust\nTime32(Second)      → chrono::NaiveTime\nTime32(Millisecond) → chrono::NaiveTime\nTime64(Microsecond) → chrono::NaiveTime\nTime64(Nanosecond)  → chrono::NaiveTime\n```\n- Conversion: Break down time units into (hours, minutes, seconds, nanoseconds)\n\n**time**:\n```rust\nTime32(Second)      → time::Time\nTime32(Millisecond) → time::Time\nTime64(Microsecond) → time::Time\nTime64(Nanosecond)  → time::Time\n```\n- Conversion: Extract hours, minutes, seconds, and nanoseconds from total time value\n\n### TimestampArray → DateTime\n\n**Without Timezone**:\n- **Arrow**: `Timestamp(TimeUnit, None)`\n- **chrono**: `→ chrono::NaiveDateTime`\n- **time**: `→ time::PrimitiveDateTime`\n- **Column Type**: `ColumnType::DateTime` or `ColumnType::Timestamp`\n\n**With Timezone**:\n- **Arrow**: `Timestamp(TimeUnit, Some(tz))`\n- **chrono**: `→ chrono::DateTime<Utc>`\n- **time**: `→ time::OffsetDateTime`\n- **Column Type**: `ColumnType::TimestampWithTimeZone`\n\n### Conversion Details by TimeUnit\n\n| TimeUnit | Conversion Method | Precision |\n|----------|-------------------|-----------|\n| **Second** | `from_timestamp(secs, 0)` | 1 second |\n| **Millisecond** | `from_timestamp_millis(ms)` | 1 millisecond |\n| **Microsecond** | `from_timestamp_micros(us)` | 1 microsecond |\n| **Nanosecond** | `from_timestamp_nanos(ns)` or `from_timestamp(secs, nsecs)` | 1 nanosecond |\n\n## References\n\n- [Arrow DataType Documentation](https://docs.rs/arrow/latest/arrow/datatypes/enum.DataType.html)\n- [Arrow Decimal Module](https://arrow.apache.org/rust/arrow_data/decimal/index.html)\n- [Decimal256Type](https://arrow.apache.org/rust/arrow/datatypes/struct.Decimal256Type.html)\n- [Arrow Temporal Types](https://arrow.apache.org/docs/python/api/datatypes.html#temporal-types)\n"
  },
  {
    "path": "src/entity/DESIGN.md",
    "content": "# Design\n\n### Turbofish and inference\n\nConsider the following method:\n```rust\nfn left_join<E>(self) -> Self\nwhere\n    E: EntityTrait,\n{\n    // ...\n}\n```\nwhich has to be invoked like:\n```rust\n.left_join::<fruit::Entity>()\n```\n\nIf we instead do:\n```rust\nfn left_join<E>(self, _: E) -> Self\nwhere\n    E: EntityTrait,\n{\n    // ...\n}\n```\nthen the Turbofish can be omitted:\n```rust\n.left_join(fruit::Entity)\n```\nprovided that `fruit::Entity` is a unit struct.\n\n### Builder pattern\n\nInstead of:\n```rust\nfn has_many(entity: Entity, from: Column, to: Column);\n\nhas_many(cake::Entity, cake::Column::Id, fruit::Column::CakeId)\n```\n\nwe'd prefer having a builder and stating the params explicitly:\n```rust\nhas_many(cake::Entity).from(cake::Column::Id).to(fruit::Column::CakeId)\n```\n\n### Method overloading\n\nConsider the following two methods, which accept the same parameter but in different forms:\n\n```rust\nfn method_with_model(m: Model) { ... }\nfn method_with_active_model(a: ActiveModel) { ... }\n```\n\nWe would define a trait\n\n```rust\npub trait IntoActiveModel {\n    fn into_active_model(self) -> ActiveModel;\n}\n```\n\nSuch that `Model` and `ActiveModel` both impl this trait.\n\nIn this way, we can overload the two methods:\n\n```rust\npub fn method<A>(a: A)\nwhere\n    A: IntoActiveModel,\n{\n    let a: ActiveModel = a.into_active_model();\n    ...\n}\n```\n"
  },
  {
    "path": "src/entity/active_enum.rs",
    "content": "use crate::{ColIdx, ColumnDef, DbErr, Iterable, QueryResult, TryFromU64, TryGetError, TryGetable};\nuse sea_query::{DynIden, Expr, ExprTrait, Nullable, SimpleExpr, Value, ValueType};\n\n/// A Rust representation of enum defined in database.\n///\n/// # Implementations\n///\n/// You can implement [ActiveEnum] manually by hand or use the derive macro [DeriveActiveEnum](sea_orm_macros::DeriveActiveEnum).\n///\n/// # Examples\n///\n/// Implementing it manually versus using the derive macro [DeriveActiveEnum](sea_orm_macros::DeriveActiveEnum).\n///\n/// > See [DeriveActiveEnum](sea_orm_macros::DeriveActiveEnum) for the full specification of macro attributes.\n///\n/// ```rust\n/// use sea_orm::entity::prelude::*;\n///\n/// // Using the derive macro\n/// #[derive(Debug, PartialEq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n/// #[sea_orm(\n///     rs_type = \"String\",\n///     db_type = \"String(StringLen::N(1))\",\n///     enum_name = \"category\"\n/// )]\n/// pub enum DeriveCategory {\n///     #[sea_orm(string_value = \"B\")]\n///     Big,\n///     #[sea_orm(string_value = \"S\")]\n///     Small,\n/// }\n///\n/// // Implementing it manually\n/// #[derive(Debug, PartialEq, EnumIter)]\n/// pub enum Category {\n///     Big,\n///     Small,\n/// }\n///\n/// #[derive(Debug, DeriveIden)]\n/// pub struct CategoryEnum;\n///\n/// impl ActiveEnum for Category {\n///     // The macro attribute `rs_type` is being pasted here\n///     type Value = String;\n///\n///     type ValueVec = Vec<String>;\n///\n///     // Will be atomically generated by `DeriveActiveEnum`\n///     fn name() -> DynIden {\n///         SeaRc::new(CategoryEnum)\n///     }\n///\n///     // Will be atomically generated by `DeriveActiveEnum`\n///     fn to_value(&self) -> Self::Value {\n///         match self {\n///             Self::Big => \"B\",\n///             Self::Small => \"S\",\n///         }\n///         .to_owned()\n///     }\n///\n///     // Will be atomically generated by `DeriveActiveEnum`\n///     fn try_from_value(v: &Self::Value) -> Result<Self, DbErr> {\n///         match v.as_ref() {\n///             \"B\" => Ok(Self::Big),\n///             \"S\" => Ok(Self::Small),\n///             _ => Err(DbErr::Type(format!(\n///                 \"unexpected value for Category enum: {}\",\n///                 v\n///             ))),\n///         }\n///     }\n///\n///     fn db_type() -> ColumnDef {\n///         // The macro attribute `db_type` is being pasted here\n///         ColumnType::String(StringLen::N(1)).def()\n///     }\n/// }\n/// ```\n///\n/// Using [ActiveEnum] on Model.\n///\n/// ```\n/// use sea_orm::entity::prelude::*;\n///\n/// // Define the `Category` active enum\n/// #[derive(Debug, Clone, PartialEq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n/// #[sea_orm(rs_type = \"String\", db_type = \"String(StringLen::N(1))\")]\n/// pub enum Category {\n///     #[sea_orm(string_value = \"B\")]\n///     Big,\n///     #[sea_orm(string_value = \"S\")]\n///     Small,\n/// }\n///\n/// #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #[sea_orm(table_name = \"active_enum\")]\n/// pub struct Model {\n///     #[sea_orm(primary_key)]\n///     pub id: i32,\n///     // Represents a db column using `Category` active enum\n///     pub category: Category,\n///     pub category_opt: Option<Category>,\n/// }\n///\n/// #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n/// pub enum Relation {}\n///\n/// impl ActiveModelBehavior for ActiveModel {}\n/// ```\npub trait ActiveEnum: Sized + Iterable {\n    /// Define the Rust type that each enum variant corresponds.\n    type Value: ActiveEnumValue;\n\n    /// This has no purpose. It will be removed in the next major version.\n    type ValueVec;\n\n    /// Get the name of enum\n    fn name() -> DynIden;\n\n    /// Convert enum variant into the corresponding value.\n    fn to_value(&self) -> Self::Value;\n\n    /// Try to convert the corresponding value into enum variant.\n    fn try_from_value(v: &Self::Value) -> Result<Self, DbErr>;\n\n    /// Get the database column definition of this active enum.\n    fn db_type() -> ColumnDef;\n\n    /// Convert an owned enum variant into the corresponding value.\n    fn into_value(self) -> Self::Value {\n        Self::to_value(&self)\n    }\n\n    /// Construct a enum expression with casting\n    fn as_enum(&self) -> SimpleExpr {\n        Expr::val(Self::to_value(self)).as_enum(Self::name())\n    }\n\n    /// Get the name of all enum variants\n    fn values() -> Vec<Self::Value> {\n        Self::iter().map(Self::into_value).collect()\n    }\n}\n\n/// The Rust Value backing ActiveEnums\npub trait ActiveEnumValue: Into<Value> + ValueType + Nullable + TryGetable {\n    /// For getting an array of enum. Postgres only\n    fn try_get_vec_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Vec<Self>, TryGetError>;\n}\n\nmacro_rules! impl_active_enum_value {\n    ($type:ident) => {\n        impl ActiveEnumValue for $type {\n            fn try_get_vec_by<I: ColIdx>(\n                _res: &QueryResult,\n                _index: I,\n            ) -> Result<Vec<Self>, TryGetError> {\n                Err(TryGetError::DbErr(DbErr::BackendNotSupported {\n                    db: \"Postgres\",\n                    ctx: \"ActiveEnumValue::try_get_vec_by\",\n                }))\n            }\n        }\n    };\n}\n\nmacro_rules! impl_active_enum_value_with_pg_array {\n    ($type:ident) => {\n        impl ActiveEnumValue for $type {\n            fn try_get_vec_by<I: ColIdx>(\n                _res: &QueryResult,\n                _index: I,\n            ) -> Result<Vec<Self>, TryGetError> {\n                #[cfg(feature = \"postgres-array\")]\n                {\n                    <Vec<Self>>::try_get_by(_res, _index)\n                }\n                #[cfg(not(feature = \"postgres-array\"))]\n                Err(TryGetError::DbErr(DbErr::BackendNotSupported {\n                    db: \"Postgres\",\n                    ctx: \"ActiveEnumValue::try_get_vec_by (`postgres-array` not enabled)\",\n                }))\n            }\n        }\n    };\n}\n\nimpl_active_enum_value!(u8);\nimpl_active_enum_value!(u16);\nimpl_active_enum_value!(u32);\nimpl_active_enum_value!(u64);\nimpl_active_enum_value_with_pg_array!(String);\nimpl_active_enum_value_with_pg_array!(i8);\nimpl_active_enum_value_with_pg_array!(i16);\nimpl_active_enum_value_with_pg_array!(i32);\nimpl_active_enum_value_with_pg_array!(i64);\n\nimpl<T> TryFromU64 for T\nwhere\n    T: ActiveEnum,\n{\n    fn try_from_u64(_: u64) -> Result<Self, DbErr> {\n        Err(DbErr::ConvertFromU64(\n            \"Fail to construct ActiveEnum from a u64, if your primary key consist of a ActiveEnum field, its auto increment should be set to false.\",\n        ))\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate as sea_orm;\n    use crate::{\n        error::*,\n        sea_query::{SeaRc, StringLen},\n        *,\n    };\n    use pretty_assertions::assert_eq;\n\n    #[test]\n    fn active_enum_string() {\n        #[derive(Debug, PartialEq, Eq, EnumIter)]\n        pub enum Category {\n            Big,\n            Small,\n        }\n\n        #[derive(Debug, DeriveIden)]\n        #[sea_orm(iden = \"category\")]\n        pub struct CategoryEnum;\n\n        impl ActiveEnum for Category {\n            type Value = String;\n\n            type ValueVec = Vec<String>;\n\n            fn name() -> DynIden {\n                SeaRc::new(CategoryEnum)\n            }\n\n            fn to_value(&self) -> Self::Value {\n                match self {\n                    Self::Big => \"B\",\n                    Self::Small => \"S\",\n                }\n                .to_owned()\n            }\n\n            fn try_from_value(v: &Self::Value) -> Result<Self, DbErr> {\n                match v.as_ref() {\n                    \"B\" => Ok(Self::Big),\n                    \"S\" => Ok(Self::Small),\n                    _ => Err(type_err(format!(\"unexpected value for Category enum: {v}\"))),\n                }\n            }\n\n            fn db_type() -> ColumnDef {\n                ColumnType::String(StringLen::N(1)).def()\n            }\n        }\n\n        #[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n        #[sea_orm(\n            rs_type = \"String\",\n            db_type = \"String(StringLen::N(1))\",\n            enum_name = \"category\"\n        )]\n        pub enum DeriveCategory {\n            #[sea_orm(string_value = \"B\")]\n            Big,\n            #[sea_orm(string_value = \"S\")]\n            Small,\n        }\n\n        assert_eq!(Category::Big.to_value(), \"B\".to_owned());\n        assert_eq!(Category::Small.to_value(), \"S\".to_owned());\n        assert_eq!(DeriveCategory::Big.to_value(), \"B\".to_owned());\n        assert_eq!(DeriveCategory::Small.to_value(), \"S\".to_owned());\n\n        assert_eq!(\n            Category::try_from_value(&\"A\".to_owned()).err(),\n            Some(type_err(\"unexpected value for Category enum: A\"))\n        );\n        assert_eq!(\n            Category::try_from_value(&\"B\".to_owned()).ok(),\n            Some(Category::Big)\n        );\n        assert_eq!(\n            Category::try_from_value(&\"S\".to_owned()).ok(),\n            Some(Category::Small)\n        );\n        assert_eq!(\n            DeriveCategory::try_from_value(&\"A\".to_owned()).err(),\n            Some(type_err(\"unexpected value for DeriveCategory enum: A\"))\n        );\n        assert_eq!(\n            DeriveCategory::try_from_value(&\"B\".to_owned()).ok(),\n            Some(DeriveCategory::Big)\n        );\n        assert_eq!(\n            DeriveCategory::try_from_value(&\"S\".to_owned()).ok(),\n            Some(DeriveCategory::Small)\n        );\n\n        assert_eq!(\n            Category::db_type(),\n            ColumnType::String(StringLen::N(1)).def()\n        );\n        assert_eq!(\n            DeriveCategory::db_type(),\n            ColumnType::String(StringLen::N(1)).def()\n        );\n\n        assert_eq!(\n            Category::name().to_string(),\n            DeriveCategory::name().to_string()\n        );\n        assert_eq!(Category::values(), DeriveCategory::values());\n\n        assert_eq!(format!(\"{}\", DeriveCategory::Big), \"Big\");\n        assert_eq!(format!(\"{}\", DeriveCategory::Small), \"Small\");\n    }\n\n    #[test]\n    fn active_enum_derive_signed_integers() {\n        macro_rules! test_num_value_int {\n            ($ident: ident, $rs_type: expr, $db_type: expr, $col_def: ident) => {\n                #[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n                #[sea_orm(rs_type = $rs_type, db_type = $db_type)]\n                pub enum $ident {\n                    #[sea_orm(num_value = -10)]\n                    Negative,\n                    #[sea_orm(num_value = 1)]\n                    Big,\n                    #[sea_orm(num_value = 0)]\n                    Small,\n                }\n\n                test_int!($ident, $rs_type, $db_type, $col_def);\n            };\n        }\n\n        macro_rules! test_fallback_int {\n            ($ident: ident, $fallback_type: ident, $rs_type: expr, $db_type: expr, $col_def: ident) => {\n                #[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n                #[sea_orm(rs_type = $rs_type, db_type = $db_type)]\n                #[repr(i32)]\n                pub enum $ident {\n                    Big = 1,\n                    Small = 0,\n                    Negative = -10,\n                }\n\n                test_int!($ident, $rs_type, $db_type, $col_def);\n            };\n        }\n\n        macro_rules! test_int {\n            ($ident: ident, $rs_type: expr, $db_type: expr, $col_def: ident) => {\n                assert_eq!($ident::Big.to_value(), 1);\n                assert_eq!($ident::Small.to_value(), 0);\n                assert_eq!($ident::Negative.to_value(), -10);\n\n                assert_eq!($ident::try_from_value(&1).ok(), Some($ident::Big));\n                assert_eq!($ident::try_from_value(&0).ok(), Some($ident::Small));\n                assert_eq!($ident::try_from_value(&-10).ok(), Some($ident::Negative));\n                assert_eq!(\n                    $ident::try_from_value(&2).err(),\n                    Some(type_err(format!(\n                        \"unexpected value for {} enum: 2\",\n                        stringify!($ident)\n                    )))\n                );\n\n                assert_eq!($ident::db_type(), ColumnType::$col_def.def());\n\n                assert_eq!(format!(\"{}\", $ident::Big), \"Big\");\n                assert_eq!(format!(\"{}\", $ident::Small), \"Small\");\n                assert_eq!(format!(\"{}\", $ident::Negative), \"Negative\");\n            };\n        }\n\n        test_num_value_int!(I8, \"i8\", \"TinyInteger\", TinyInteger);\n        test_num_value_int!(I16, \"i16\", \"SmallInteger\", SmallInteger);\n        test_num_value_int!(I32, \"i32\", \"Integer\", Integer);\n        test_num_value_int!(I64, \"i64\", \"BigInteger\", BigInteger);\n\n        test_fallback_int!(I8Fallback, i8, \"i8\", \"TinyInteger\", TinyInteger);\n        test_fallback_int!(I16Fallback, i16, \"i16\", \"SmallInteger\", SmallInteger);\n        test_fallback_int!(I32Fallback, i32, \"i32\", \"Integer\", Integer);\n        test_fallback_int!(I64Fallback, i64, \"i64\", \"BigInteger\", BigInteger);\n    }\n\n    #[test]\n    fn active_enum_derive_unsigned_integers() {\n        macro_rules! test_num_value_uint {\n            ($ident: ident, $rs_type: expr, $db_type: expr, $col_def: ident) => {\n                #[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n                #[sea_orm(rs_type = $rs_type, db_type = $db_type)]\n                pub enum $ident {\n                    #[sea_orm(num_value = 1)]\n                    Big,\n                    #[sea_orm(num_value = 0)]\n                    Small,\n                }\n\n                test_uint!($ident, $rs_type, $db_type, $col_def);\n            };\n        }\n\n        macro_rules! test_fallback_uint {\n            ($ident: ident, $fallback_type: ident, $rs_type: expr, $db_type: expr, $col_def: ident) => {\n                #[derive(Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n                #[sea_orm(rs_type = $rs_type, db_type = $db_type)]\n                #[repr($fallback_type)]\n                pub enum $ident {\n                    Big = 1,\n                    Small = 0,\n                }\n\n                test_uint!($ident, $rs_type, $db_type, $col_def);\n            };\n        }\n\n        macro_rules! test_uint {\n            ($ident: ident, $rs_type: expr, $db_type: expr, $col_def: ident) => {\n                assert_eq!($ident::Big.to_value(), 1);\n                assert_eq!($ident::Small.to_value(), 0);\n\n                assert_eq!($ident::try_from_value(&1).ok(), Some($ident::Big));\n                assert_eq!($ident::try_from_value(&0).ok(), Some($ident::Small));\n                assert_eq!(\n                    $ident::try_from_value(&2).err(),\n                    Some(type_err(format!(\n                        \"unexpected value for {} enum: 2\",\n                        stringify!($ident)\n                    )))\n                );\n\n                assert_eq!($ident::db_type(), ColumnType::$col_def.def());\n\n                assert_eq!(format!(\"{}\", $ident::Big), \"Big\");\n                assert_eq!(format!(\"{}\", $ident::Small), \"Small\");\n            };\n        }\n\n        test_num_value_uint!(U8, \"u8\", \"TinyInteger\", TinyInteger);\n        test_num_value_uint!(U16, \"u16\", \"SmallInteger\", SmallInteger);\n        test_num_value_uint!(U32, \"u32\", \"Integer\", Integer);\n        test_num_value_uint!(U64, \"u64\", \"BigInteger\", BigInteger);\n\n        test_fallback_uint!(U8Fallback, u8, \"u8\", \"TinyInteger\", TinyInteger);\n        test_fallback_uint!(U16Fallback, u16, \"u16\", \"SmallInteger\", SmallInteger);\n        test_fallback_uint!(U32Fallback, u32, \"u32\", \"Integer\", Integer);\n        test_fallback_uint!(U64Fallback, u64, \"u64\", \"BigInteger\", BigInteger);\n    }\n\n    #[test]\n    fn escaped_non_uax31() {\n        #[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Copy)]\n        #[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"pop_os_names_typos\")]\n        pub enum PopOSTypos {\n            #[sea_orm(string_value = \"Pop!_OS\")]\n            PopOSCorrect,\n            #[sea_orm(string_value = \"Pop\\u{2757}_OS\")]\n            PopOSEmoji,\n            #[sea_orm(string_value = \"Pop!_操作系统\")]\n            PopOSChinese,\n            #[sea_orm(string_value = \"PopOS\")]\n            PopOSASCIIOnly,\n            #[sea_orm(string_value = \"Pop OS\")]\n            PopOSASCIIOnlyWithSpace,\n            #[sea_orm(string_value = \"Pop!OS\")]\n            PopOSNoUnderscore,\n            #[sea_orm(string_value = \"Pop_OS\")]\n            PopOSNoExclaimation,\n            #[sea_orm(string_value = \"!PopOS_\")]\n            PopOSAllOverThePlace,\n            #[sea_orm(string_value = \"Pop!_OS22.04LTS\")]\n            PopOSWithVersion,\n            #[sea_orm(string_value = \"22.04LTSPop!_OS\")]\n            PopOSWithVersionPrefix,\n            #[sea_orm(string_value = \"!_\")]\n            PopOSJustTheSymbols,\n            #[sea_orm(string_value = \"\")]\n            Nothing,\n            // This WILL fail:\n            // Both PopOs and PopOS will create identifier \"Popos\"\n            // #[sea_orm(string_value = \"PopOs\")]\n            // PopOSLowerCase,\n        }\n        let values = [\n            \"Pop!_OS\",\n            \"Pop\\u{2757}_OS\",\n            \"Pop!_操作系统\",\n            \"PopOS\",\n            \"Pop OS\",\n            \"Pop!OS\",\n            \"Pop_OS\",\n            \"!PopOS_\",\n            \"Pop!_OS22.04LTS\",\n            \"22.04LTSPop!_OS\",\n            \"!_\",\n            \"\",\n        ];\n        for (variant, val) in PopOSTypos::iter().zip(values) {\n            assert_eq!(variant.to_value(), val);\n            assert_eq!(PopOSTypos::try_from_value(&val.to_owned()), Ok(variant));\n        }\n\n        #[derive(Clone, Debug, PartialEq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n        #[sea_orm(\n            rs_type = \"String\",\n            db_type = \"String(StringLen::None)\",\n            enum_name = \"conflicting_string_values\"\n        )]\n        pub enum ConflictingStringValues {\n            #[sea_orm(string_value = \"\")]\n            Member1,\n            #[sea_orm(string_value = \"$\")]\n            Member2,\n            #[sea_orm(string_value = \"$$\")]\n            Member3,\n            #[sea_orm(string_value = \"AB\")]\n            Member4,\n            #[sea_orm(string_value = \"A_B\")]\n            Member5,\n            #[sea_orm(string_value = \"A$B\")]\n            Member6,\n            #[sea_orm(string_value = \"0 123\")]\n            Member7,\n        }\n        type EnumVariant = ConflictingStringValuesVariant;\n        assert_eq!(EnumVariant::__Empty.to_string(), \"\");\n        assert_eq!(EnumVariant::_0x24.to_string(), \"$\");\n        assert_eq!(EnumVariant::_0x240x24.to_string(), \"$$\");\n        assert_eq!(EnumVariant::Ab.to_string(), \"AB\");\n        assert_eq!(EnumVariant::A0x5Fb.to_string(), \"A_B\");\n        assert_eq!(EnumVariant::A0x24B.to_string(), \"A$B\");\n        assert_eq!(EnumVariant::_0x300x20123.to_string(), \"0 123\");\n    }\n\n    #[test]\n    fn test_derive_display() {\n        use crate::DeriveDisplay;\n\n        #[derive(DeriveDisplay)]\n        enum DisplayTea {\n            EverydayTea,\n            #[sea_orm(display_value = \"Breakfast Tea\")]\n            BreakfastTea,\n        }\n        assert_eq!(format!(\"{}\", DisplayTea::EverydayTea), \"EverydayTea\");\n        assert_eq!(format!(\"{}\", DisplayTea::BreakfastTea), \"Breakfast Tea\");\n    }\n}\n"
  },
  {
    "path": "src/entity/active_model.rs",
    "content": "use super::{ActiveValue, ActiveValue::*};\nuse crate::{\n    ColumnTrait, Condition, ConnectionTrait, DbBackend, DeleteResult, EntityName, EntityTrait,\n    IdenStatic, Iterable, PrimaryKeyArity, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter,\n    Related, RelatedSelfVia, RelationDef, RelationTrait, Value,\n    error::*,\n    query::{\n        clear_key_on_active_model, column_tuple_in_condition, get_key_from_active_model,\n        set_key_on_active_model,\n    },\n};\nuse sea_query::ValueTuple;\nuse std::fmt::Debug;\n\n/// `ActiveModel` is a type for constructing `INSERT` and `UPDATE` statements for a particular table.\n///\n/// Like [Model][ModelTrait], it represents a database record and each field represents a column.\n///\n/// But unlike [Model][ModelTrait], it also stores [additional state][ActiveValue] for every field,\n/// and fields are not guaranteed to have a value.\n///\n/// This allows you to:\n///\n/// - omit columns from the query,\n/// - know which columns have changed after editing a record.\n#[async_trait::async_trait]\npub trait ActiveModelTrait: Clone + Debug {\n    /// The Entity this ActiveModel belongs to\n    type Entity: EntityTrait;\n\n    /// Get a mutable [ActiveValue] from an ActiveModel\n    fn take(&mut self, c: <Self::Entity as EntityTrait>::Column) -> ActiveValue<Value>;\n\n    /// Get a immutable [ActiveValue] from an ActiveModel\n    fn get(&self, c: <Self::Entity as EntityTrait>::Column) -> ActiveValue<Value>;\n\n    /// Set the Value of a ActiveModel field, panic if failed\n    fn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) {\n        self.try_set(c, v)\n            .unwrap_or_else(|e| panic!(\"Failed to set value for {:?}: {e:?}\", c.as_column_ref()))\n    }\n\n    /// Set the Value of a ActiveModel field if value is different, panic if failed\n    fn set_if_not_equals(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value);\n\n    /// Set the Value of a ActiveModel field, return error if failed\n    fn try_set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) -> Result<(), DbErr>;\n\n    /// Set the state of an [ActiveValue] to the not set state\n    fn not_set(&mut self, c: <Self::Entity as EntityTrait>::Column);\n\n    /// Check the state of a [ActiveValue]\n    fn is_not_set(&self, c: <Self::Entity as EntityTrait>::Column) -> bool;\n\n    /// Create an ActiveModel with all fields to NotSet\n    fn default() -> Self;\n\n    /// Create an ActiveModel with all fields to Set(default_value) if Default is implemented, NotSet otherwise\n    fn default_values() -> Self;\n\n    /// Reset the value from [ActiveValue::Unchanged] to [ActiveValue::Set],\n    /// leaving [ActiveValue::NotSet] untouched.\n    fn reset(&mut self, c: <Self::Entity as EntityTrait>::Column);\n\n    /// Reset all values from [ActiveValue::Unchanged] to [ActiveValue::Set],\n    /// leaving [ActiveValue::NotSet] untouched.\n    fn reset_all(mut self) -> Self {\n        for col in <Self::Entity as EntityTrait>::Column::iter() {\n            self.reset(col);\n        }\n        self\n    }\n\n    /// Get the primary key of the ActiveModel, only if it's fully specified.\n    fn get_primary_key_value(&self) -> Option<ValueTuple> {\n        let mut cols = <Self::Entity as EntityTrait>::PrimaryKey::iter();\n        macro_rules! next {\n            () => {\n                self.get(cols.next()?.into_column()).into_value()?\n            };\n        }\n        match <<<Self::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n            1 => {\n                let s1 = next!();\n                Some(ValueTuple::One(s1))\n            }\n            2 => {\n                let s1 = next!();\n                let s2 = next!();\n                Some(ValueTuple::Two(s1, s2))\n            }\n            3 => {\n                let s1 = next!();\n                let s2 = next!();\n                let s3 = next!();\n                Some(ValueTuple::Three(s1, s2, s3))\n            }\n            len => {\n                let mut vec = Vec::with_capacity(len);\n                for _ in 0..len {\n                    let s = next!();\n                    vec.push(s);\n                }\n                Some(ValueTuple::Many(vec))\n            }\n        }\n    }\n\n    /// Perform an `INSERT` operation on the ActiveModel\n    ///\n    /// # Example (Postgres)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 15,\n    /// #             name: \"Apple Pie\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let apple = cake::ActiveModel {\n    ///     name: Set(\"Apple Pie\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// assert_eq!(\n    ///     apple.insert(&db).await?,\n    ///     cake::Model {\n    ///         id: 15,\n    ///         name: \"Apple Pie\".to_owned(),\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"INSERT INTO \"cake\" (\"name\") VALUES ($1) RETURNING \"id\", \"name\"\"#,\n    ///         [\"Apple Pie\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// # Example (MySQL)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::MySql)\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 15,\n    /// #             name: \"Apple Pie\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 15,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let apple = cake::ActiveModel {\n    ///     name: Set(\"Apple Pie\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// assert_eq!(\n    ///     apple.insert(&db).await?,\n    ///     cake::Model {\n    ///         id: 15,\n    ///         name: \"Apple Pie\".to_owned(),\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::MySql,\n    ///             r#\"INSERT INTO `cake` (`name`) VALUES (?)\"#,\n    ///             [\"Apple Pie\".into()]\n    ///         ),\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::MySql,\n    ///             r#\"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = ? LIMIT ?\"#,\n    ///             [15.into(), 1u64.into()]\n    ///         )\n    ///     ]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    async fn insert<'a, C>(self, db: &'a C) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>\n    where\n        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,\n        Self: ActiveModelBehavior,\n        C: ConnectionTrait,\n    {\n        let am = ActiveModelBehavior::before_save(self, db, true).await?;\n        let model = <Self::Entity as EntityTrait>::insert(am)\n            .exec_with_returning(db)\n            .await?;\n        Self::after_save(model, db, true).await\n    }\n\n    /// Perform the `UPDATE` operation on an ActiveModel\n    ///\n    /// # Example (Postgres)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [fruit::Model {\n    /// #             id: 1,\n    /// #             name: \"Orange\".to_owned(),\n    /// #             cake_id: None,\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let orange = fruit::ActiveModel {\n    ///     id: Set(1),\n    ///     name: Set(\"Orange\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// assert_eq!(\n    ///     orange.update(&db).await?,\n    ///     fruit::Model {\n    ///         id: 1,\n    ///         name: \"Orange\".to_owned(),\n    ///         cake_id: None,\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"UPDATE \"fruit\" SET \"name\" = $1 WHERE \"fruit\".\"id\" = $2 RETURNING \"id\", \"name\", \"cake_id\"\"#,\n    ///         [\"Orange\".into(), 1i32.into()]\n    ///     )]);\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// # Example (MySQL)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::MySql)\n    /// #     .append_query_results([\n    /// #         [fruit::Model {\n    /// #             id: 1,\n    /// #             name: \"Orange\".to_owned(),\n    /// #             cake_id: None,\n    /// #         }],\n    /// #     ])\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let orange = fruit::ActiveModel {\n    ///     id: Set(1),\n    ///     name: Set(\"Orange\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// assert_eq!(\n    ///     orange.update(&db).await?,\n    ///     fruit::Model {\n    ///         id: 1,\n    ///         name: \"Orange\".to_owned(),\n    ///         cake_id: None,\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::MySql,\n    ///             r#\"UPDATE `fruit` SET `name` = ? WHERE `fruit`.`id` = ?\"#,\n    ///             [\"Orange\".into(), 1i32.into()]\n    ///         ),\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::MySql,\n    ///             r#\"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = ? LIMIT ?\"#,\n    ///             [1i32.into(), 1u64.into()]\n    ///         )]);\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    async fn update<'a, C>(self, db: &'a C) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>\n    where\n        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,\n        Self: ActiveModelBehavior,\n        C: ConnectionTrait,\n    {\n        let am = ActiveModelBehavior::before_save(self, db, false).await?;\n        let model: <Self::Entity as EntityTrait>::Model = Self::Entity::update(am).exec(db).await?;\n        Self::after_save(model, db, false).await\n    }\n\n    /// Insert the model if primary key is `NotSet`, update otherwise.\n    /// Only works if the entity has auto increment primary key.\n    async fn save<'a, C>(self, db: &'a C) -> Result<Self, DbErr>\n    where\n        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,\n        Self: ActiveModelBehavior,\n        C: ConnectionTrait,\n    {\n        let res = if !self.is_update() {\n            self.insert(db).await\n        } else {\n            self.update(db).await\n        }?;\n        Ok(res.into_active_model())\n    }\n\n    /// Returns true if the primary key is fully-specified\n    #[doc(hidden)]\n    fn is_update(&self) -> bool {\n        let mut is_update = true;\n        for key in <Self::Entity as EntityTrait>::PrimaryKey::iter() {\n            let col = key.into_column();\n            if self.is_not_set(col) {\n                is_update = false;\n                break;\n            }\n        }\n        is_update\n    }\n\n    /// Delete an active model by its primary key\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let orange = fruit::ActiveModel {\n    ///     id: Set(3),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// let delete_result = orange.delete(&db).await?;\n    ///\n    /// assert_eq!(delete_result.rows_affected, 1);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"DELETE FROM \"fruit\" WHERE \"fruit\".\"id\" = $1\"#,\n    ///         [3i32.into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    async fn delete<'a, C>(self, db: &'a C) -> Result<DeleteResult, DbErr>\n    where\n        Self: ActiveModelBehavior,\n        C: ConnectionTrait,\n    {\n        let am = ActiveModelBehavior::before_delete(self, db).await?;\n        let am_clone = am.clone();\n        let delete_res = Self::Entity::delete(am).exec(db).await?;\n        ActiveModelBehavior::after_delete(am_clone, db).await?;\n        Ok(delete_res)\n    }\n\n    /// Set the corresponding attributes in the ActiveModel from a JSON value\n    ///\n    /// Note that this method will not alter the primary key values in ActiveModel.\n    #[cfg(feature = \"with-json\")]\n    fn set_from_json(&mut self, json: serde_json::Value) -> Result<(), DbErr>\n    where\n        Self: crate::TryIntoModel<<Self::Entity as EntityTrait>::Model>,\n        <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self>,\n        for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model:\n            serde::de::Deserialize<'de> + serde::Serialize,\n    {\n        use crate::Iterable;\n\n        // Backup primary key values\n        let primary_key_values: Vec<(<Self::Entity as EntityTrait>::Column, ActiveValue<Value>)> =\n            <<Self::Entity as EntityTrait>::PrimaryKey>::iter()\n                .map(|pk| (pk.into_column(), self.take(pk.into_column())))\n                .collect();\n\n        // Replace all values in ActiveModel\n        *self = Self::from_json(json)?;\n\n        // Restore primary key values\n        for (col, active_value) in primary_key_values {\n            match active_value {\n                ActiveValue::Unchanged(v) | ActiveValue::Set(v) => self.set(col, v),\n                NotSet => self.not_set(col),\n            }\n        }\n\n        Ok(())\n    }\n\n    /// Create ActiveModel from a JSON value\n    #[cfg(feature = \"with-json\")]\n    fn from_json(mut json: serde_json::Value) -> Result<Self, DbErr>\n    where\n        Self: crate::TryIntoModel<<Self::Entity as EntityTrait>::Model>,\n        <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model: IntoActiveModel<Self>,\n        for<'de> <<Self as ActiveModelTrait>::Entity as EntityTrait>::Model:\n            serde::de::Deserialize<'de> + serde::Serialize,\n    {\n        use crate::{IdenStatic, Iterable};\n\n        let serde_json::Value::Object(obj) = &json else {\n            return Err(DbErr::Json(format!(\n                \"invalid type: expected JSON object for {}\",\n                <<Self as ActiveModelTrait>::Entity as IdenStatic>::as_str(&Default::default())\n            )));\n        };\n\n        // Mark down which attribute exists in the JSON object\n        let mut json_keys: Vec<(<Self::Entity as EntityTrait>::Column, bool)> = Vec::new();\n\n        for col in <<Self::Entity as EntityTrait>::Column>::iter() {\n            let key = col.json_key();\n            let has_key = obj.contains_key(key);\n            json_keys.push((col, has_key));\n        }\n\n        // Create dummy model with dummy values\n        let dummy_model = Self::default_values();\n        if let Ok(dummy_model) = dummy_model.try_into_model() {\n            if let Ok(mut dummy_json) = serde_json::to_value(&dummy_model) {\n                let serde_json::Value::Object(merged) = &mut dummy_json else {\n                    unreachable!();\n                };\n                let serde_json::Value::Object(obj) = json else {\n                    unreachable!();\n                };\n                // overwrite dummy values with input values\n                for (key, value) in obj {\n                    merged.insert(key, value);\n                }\n                json = dummy_json;\n            }\n        }\n\n        // Convert JSON object into ActiveModel via Model\n        let model: <Self::Entity as EntityTrait>::Model =\n            serde_json::from_value(json).map_err(json_err)?;\n        let mut am = model.into_active_model();\n\n        // Transform attribute that exists in JSON object into ActiveValue::Set, otherwise ActiveValue::NotSet\n        for (col, json_key_exists) in json_keys {\n            match (json_key_exists, am.get(col)) {\n                (true, ActiveValue::Set(value) | ActiveValue::Unchanged(value)) => {\n                    am.set(col, value);\n                }\n                _ => {\n                    am.not_set(col);\n                }\n            }\n        }\n\n        Ok(am)\n    }\n\n    /// Create a Vec of ActiveModels from an Arrow RecordBatch.\n    ///\n    /// Each row in the RecordBatch becomes one ActiveModel.\n    /// Columns are matched by name (using [`ColumnTrait::as_str`](crate::ColumnTrait::as_str)).\n    /// Columns present in the RecordBatch are marked as `Set`;\n    /// columns absent from the RecordBatch are marked as `NotSet`.\n    ///\n    /// Supported column types: integers (i8–i64, u8–u64), floats (f32, f64),\n    /// `String`/`Text`, `Boolean`, and date/time types (with `with-chrono` or `with-time`).\n    /// Null values in nullable columns are handled.\n    ///\n    /// When both `with-chrono` and `with-time` features are enabled, chrono values\n    /// are attempted first. If the model uses time-crate types, the conversion\n    /// automatically falls back to the time-crate representation.\n    #[cfg(feature = \"with-arrow\")]\n    fn from_arrow(batch: &sea_orm_arrow::arrow::array::RecordBatch) -> Result<Vec<Self>, DbErr> {\n        use crate::{IdenStatic, Iterable, with_arrow::arrow_array_to_value};\n\n        let num_rows = batch.num_rows();\n        let mut results = Vec::with_capacity(num_rows);\n\n        for row in 0..num_rows {\n            let mut am = Self::default();\n\n            for col in <<Self::Entity as EntityTrait>::Column>::iter() {\n                let col_name = col.as_str();\n\n                if let Some(arrow_col) = batch.column_by_name(col_name) {\n                    let col_def = col.def();\n                    let col_type = col_def.get_column_type();\n                    let value = arrow_array_to_value(arrow_col.as_ref(), col_type, row)?;\n\n                    // When both chrono and time features are enabled, the primary\n                    // conversion produces chrono Values for date/time columns.\n                    // If the model's field uses time-crate types, try_set will fail;\n                    // retry with the time-crate alternative.\n                    #[cfg(all(feature = \"with-chrono\", feature = \"with-time\"))]\n                    {\n                        use crate::with_arrow::{arrow_array_to_value_alt, is_datetime_column};\n                        match am.try_set(col, value) {\n                            Ok(()) => {}\n                            Err(first_err) if is_datetime_column(col_type) => {\n                                if let Some(alt_value) =\n                                    arrow_array_to_value_alt(arrow_col.as_ref(), col_type, row)?\n                                {\n                                    am.try_set(col, alt_value)?;\n                                } else {\n                                    return Err(first_err);\n                                }\n                            }\n                            Err(e) => return Err(e),\n                        }\n                    }\n\n                    #[cfg(not(all(feature = \"with-chrono\", feature = \"with-time\")))]\n                    am.try_set(col, value)?;\n                } else {\n                    am.not_set(col);\n                }\n            }\n\n            results.push(am);\n        }\n\n        Ok(results)\n    }\n\n    /// Convert a slice of ActiveModels into an Arrow [`RecordBatch`](arrow::array::RecordBatch).\n    ///\n    /// The `schema` determines the output columns: each schema field is matched\n    /// to an entity column by name (using [`ColumnTrait::as_str`](crate::ColumnTrait::as_str)).\n    /// Columns marked `Set` or `Unchanged` contribute their value;\n    /// `NotSet` columns become null in the output.\n    ///\n    /// Typical usage together with [`ArrowSchema`](crate::ArrowSchema):\n    /// ```ignore\n    /// let schema = MyEntity::arrow_schema();\n    /// let batch = MyActiveModel::to_arrow(&models, &schema)?;\n    /// ```\n    #[cfg(feature = \"with-arrow\")]\n    fn to_arrow(\n        models: &[Self],\n        schema: &sea_orm_arrow::arrow::datatypes::Schema,\n    ) -> Result<sea_orm_arrow::arrow::array::RecordBatch, DbErr> {\n        use crate::{Iterable, with_arrow::option_values_to_arrow_array};\n        use std::sync::Arc;\n\n        let mut columns: Vec<Arc<dyn sea_orm_arrow::arrow::array::Array>> =\n            Vec::with_capacity(schema.fields().len());\n\n        for field in schema.fields() {\n            let field_name = field.name();\n\n            // Find the entity column whose name matches this schema field\n            let entity_col =\n                <<Self::Entity as EntityTrait>::Column>::iter().find(|c| c.as_str() == field_name);\n\n            if let Some(col) = entity_col {\n                let values: Vec<Option<Value>> = models\n                    .iter()\n                    .map(|m| match m.get(col) {\n                        ActiveValue::Set(v) | ActiveValue::Unchanged(v) => Some(v),\n                        ActiveValue::NotSet => None,\n                    })\n                    .collect();\n\n                let array = option_values_to_arrow_array(&values, field.data_type())?;\n                columns.push(array);\n            } else {\n                // Field in schema but not in entity → null column\n                let array =\n                    sea_orm_arrow::arrow::array::new_null_array(field.data_type(), models.len());\n                columns.push(array);\n            }\n        }\n\n        sea_orm_arrow::arrow::array::RecordBatch::try_new(Arc::new(schema.clone()), columns)\n            .map_err(|e| DbErr::Type(format!(\"Failed to create RecordBatch: {e}\")))\n    }\n\n    /// Return `true` if any attribute of `ActiveModel` is `Set`\n    fn is_changed(&self) -> bool {\n        <Self::Entity as EntityTrait>::Column::iter()\n            .any(|col| matches!(self.get(col), ActiveValue::Set(_)))\n    }\n\n    #[doc(hidden)]\n    /// Set the key to parent's key value for a belongs to relation.\n    fn set_parent_key<R, AM>(&mut self, model: &AM) -> Result<(), DbErr>\n    where\n        R: EntityTrait,\n        AM: ActiveModelTrait<Entity = R>,\n        Self::Entity: Related<R>,\n    {\n        let rel_def = Self::Entity::to();\n\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\n                \"Relation from {} to {} is not belongs_to\",\n                <Self::Entity as Default>::default().as_str(),\n                <R as Default>::default().as_str()\n            )));\n        }\n\n        let values = get_key_from_active_model(&rel_def.to_col, model)?;\n\n        set_key_on_active_model(&rel_def.from_col, self, values)?;\n\n        Ok(())\n    }\n\n    #[doc(hidden)]\n    fn set_parent_key_for<R, AM>(\n        &mut self,\n        model: &AM,\n        rel: <Self::Entity as EntityTrait>::Relation,\n    ) -> Result<(), DbErr>\n    where\n        R: EntityTrait,\n        AM: ActiveModelTrait<Entity = R>,\n    {\n        let rel_def = rel.def();\n\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\"Relation {rel:?} is not belongs_to\")));\n        }\n\n        let values = get_key_from_active_model(&rel_def.to_col, model)?;\n\n        set_key_on_active_model(&rel_def.from_col, self, values)?;\n\n        Ok(())\n    }\n\n    #[doc(hidden)]\n    fn set_parent_key_for_def<R, AM>(\n        &mut self,\n        model: &AM,\n        rel_def: &RelationDef,\n    ) -> Result<(), DbErr>\n    where\n        R: EntityTrait,\n        AM: ActiveModelTrait<Entity = R>,\n    {\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\n                \"Relation {rel_def:?} is not belongs_to\"\n            )));\n        }\n\n        let values = get_key_from_active_model(&rel_def.to_col, model)?;\n\n        set_key_on_active_model(&rel_def.from_col, self, values)?;\n\n        Ok(())\n    }\n\n    #[doc(hidden)]\n    fn set_parent_key_for_self_rev<AM>(\n        &mut self,\n        model: &AM,\n        rel: <Self::Entity as EntityTrait>::Relation,\n    ) -> Result<(), DbErr>\n    where\n        AM: ActiveModelTrait<Entity = Self::Entity>,\n    {\n        let rel_def = rel.def();\n\n        if !rel_def.is_owner {\n            return Err(DbErr::Type(format!(\"Relation {rel:?} is not owner\")));\n        }\n\n        let values = get_key_from_active_model(&rel_def.from_col, model)?;\n\n        set_key_on_active_model(&rel_def.to_col, self, values)?;\n\n        Ok(())\n    }\n\n    #[doc(hidden)]\n    /// Clear parent association if the relation is optional and return true\n    fn clear_parent_key<R>(&mut self) -> Result<bool, DbErr>\n    where\n        R: EntityTrait,\n        Self::Entity: Related<R>,\n    {\n        let rel_def = Self::Entity::to();\n\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\n                \"Relation from {} to {} is not belongs_to\",\n                <Self::Entity as Default>::default().as_str(),\n                <R as Default>::default().as_str()\n            )));\n        }\n\n        clear_key_on_active_model(&rel_def.from_col, self)\n    }\n\n    #[doc(hidden)]\n    fn clear_parent_key_for_self_rev(\n        &mut self,\n        rel: <Self::Entity as EntityTrait>::Relation,\n    ) -> Result<bool, DbErr> {\n        let rel_def = rel.def();\n\n        if !rel_def.is_owner {\n            return Err(DbErr::Type(format!(\"Relation {rel:?} is not owner\")));\n        }\n\n        clear_key_on_active_model(&rel_def.to_col, self)\n    }\n\n    #[doc(hidden)]\n    /// Get the key value of belongs to relation\n    fn get_parent_key<R>(&self) -> Result<ValueTuple, DbErr>\n    where\n        R: EntityTrait,\n        Self::Entity: Related<R>,\n    {\n        let rel_def = Self::Entity::to();\n\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\n                \"Relation from {} to {} is not belongs_to\",\n                <Self::Entity as Default>::default().as_str(),\n                <R as Default>::default().as_str()\n            )));\n        }\n\n        get_key_from_active_model(&rel_def.from_col, self)\n    }\n\n    #[doc(hidden)]\n    /// Get the key value of belongs to relation\n    fn get_parent_key_for(\n        &self,\n        rel: <Self::Entity as EntityTrait>::Relation,\n    ) -> Result<ValueTuple, DbErr> {\n        let rel_def = rel.def();\n\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\"Relation {rel:?} is not belongs_to\")));\n        }\n\n        get_key_from_active_model(&rel_def.from_col, self)\n    }\n\n    #[doc(hidden)]\n    fn find_belongs_to_self(\n        &self,\n        rel: <Self::Entity as EntityTrait>::Relation,\n        db_backend: DbBackend,\n    ) -> Result<crate::query::Select<Self::Entity>, DbErr> {\n        let rel_def = rel.def();\n\n        if !rel_def.is_owner {\n            return Err(DbErr::Type(format!(\n                \"Relation {rel:?} is not has_one / has_many\"\n            )));\n        }\n\n        let id = get_key_from_active_model(&rel_def.from_col, self)?;\n\n        Ok(Self::Entity::find().filter(\n            column_tuple_in_condition(\n                &<Self::Entity as Default>::default().table_ref(),\n                &rel_def.to_col,\n                &[id],\n                db_backend,\n            )\n            .expect(\"\"),\n        ))\n    }\n\n    #[doc(hidden)]\n    fn find_belongs_to_model<AM>(\n        rel_def: &RelationDef,\n        belongs_to: &AM,\n        db_backend: DbBackend,\n    ) -> Result<crate::query::Select<Self::Entity>, DbErr>\n    where\n        AM: ActiveModelTrait,\n    {\n        if rel_def.is_owner {\n            return Err(DbErr::Type(format!(\n                \"Relation {rel_def:?} is not belongs_to\"\n            )));\n        }\n\n        let id = get_key_from_active_model(&rel_def.to_col, belongs_to)?;\n        Ok(<Self::Entity as EntityTrait>::find().filter(\n            column_tuple_in_condition(&rel_def.from_tbl, &rel_def.from_col, &[id], db_backend)\n                .expect(\"\"),\n        ))\n    }\n\n    /// Find related Models belonging to self\n    fn find_related<R>(&self, _: R) -> crate::query::Select<R>\n    where\n        R: EntityTrait,\n        Self::Entity: Related<R>,\n    {\n        Self::Entity::find_related().belongs_to_active_model(self)\n    }\n\n    /// Like find_related, but infer type from `AM`\n    #[doc(hidden)]\n    fn find_related_of<AM>(&self, _: &[AM]) -> crate::query::Select<AM::Entity>\n    where\n        AM: ActiveModelTrait,\n        Self::Entity: Related<AM::Entity>,\n    {\n        self.find_related(AM::Entity::default())\n    }\n\n    /// Establish links between self and a related Entity for a many-to-many relation.\n    /// New associations will be added, and leftovers can be optionally deleted.\n    #[doc(hidden)]\n    async fn establish_links<J, R, RM, C>(\n        &self,\n        _: J,\n        related_models: &[RM],\n        delete_leftover: bool,\n        db: &C,\n    ) -> Result<(), DbErr>\n    where\n        R: EntityTrait,\n        RM: ActiveModelTrait<Entity = R> + Sync,\n        J: EntityTrait + Related<R> + Related<Self::Entity>,\n        J::Model: IntoActiveModel<J::ActiveModel>,\n        J::ActiveModel: ActiveModelBehavior + Send,\n        C: ConnectionTrait,\n    {\n        let left = <J as Related<Self::Entity>>::to();\n        let right = <J as Related<R>>::to();\n\n        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db).await\n    }\n\n    /// Establish links for self-referencing many-to-many relation\n    #[doc(hidden)]\n    async fn establish_links_self<J, RM, C>(\n        &self,\n        _: J,\n        related_models: &[RM],\n        delete_leftover: bool,\n        db: &C,\n    ) -> Result<(), DbErr>\n    where\n        RM: ActiveModelTrait<Entity = Self::Entity> + Sync,\n        J: EntityTrait,\n        J::Model: IntoActiveModel<J::ActiveModel>,\n        J::ActiveModel: ActiveModelBehavior + Send,\n        C: ConnectionTrait,\n        Self::Entity: RelatedSelfVia<J>,\n    {\n        let left = <Self::Entity as RelatedSelfVia<J>>::via().rev();\n        let right = <Self::Entity as RelatedSelfVia<J>>::to();\n\n        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db).await\n    }\n\n    /// Establish links for self-referencing many-to-many relation, but left-right reversed\n    #[doc(hidden)]\n    async fn establish_links_self_rev<J, RM, C>(\n        &self,\n        _: J,\n        related_models: &[RM],\n        delete_leftover: bool,\n        db: &C,\n    ) -> Result<(), DbErr>\n    where\n        RM: ActiveModelTrait<Entity = Self::Entity> + Sync,\n        J: EntityTrait,\n        J::Model: IntoActiveModel<J::ActiveModel>,\n        J::ActiveModel: ActiveModelBehavior + Send,\n        C: ConnectionTrait,\n        Self::Entity: RelatedSelfVia<J>,\n    {\n        let left = <Self::Entity as RelatedSelfVia<J>>::to();\n        let right = <Self::Entity as RelatedSelfVia<J>>::via().rev();\n\n        establish_links::<_, J, _, C>(self, related_models, left, right, delete_leftover, db).await\n    }\n\n    /// Inverse of establish link, break links between two many-to-many models\n    #[doc(hidden)]\n    async fn delete_links<J, C>(&self, _: J, db: &C) -> Result<DeleteResult, DbErr>\n    where\n        J: EntityTrait + Related<Self::Entity>,\n        C: ConnectionTrait,\n    {\n        let rel_def = <J as Related<Self::Entity>>::to();\n        let id = get_key_from_active_model(&rel_def.to_col, self)?;\n\n        J::delete_many()\n            .filter(\n                column_tuple_in_condition(\n                    &rel_def.from_tbl,\n                    &rel_def.from_col,\n                    &[id],\n                    db.get_database_backend(),\n                )\n                .expect(\"\"),\n            )\n            .exec(db)\n            .await\n    }\n\n    /// Like `delete_links` but for self-referencing relations\n    #[doc(hidden)]\n    async fn delete_links_self<J, C>(&self, _: J, db: &C) -> Result<DeleteResult, DbErr>\n    where\n        J: EntityTrait,\n        C: ConnectionTrait,\n        Self::Entity: RelatedSelfVia<J>,\n    {\n        let left = <Self::Entity as RelatedSelfVia<J>>::via().rev();\n        let right = <Self::Entity as RelatedSelfVia<J>>::to();\n\n        let id = get_key_from_active_model(&left.to_col, self)?;\n\n        if left.to_col != right.to_col {\n            return Err(DbErr::Type(\"Expect Self Referencing Relation\".into()));\n        }\n\n        J::delete_many()\n            .filter(\n                Condition::any()\n                    .add(\n                        column_tuple_in_condition(\n                            &left.from_tbl,\n                            &left.from_col,\n                            std::slice::from_ref(&id),\n                            db.get_database_backend(),\n                        )\n                        .expect(\"\"),\n                    )\n                    .add(\n                        column_tuple_in_condition(\n                            &right.from_tbl,\n                            &right.from_col,\n                            std::slice::from_ref(&id),\n                            db.get_database_backend(),\n                        )\n                        .expect(\"\"),\n                    ),\n            )\n            .exec(db)\n            .await\n    }\n}\n\n/// A Trait for overriding the ActiveModel behavior\n///\n/// ### Example\n/// ```ignore\n/// use sea_orm::entity::prelude::*;\n///\n///  // Use [DeriveEntity] to derive the EntityTrait automatically\n/// #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n/// pub struct Entity;\n///\n/// /// The [EntityName] describes the name of a table\n/// impl EntityName for Entity {\n///     fn table_name(&self) -> &'static str {\n///         \"cake\"\n///     }\n/// }\n///\n/// // Derive the ActiveModel\n/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\n/// pub struct Model {\n///     pub id: i32,\n///     pub name: String,\n/// }\n///\n/// impl ActiveModelBehavior for ActiveModel {}\n/// ```\n/// See module level docs [crate::entity] for a full example\n#[allow(unused_variables)]\n#[async_trait::async_trait]\npub trait ActiveModelBehavior: ActiveModelTrait {\n    /// Create a new ActiveModel with default values. This is also called by `Default::default()`.\n    ///\n    /// You can override it like the following:\n    ///\n    /// ```ignore\n    /// fn new() -> Self {\n    ///     Self {\n    ///         status: Set(Status::New),\n    ///         ..ActiveModelTrait::default()\n    ///     }\n    /// }\n    /// ```\n    fn new() -> Self {\n        <Self as ActiveModelTrait>::default()\n    }\n\n    /// Will be called before `ActiveModel::insert`, `ActiveModel::update`, and `ActiveModel::save`\n    async fn before_save<C>(self, db: &C, insert: bool) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Ok(self)\n    }\n\n    /// Will be called after `ActiveModel::insert`, `ActiveModel::update`, and `ActiveModel::save`\n    async fn after_save<C>(\n        model: <Self::Entity as EntityTrait>::Model,\n        db: &C,\n        insert: bool,\n    ) -> Result<<Self::Entity as EntityTrait>::Model, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Ok(model)\n    }\n\n    /// Will be called before `ActiveModel::delete`\n    async fn before_delete<C>(self, db: &C) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Ok(self)\n    }\n\n    /// Will be called after `ActiveModel::delete`\n    async fn after_delete<C>(self, db: &C) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Ok(self)\n    }\n}\n\n/// A Trait for any type that can be converted into an `ActiveModel`,\n/// can be derived using `DeriveIntoActiveModel`.\n///\n/// ## Derive Macro Example\n///\n/// ```rust\n/// use sea_orm::DeriveIntoActiveModel;\n/// mod fruit {\n///     use sea_orm::entity::prelude::*;\n///     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n///     #[sea_orm(table_name = \"fruit\")]\n///     pub struct Model {\n///         #[sea_orm(primary_key)]\n///         pub id: i32,\n///         pub name: String,\n///         pub cake_id: Option<i32>,\n///     }\n///     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n///     pub enum Relation {}\n///     impl ActiveModelBehavior for ActiveModel {}\n/// }\n///\n/// #[derive(DeriveIntoActiveModel)]\n/// #[sea_orm(active_model = \"fruit::ActiveModel\")]\n/// struct NewFruit {\n///     name: String,\n///     // `id` and `cake_id` are omitted - they become `NotSet`\n/// }\n/// ```\n///\n/// ## `set(...)` - always set absent ActiveModel fields\n///\n/// ```rust\n/// # mod fruit {\n/// #     use sea_orm::entity::prelude::*;\n/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #     #[sea_orm(table_name = \"fruit\")]\n/// #     pub struct Model {\n/// #         #[sea_orm(primary_key)]\n/// #         pub id: i32,\n/// #         pub name: String,\n/// #         pub cake_id: Option<i32>,\n/// #     }\n/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n/// #     pub enum Relation {}\n/// #     impl ActiveModelBehavior for ActiveModel {}\n/// # }\n/// use sea_orm::DeriveIntoActiveModel;\n///\n/// #[derive(DeriveIntoActiveModel)]\n/// #[sea_orm(active_model = \"fruit::ActiveModel\", set(cake_id = \"None\"))]\n/// struct NewFruit {\n///     name: String,\n///     // `cake_id` is not on the struct, but will always be `Set(None)`\n/// }\n/// ```\n///\n/// ## `default = \"expr\"` - fallback for `Option<T>` struct fields\n///\n/// ```rust\n/// # mod fruit {\n/// #     use sea_orm::entity::prelude::*;\n/// #     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n/// #     #[sea_orm(table_name = \"fruit\")]\n/// #     pub struct Model {\n/// #         #[sea_orm(primary_key)]\n/// #         pub id: i32,\n/// #         pub name: String,\n/// #         pub cake_id: Option<i32>,\n/// #     }\n/// #     #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n/// #     pub enum Relation {}\n/// #     impl ActiveModelBehavior for ActiveModel {}\n/// # }\n/// use sea_orm::DeriveIntoActiveModel;\n///\n/// #[derive(DeriveIntoActiveModel)]\n/// #[sea_orm(active_model = \"fruit::ActiveModel\")]\n/// struct UpdateFruit {\n///     /// `Some(\"Apple\")` -> `Set(\"Apple\")`, `None` ->`Set(\"Unnamed\")`\n///     #[sea_orm(default = \"String::from(\\\"Unnamed\\\")\")]\n///     name: Option<String>,\n/// }\n/// ```\npub trait IntoActiveModel<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Method to call to perform the conversion\n    fn into_active_model(self) -> A;\n}\n\nimpl<A> IntoActiveModel<A> for A\nwhere\n    A: ActiveModelTrait,\n{\n    fn into_active_model(self) -> A {\n        self\n    }\n}\n\nasync fn establish_links<EM, J, RM, C>(\n    model: &EM,\n    related_models: &[RM],\n    left: RelationDef,\n    right: RelationDef,\n    delete_leftover: bool,\n    db: &C,\n) -> Result<(), DbErr>\nwhere\n    EM: ActiveModelTrait,\n    RM: ActiveModelTrait,\n    J: EntityTrait,\n    J::Model: IntoActiveModel<J::ActiveModel>,\n    J::ActiveModel: ActiveModelBehavior,\n    C: ConnectionTrait,\n{\n    let mut require_leftover = true;\n\n    if related_models.is_empty() {\n        // if there are no related models, then there is no risk of insert conflict\n        require_leftover = false;\n    }\n\n    let primary_key = J::primary_key_identity();\n    if require_leftover\n        && primary_key.fully_contains(&left.from_col)\n        && primary_key.fully_contains(&right.from_col)\n    {\n        // if the primary key is a composite key of the two relations\n        // we can use on conflict no action safely\n        require_leftover = false;\n    }\n\n    let mut leftover = Vec::new();\n    if delete_leftover || require_leftover {\n        for item in <J::ActiveModel as ActiveModelTrait>::find_belongs_to_model(\n            &left,\n            model,\n            db.get_database_backend(),\n        )?\n        .all(db)\n        .await?\n        {\n            let item = item.into_active_model();\n            let key = get_key_from_active_model(&right.from_col, &item)?;\n            leftover.push((item, key));\n        }\n    }\n    let leftover = leftover; // un-mut\n\n    let mut via_models = Vec::new();\n    let mut all_keys = std::collections::HashSet::new();\n\n    for related_model in related_models {\n        let mut via: J::ActiveModel = ActiveModelBehavior::new();\n        via.set_parent_key_for_def(model, &left)?;\n        via.set_parent_key_for_def(related_model, &right)?;\n        let via_key = get_key_from_active_model(&right.from_col, &via)?;\n        if !leftover.iter().any(|t| t.1 == via_key) {\n            // if not already exist, save for insert\n            via_models.push(via);\n        }\n        if delete_leftover {\n            all_keys.insert(via_key);\n        }\n    }\n\n    if delete_leftover {\n        let mut to_delete = Vec::new();\n        for (leftover, key) in leftover {\n            if !all_keys.contains(&key) {\n                to_delete.push(\n                    leftover\n                        .get_primary_key_value()\n                        .expect(\"item is a full model\"),\n                );\n            }\n        }\n        if !to_delete.is_empty() {\n            J::delete_many()\n                .filter_by_value_tuples(&to_delete, db.get_database_backend())\n                .exec(db)\n                .await?;\n        }\n    }\n\n    if !via_models.is_empty() {\n        // insert new junctions\n        J::insert_many(via_models)\n            .on_conflict_do_nothing()\n            .exec(db)\n            .await?;\n    }\n\n    Ok(())\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{DbErr, entity::*, tests_cfg::*};\n    use pretty_assertions::assert_eq;\n\n    #[cfg(feature = \"with-json\")]\n    use serde_json::json;\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_1() {\n        mod my_fruit {\n            pub use super::fruit::*;\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(DeriveIntoActiveModel)]\n            pub struct NewFruit {\n                // id is omitted\n                pub name: String,\n                // it is required as opposed to optional in Model\n                pub cake_id: i32,\n            }\n        }\n\n        assert_eq!(\n            my_fruit::NewFruit {\n                name: \"Apple\".to_owned(),\n                cake_id: 1,\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(1)),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_2() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct RequiredFruitName {\n            name: String,\n        }\n\n        assert_eq!(\n            RequiredFruitName {\n                name: \"Apple Pie\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple Pie\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct OptionalFruitName {\n            name: Option<String>,\n        }\n\n        assert_eq!(\n            OptionalFruitName {\n                name: Some(\"Apple Pie\".to_owned()),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple Pie\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n\n        assert_eq!(\n            OptionalFruitName { name: None }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: NotSet,\n            }\n        );\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"<fruit::Entity as EntityTrait>::ActiveModel\")]\n        struct RequiredAndNotNullFruitCake {\n            cake_id: i32,\n        }\n\n        assert_eq!(\n            RequiredAndNotNullFruitCake { cake_id: 1 }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: Set(Some(1)),\n            }\n        );\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"<fruit::Entity as EntityTrait>::ActiveModel\")]\n        struct OptionalAndNotNullFruitCake {\n            cake_id: Option<i32>,\n        }\n\n        assert_eq!(\n            OptionalAndNotNullFruitCake { cake_id: Some(1) }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: Set(Some(1)),\n            }\n        );\n\n        assert_eq!(\n            OptionalAndNotNullFruitCake { cake_id: None }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: NotSet,\n            }\n        );\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"<fruit::Entity as EntityTrait>::ActiveModel\")]\n        struct OptionalAndNullableFruitCake {\n            cake_id: Option<Option<i32>>,\n        }\n\n        assert_eq!(\n            OptionalAndNullableFruitCake {\n                cake_id: Some(Some(1)),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: Set(Some(1)),\n            }\n        );\n\n        assert_eq!(\n            OptionalAndNullableFruitCake {\n                cake_id: Some(None),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: Set(None),\n            }\n        );\n\n        assert_eq!(\n            OptionalAndNullableFruitCake { cake_id: None }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: NotSet,\n                cake_id: NotSet,\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_set_single() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\", set(cake_id = \"None\"))]\n        struct NewFruit {\n            name: String,\n        }\n\n        assert_eq!(\n            NewFruit {\n                name: \"Apple\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_set_multiple() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(\n            active_model = \"fruit::ActiveModel\",\n            set(name = \"String::from(\\\"cherry\\\")\", cake_id = \"None\")\n        )]\n        struct IdOnlyFruit {\n            id: i32,\n        }\n        assert_eq!(\n            IdOnlyFruit { id: 1 }.into_active_model(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"cherry\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(\n            active_model = \"fruit::ActiveModel\",\n            set(name = \"String::from(\\\"cherry\\\")\"),\n            set(cake_id = \"None\")\n        )]\n        struct IdOnlyFruit2 {\n            id: i32,\n        }\n        assert_eq!(\n            IdOnlyFruit2 { id: 1 }.into_active_model(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"cherry\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_set_separate_attrs() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(\n            active_model = \"fruit::ActiveModel\",\n            set(name = \"String::from(\\\"cherry\\\")\")\n        )]\n        #[sea_orm(set(cake_id = \"None\"))]\n        struct IdOnlyFruit {\n            id: i32,\n        }\n\n        assert_eq!(\n            IdOnlyFruit { id: 1 }.into_active_model(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"cherry\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_ignore() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct NewFruit {\n            name: String,\n            cake_id: i32,\n            #[sea_orm(ignore)]\n            _extra: String,\n        }\n\n        assert_eq!(\n            NewFruit {\n                name: \"Apple\".to_owned(),\n                cake_id: 1,\n                _extra: \"ignored\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(1)),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_skip() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct NewFruit {\n            name: String,\n            #[sea_orm(skip)]\n            _extra: String,\n        }\n\n        assert_eq!(\n            NewFruit {\n                name: \"Apple\".to_owned(),\n                _extra: \"skipped\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_set_and_ignore() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\", set(cake_id = \"Some(42)\"))]\n        struct NewFruit {\n            name: String,\n            #[sea_orm(ignore)]\n            _extra: String,\n        }\n\n        assert_eq!(\n            NewFruit {\n                name: \"Apple\".to_owned(),\n                _extra: \"ignored\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(42)),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_foreign_ignore() {\n        use serde::{Deserialize, Serialize};\n\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel, Serialize, Deserialize)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct NewFruit {\n            #[sea_orm(ignore)]\n            id: i32,\n            name: String,\n            #[serde(skip)]\n            cake_id: Option<i32>,\n        }\n\n        assert_eq!(\n            NewFruit {\n                id: 1.to_owned(),\n                name: \"Apple\".to_owned(),\n                cake_id: Some(42)\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(42)),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_exhaustive() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\", exhaustive, set(cake_id = \"None\"))]\n        struct FullFruit {\n            id: i32,\n            name: String,\n        }\n\n        assert_eq!(\n            FullFruit {\n                id: 1,\n                name: \"Apple\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_multiple_sets() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        const DEFULT_CAKE_ID: i32 = 1;\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(\n            active_model = \"fruit::ActiveModel\",\n            exhaustive,\n            set(cake_id = \"Some(DEFULT_CAKE_ID)\")\n        )]\n        struct FullFruit {\n            id: i32,\n            name: String,\n        }\n\n        assert_eq!(\n            FullFruit {\n                id: 1,\n                name: \"Apple\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(1)),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_field_empty_default() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct NewFruit {\n            #[sea_orm(default)]\n            name: Option<String>,\n        }\n\n        // Some(v) -> Set(v)\n        assert_eq!(\n            NewFruit {\n                name: Some(\"Apple\".to_owned()),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n\n        // None -> Set(fallback)\n        assert_eq!(\n            NewFruit { name: None }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_field_custom_option() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n        mod foreign_crate {\n            #[derive(Debug, Clone, PartialEq, Eq)]\n            pub enum CustomOption<T> {\n                None,\n                Some(T),\n            }\n\n            impl From<CustomOption<String>> for Option<String> {\n                fn from(option: CustomOption<String>) -> Self {\n                    match option {\n                        CustomOption::None => Option::None,\n                        CustomOption::Some(value) => value.into(),\n                    }\n                }\n            }\n        }\n        use foreign_crate::CustomOption;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct NewFruit {\n            #[sea_orm(default)]\n            name: CustomOption<String>,\n        }\n\n        // Some(v) -> Set(v)\n        assert_eq!(\n            NewFruit {\n                name: CustomOption::Some(\"Apple\".to_owned()),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n\n        // None -> Set(fallback)\n        assert_eq!(\n            NewFruit {\n                name: CustomOption::None\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_field_default_some() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\")]\n        struct NewFruit {\n            #[sea_orm(default = \"String::from(\\\"Unnamed\\\")\")]\n            name: Option<String>,\n        }\n\n        // Some(v) -> Set(v)\n        assert_eq!(\n            NewFruit {\n                name: Some(\"Apple\".to_owned()),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n\n        // None -> Set(fallback)\n        assert_eq!(\n            NewFruit { name: None }.into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Unnamed\".to_owned()),\n                cake_id: NotSet,\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_field_default_with_set() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\", set(cake_id = \"Some(99)\"))]\n        struct NewFruit {\n            #[sea_orm(default = \"String::from(\\\"Unnamed\\\")\")]\n            name: Option<String>,\n            #[sea_orm(ignore)]\n            _extra: String,\n        }\n\n        assert_eq!(\n            NewFruit {\n                name: Some(\"Apple\".to_owned()),\n                _extra: \"ignored\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(99)),\n            }\n        );\n\n        assert_eq!(\n            NewFruit {\n                name: None,\n                _extra: \"ignored\".to_owned(),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: NotSet,\n                name: Set(\"Unnamed\".to_owned()),\n                cake_id: Set(Some(99)),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_into_active_model_field_default_exhaustive() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(DeriveIntoActiveModel)]\n        #[sea_orm(active_model = \"fruit::ActiveModel\", exhaustive, set(cake_id = \"None\"))]\n        struct NewFruit {\n            id: i32,\n            #[sea_orm(default = \"String::from(\\\"Unnamed\\\")\")]\n            name: Option<String>,\n        }\n\n        assert_eq!(\n            NewFruit {\n                id: 1,\n                name: Some(\"Apple\".to_owned()),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n\n        assert_eq!(\n            NewFruit { id: 2, name: None }.into_active_model(),\n            fruit::ActiveModel {\n                id: Set(2),\n                name: Set(\"Unnamed\".to_owned()),\n                cake_id: Set(None),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_try_into_model_1() {\n        mod my_fruit {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"fruit\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                pub name: String,\n                pub cake_id: Option<i32>,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n        assert_eq!(\n            my_fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Pineapple\".to_owned()),\n                cake_id: Set(None),\n            }\n            .try_into_model()\n            .unwrap(),\n            my_fruit::Model {\n                id: 1,\n                name: \"Pineapple\".to_owned(),\n                cake_id: None,\n            }\n        );\n\n        assert_eq!(\n            my_fruit::ActiveModel {\n                id: Set(2),\n                name: Set(\"Apple\".to_owned()),\n                cake_id: Set(Some(1)),\n            }\n            .try_into_model()\n            .unwrap(),\n            my_fruit::Model {\n                id: 2,\n                name: \"Apple\".to_owned(),\n                cake_id: Some(1),\n            }\n        );\n\n        assert_eq!(\n            my_fruit::ActiveModel {\n                id: Set(1),\n                name: NotSet,\n                cake_id: Set(None),\n            }\n            .try_into_model(),\n            Err(DbErr::AttrNotSet(String::from(\"name\")))\n        );\n\n        assert_eq!(\n            my_fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Pineapple\".to_owned()),\n                cake_id: NotSet,\n            }\n            .try_into_model(),\n            Err(DbErr::AttrNotSet(String::from(\"cake_id\")))\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_try_into_model_2() {\n        mod my_fruit {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"fruit\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                pub name: String,\n                #[sea_orm(ignore)]\n                pub cake_id: Option<i32>,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n        assert_eq!(\n            my_fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Pineapple\".to_owned()),\n            }\n            .try_into_model()\n            .unwrap(),\n            my_fruit::Model {\n                id: 1,\n                name: \"Pineapple\".to_owned(),\n                cake_id: None,\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_derive_try_into_model_3() {\n        mod my_fruit {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"fruit\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                #[sea_orm(ignore)]\n                pub name: String,\n                pub cake_id: Option<i32>,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n        assert_eq!(\n            my_fruit::ActiveModel {\n                id: Set(1),\n                cake_id: Set(Some(1)),\n            }\n            .try_into_model()\n            .unwrap(),\n            my_fruit::Model {\n                id: 1,\n                name: \"\".to_owned(),\n                cake_id: Some(1),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"with-json\")]\n    fn test_active_model_set_from_json_1() {\n        assert_eq!(\n            cake::ActiveModel::from_json(json!({\n                \"id\": 1,\n                \"name\": \"Apple Pie\",\n            }))\n            .unwrap(),\n            cake::ActiveModel {\n                id: Set(1),\n                name: Set(\"Apple Pie\".to_owned()),\n            }\n        );\n\n        assert_eq!(\n            cake::ActiveModel::from_json(json!({\n                \"id\": 1,\n            }))\n            .unwrap(),\n            cake::ActiveModel {\n                id: Set(1),\n                name: NotSet,\n            }\n        );\n\n        assert_eq!(\n            cake::ActiveModel::from_json(json!({\n                \"name\": \"Apple Pie\",\n            }))\n            .unwrap(),\n            cake::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple Pie\".to_owned()),\n            }\n        );\n\n        let mut cake: cake::ActiveModel = Default::default();\n        cake.set_from_json(json!({\n            \"name\": \"Apple Pie\",\n        }))\n        .unwrap();\n        assert_eq!(\n            cake,\n            cake::ActiveModel {\n                id: NotSet,\n                name: Set(\"Apple Pie\".to_owned()),\n            }\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"with-json\")]\n    fn test_active_model_set_from_json_2() -> Result<(), DbErr> {\n        let mut fruit: fruit::ActiveModel = Default::default();\n\n        fruit.set_from_json(json!({\n            \"name\": \"Apple\",\n        }))?;\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: ActiveValue::NotSet,\n                name: ActiveValue::Set(\"Apple\".to_owned()),\n                cake_id: ActiveValue::NotSet,\n            }\n        );\n\n        assert_eq!(\n            fruit::ActiveModel::from_json(json!({\n                \"name\": \"Apple\",\n            }))?,\n            fruit::ActiveModel {\n                id: ActiveValue::NotSet,\n                name: ActiveValue::Set(\"Apple\".to_owned()),\n                cake_id: ActiveValue::NotSet,\n            }\n        );\n\n        fruit.set_from_json(json!({\n            \"name\": \"Apple\",\n            \"cake_id\": null,\n        }))?;\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: ActiveValue::NotSet,\n                name: ActiveValue::Set(\"Apple\".to_owned()),\n                cake_id: ActiveValue::Set(None),\n            }\n        );\n\n        fruit.set_from_json(json!({\n            \"id\": null,\n            \"name\": \"Apple\",\n            \"cake_id\": 1,\n        }))?;\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: ActiveValue::NotSet,\n                name: ActiveValue::Set(\"Apple\".to_owned()),\n                cake_id: ActiveValue::Set(Some(1)),\n            }\n        );\n\n        fruit.set_from_json(json!({\n            \"id\": 2,\n            \"name\": \"Apple\",\n            \"cake_id\": 1,\n        }))?;\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: ActiveValue::NotSet,\n                name: ActiveValue::Set(\"Apple\".to_owned()),\n                cake_id: ActiveValue::Set(Some(1)),\n            }\n        );\n\n        let mut fruit = fruit::ActiveModel {\n            id: ActiveValue::Set(1),\n            name: ActiveValue::NotSet,\n            cake_id: ActiveValue::NotSet,\n        };\n        fruit.set_from_json(json!({\n            \"id\": 8,\n            \"name\": \"Apple\",\n            \"cake_id\": 1,\n        }))?;\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: ActiveValue::Set(1),\n                name: ActiveValue::Set(\"Apple\".to_owned()),\n                cake_id: ActiveValue::Set(Some(1)),\n            }\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    #[cfg(feature = \"with-json\")]\n    async fn test_active_model_set_from_json_3() -> Result<(), DbErr> {\n        use crate::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_exec_results([\n                MockExecResult {\n                    last_insert_id: 1,\n                    rows_affected: 1,\n                },\n                MockExecResult {\n                    last_insert_id: 1,\n                    rows_affected: 1,\n                },\n            ])\n            .append_query_results([\n                [fruit::Model {\n                    id: 1,\n                    name: \"Apple\".to_owned(),\n                    cake_id: None,\n                }],\n                [fruit::Model {\n                    id: 2,\n                    name: \"Orange\".to_owned(),\n                    cake_id: Some(1),\n                }],\n            ])\n            .into_connection();\n\n        let mut fruit: fruit::ActiveModel = Default::default();\n        fruit.set_from_json(json!({\n            \"name\": \"Apple\",\n        }))?;\n        fruit.save(&db).await?;\n\n        let mut fruit = fruit::ActiveModel {\n            id: Set(2),\n            ..Default::default()\n        };\n        fruit.set_from_json(json!({\n            \"id\": 9,\n            \"name\": \"Orange\",\n            \"cake_id\": 1,\n        }))?;\n        fruit.save(&db).await?;\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"INSERT INTO \"fruit\" (\"name\") VALUES ($1) RETURNING \"id\", \"name\", \"cake_id\"\"#,\n                    [\"Apple\".into()],\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"fruit\" SET \"name\" = $1, \"cake_id\" = $2 WHERE \"fruit\".\"id\" = $3 RETURNING \"id\", \"name\", \"cake_id\"\"#,\n                    [\"Orange\".into(), 1i32.into(), 2i32.into()],\n                ),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_active_model_is_changed() {\n        let mut fruit: fruit::ActiveModel = Default::default();\n        assert!(!fruit.is_changed());\n\n        fruit.set(fruit::Column::Name, \"apple\".into());\n        assert!(fruit.is_changed());\n\n        let mut fruit = fruit::Model {\n            id: 1,\n            name: \"\".into(),\n            cake_id: None,\n        };\n        fruit.set(\"name\".parse().unwrap(), \"orange\".into());\n        assert_eq!(fruit.name, \"orange\");\n    }\n\n    #[test]\n    fn test_reset_1() {\n        assert_eq!(\n            fruit::Model {\n                id: 1,\n                name: \"Apple\".into(),\n                cake_id: None,\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: Unchanged(1),\n                name: Unchanged(\"Apple\".into()),\n                cake_id: Unchanged(None)\n            },\n        );\n\n        assert_eq!(\n            fruit::Model {\n                id: 1,\n                name: \"Apple\".into(),\n                cake_id: None,\n            }\n            .into_active_model()\n            .reset_all(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Apple\".into()),\n                cake_id: Set(None)\n            },\n        );\n\n        assert_eq!(\n            fruit::Model {\n                id: 1,\n                name: \"Apple\".into(),\n                cake_id: Some(2),\n            }\n            .into_active_model(),\n            fruit::ActiveModel {\n                id: Unchanged(1),\n                name: Unchanged(\"Apple\".into()),\n                cake_id: Unchanged(Some(2)),\n            },\n        );\n\n        assert_eq!(\n            fruit::Model {\n                id: 1,\n                name: \"Apple\".into(),\n                cake_id: Some(2),\n            }\n            .into_active_model()\n            .reset_all(),\n            fruit::ActiveModel {\n                id: Set(1),\n                name: Set(\"Apple\".into()),\n                cake_id: Set(Some(2)),\n            },\n        );\n    }\n\n    #[smol_potat::test]\n    async fn test_reset_2() -> Result<(), DbErr> {\n        use crate::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_exec_results(vec![\n                MockExecResult {\n                    last_insert_id: 1,\n                    rows_affected: 1,\n                },\n                MockExecResult {\n                    last_insert_id: 1,\n                    rows_affected: 1,\n                },\n            ])\n            .append_query_results(vec![\n                vec![fruit::Model {\n                    id: 1,\n                    name: \"Apple\".to_owned(),\n                    cake_id: None,\n                }],\n                vec![fruit::Model {\n                    id: 1,\n                    name: \"Apple\".to_owned(),\n                    cake_id: None,\n                }],\n            ])\n            .into_connection();\n\n        fruit::Model {\n            id: 1,\n            name: \"Apple\".into(),\n            cake_id: None,\n        }\n        .into_active_model()\n        .update(&db)\n        .await?;\n\n        fruit::Model {\n            id: 1,\n            name: \"Apple\".into(),\n            cake_id: None,\n        }\n        .into_active_model()\n        .reset_all()\n        .update(&db)\n        .await?;\n\n        assert_eq!(\n            db.into_transaction_log(),\n            vec![\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\" WHERE \"fruit\".\"id\" = $1 LIMIT $2\"#,\n                    vec![1i32.into(), 1u64.into()],\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"fruit\" SET \"name\" = $1, \"cake_id\" = $2 WHERE \"fruit\".\"id\" = $3 RETURNING \"id\", \"name\", \"cake_id\"\"#,\n                    vec![\"Apple\".into(), Option::<i32>::None.into(), 1i32.into()],\n                ),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_active_model_default_values() {\n        assert_eq!(\n            fruit::ActiveModel::default_values(),\n            fruit::ActiveModel {\n                id: Set(0),\n                name: Set(\"\".into()),\n                cake_id: Set(None),\n            },\n        );\n\n        assert_eq!(\n            lunch_set::ActiveModel::default_values(),\n            lunch_set::ActiveModel {\n                id: Set(0),\n                name: Set(\"\".into()),\n                tea: NotSet,\n            },\n        );\n    }\n\n    #[test]\n    fn test_active_model_set_parent_key() {\n        let mut fruit = fruit::Model {\n            id: 2,\n            name: \"F\".into(),\n            cake_id: None,\n        }\n        .into_active_model();\n\n        let cake = cake::Model {\n            id: 4,\n            name: \"C\".into(),\n        }\n        .into_active_model();\n\n        fruit.set_parent_key(&cake).unwrap();\n\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: Unchanged(2),\n                name: Unchanged(\"F\".into()),\n                cake_id: Set(Some(4)),\n            }\n        );\n\n        assert!(fruit.clear_parent_key::<cake::Entity>().unwrap());\n\n        assert_eq!(\n            fruit,\n            fruit::ActiveModel {\n                id: Unchanged(2),\n                name: Unchanged(\"F\".into()),\n                cake_id: Set(None),\n            }\n        );\n\n        let mut cake_filling = cake_filling::ActiveModel::new();\n\n        cake_filling.set_parent_key(&cake).unwrap();\n\n        assert_eq!(\n            cake_filling,\n            cake_filling::ActiveModel {\n                cake_id: Set(4),\n                filling_id: NotSet,\n            }\n        );\n    }\n}\n"
  },
  {
    "path": "src/entity/active_model_ex.rs",
    "content": "use super::compound::{HasMany, HasOne};\nuse crate::{ActiveModelTrait, DbErr, EntityTrait, ModelTrait, TryIntoModel};\nuse core::ops::{Index, IndexMut};\n\n/// Container for belongs_to or has_one relation\n#[derive(Debug, Default, Clone)]\npub enum HasOneModel<E: EntityTrait> {\n    /// Unspecified value, do nothing\n    #[default]\n    NotSet,\n    /// Specify the value for the has one relation\n    Set(Box<E::ActiveModelEx>),\n}\n\n/// Container for 1-N or M-N related Models\n#[derive(Debug, Default, Clone)]\npub enum HasManyModel<E: EntityTrait> {\n    /// Unspecified value, do nothing\n    #[default]\n    NotSet,\n    /// Replace all items with this value set; delete leftovers\n    Replace(Vec<E::ActiveModelEx>),\n    /// Add new items to this has many relation; do not delete\n    Append(Vec<E::ActiveModelEx>),\n}\n\n/// Action to perform on ActiveModel\n#[derive(Debug, Copy, Clone, PartialEq, Eq)]\npub enum ActiveModelAction {\n    /// Insert\n    Insert,\n    /// Update\n    Update,\n    /// Insert the model if primary key is `NotSet`, update otherwise.\n    /// Only works if the entity has auto increment primary key.\n    Save,\n}\n\nimpl<E> HasOneModel<E>\nwhere\n    E: EntityTrait,\n{\n    /// Construct a `HasOneModel::Set`\n    pub fn set<AM: Into<E::ActiveModelEx>>(model: AM) -> Self {\n        Self::Set(Box::new(model.into()))\n    }\n\n    /// Replace the inner Model\n    pub fn replace<AM: Into<E::ActiveModelEx>>(&mut self, model: AM) {\n        *self = Self::Set(Box::new(model.into()));\n    }\n\n    /// Take ownership of this model, leaving `NotSet` in place\n    pub fn take(&mut self) -> Option<E::ActiveModelEx> {\n        match std::mem::take(self) {\n            Self::Set(model) => Some(*model),\n            _ => None,\n        }\n    }\n\n    /// Get a reference, if set\n    pub fn as_ref(&self) -> Option<&E::ActiveModelEx> {\n        match self {\n            Self::Set(model) => Some(model),\n            _ => None,\n        }\n    }\n\n    /// Get a mutable reference, if set\n    #[allow(clippy::should_implement_trait)]\n    pub fn as_mut(&mut self) -> Option<&mut E::ActiveModelEx> {\n        match self {\n            Self::Set(model) => Some(model),\n            _ => None,\n        }\n    }\n\n    /// Return true if there is a model\n    pub fn is_set(&self) -> bool {\n        matches!(self, Self::Set(_))\n    }\n\n    /// Return true if self is NotSet\n    pub fn is_not_set(&self) -> bool {\n        matches!(self, Self::NotSet)\n    }\n\n    /// Return true if self is NotSet\n    pub fn is_none(&self) -> bool {\n        matches!(self, Self::NotSet)\n    }\n\n    /// Return true if the containing model is set and changed\n    pub fn is_changed(&self) -> bool {\n        match self {\n            Self::Set(model) => model.is_changed(),\n            _ => false,\n        }\n    }\n\n    /// Convert into an `Option<ActiveModelEx>`\n    pub fn into_option(self) -> Option<E::ActiveModelEx> {\n        match self {\n            Self::Set(model) => Some(*model),\n            Self::NotSet => None,\n        }\n    }\n\n    /// For type inference purpose\n    #[doc(hidden)]\n    pub fn empty_slice(&self) -> &[E::ActiveModelEx] {\n        &[]\n    }\n\n    /// Convert this back to a `ModelEx` container\n    pub fn try_into_model(self) -> Result<HasOne<E>, DbErr>\n    where\n        E::ActiveModelEx: TryIntoModel<E::ModelEx>,\n    {\n        Ok(match self {\n            Self::Set(model) => HasOne::Loaded(Box::new((*model).try_into_model()?)),\n            Self::NotSet => HasOne::Unloaded,\n        })\n    }\n}\n\nimpl<E> PartialEq for HasOneModel<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: PartialEq,\n{\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (HasOneModel::NotSet, HasOneModel::NotSet) => true,\n            (HasOneModel::Set(a), HasOneModel::Set(b)) => a == b,\n            _ => false,\n        }\n    }\n}\n\nimpl<E> PartialEq<Option<E::ActiveModelEx>> for HasOneModel<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: PartialEq,\n{\n    fn eq(&self, other: &Option<E::ActiveModelEx>) -> bool {\n        match (self, other) {\n            (HasOneModel::NotSet, None) => true,\n            (HasOneModel::Set(a), Some(b)) => a.as_ref() == b,\n            _ => false,\n        }\n    }\n}\n\nimpl<E> Eq for HasOneModel<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: Eq,\n{\n}\n\nimpl<E> HasManyModel<E>\nwhere\n    E: EntityTrait,\n{\n    /// Take ownership of the models, leaving `NotSet` in place\n    pub fn take(&mut self) -> Self {\n        std::mem::take(self)\n    }\n\n    /// Borrow models as slice\n    pub fn as_slice(&self) -> &[E::ActiveModelEx] {\n        match self {\n            Self::Replace(models) | Self::Append(models) => models,\n            Self::NotSet => &[],\n        }\n    }\n\n    /// Get a mutable vec. If self is `NotSet`, convert to append.\n    pub fn as_mut_vec(&mut self) -> &mut Vec<E::ActiveModelEx> {\n        match self {\n            Self::Replace(models) | Self::Append(models) => models,\n            Self::NotSet => {\n                *self = Self::Append(vec![]);\n                self.as_mut_vec()\n            }\n        }\n    }\n\n    /// Consume self as vector\n    pub fn into_vec(self) -> Vec<E::ActiveModelEx> {\n        match self {\n            Self::Replace(models) | Self::Append(models) => models,\n            Self::NotSet => vec![],\n        }\n    }\n\n    /// Returns an empty container of self\n    pub fn empty_holder(&self) -> Self {\n        match self {\n            Self::Replace(_) => Self::Replace(vec![]),\n            Self::Append(_) => Self::Append(vec![]),\n            Self::NotSet => Self::NotSet,\n        }\n    }\n\n    /// Push an item to self\n    pub fn push<AM: Into<E::ActiveModelEx>>(&mut self, model: AM) -> &mut Self {\n        let model = model.into();\n        match self {\n            Self::Replace(models) | Self::Append(models) => models.push(model),\n            Self::NotSet => {\n                *self = Self::Append(vec![model]);\n            }\n        }\n\n        self\n    }\n\n    /// Push an item to self, but convert Replace to Append\n    pub fn append<AM: Into<E::ActiveModelEx>>(&mut self, model: AM) -> &mut Self {\n        self.convert_to_append().push(model)\n    }\n\n    /// Replace all items in this set\n    pub fn replace_all<I>(&mut self, models: I) -> &mut Self\n    where\n        I: IntoIterator<Item = E::ActiveModelEx>,\n    {\n        *self = Self::Replace(models.into_iter().collect());\n        self\n    }\n\n    /// Convert self to Append, if set\n    pub fn convert_to_append(&mut self) -> &mut Self {\n        match self.take() {\n            Self::Replace(models) | Self::Append(models) => {\n                *self = Self::Append(models);\n            }\n            Self::NotSet => {\n                *self = Self::NotSet;\n            }\n        }\n\n        self\n    }\n\n    /// Reset self to NotSet\n    pub fn not_set(&mut self) {\n        *self = Self::NotSet;\n    }\n\n    /// If self is `Replace`\n    pub fn is_replace(&self) -> bool {\n        matches!(self, Self::Replace(_))\n    }\n\n    /// If self is `Append`\n    pub fn is_append(&self) -> bool {\n        matches!(self, Self::Append(_))\n    }\n\n    /// Return true if self is `Replace` or any containing model is changed\n    pub fn is_changed(&self) -> bool {\n        match self {\n            Self::Replace(_) => true,\n            Self::Append(models) => models.iter().any(|model| model.is_changed()),\n            Self::NotSet => false,\n        }\n    }\n\n    /// Find within the models by primary key, return true if found\n    pub fn find(&self, model: &E::Model) -> bool {\n        let pk = model.get_primary_key_value();\n\n        for item in self.as_slice() {\n            if let Some(pk_item) = item.get_primary_key_value() {\n                if pk_item == pk {\n                    return true;\n                }\n            }\n        }\n\n        false\n    }\n\n    /// Convert this back to a `ModelEx` container\n    pub fn try_into_model(self) -> Result<HasMany<E>, DbErr>\n    where\n        E::ActiveModelEx: TryIntoModel<E::ModelEx>,\n    {\n        Ok(match self {\n            Self::Replace(models) | Self::Append(models) => HasMany::Loaded(\n                models\n                    .into_iter()\n                    .map(|t| t.try_into_model())\n                    .collect::<Result<Vec<_>, DbErr>>()?,\n            ),\n            Self::NotSet => HasMany::Unloaded,\n        })\n    }\n}\n\nimpl<E> PartialEq for HasManyModel<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: PartialEq,\n{\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (HasManyModel::NotSet, HasManyModel::NotSet) => true,\n            (HasManyModel::Replace(a), HasManyModel::Replace(b)) => a == b,\n            (HasManyModel::Append(a), HasManyModel::Append(b)) => a == b,\n            _ => false,\n        }\n    }\n}\n\nimpl<E> Eq for HasManyModel<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: Eq,\n{\n}\n\nimpl<E: EntityTrait> From<HasManyModel<E>> for Option<Vec<E::ActiveModelEx>> {\n    fn from(value: HasManyModel<E>) -> Self {\n        match value {\n            HasManyModel::NotSet => None,\n            HasManyModel::Replace(models) | HasManyModel::Append(models) => Some(models),\n        }\n    }\n}\n\nimpl<E: EntityTrait> Index<usize> for HasManyModel<E> {\n    type Output = E::ActiveModelEx;\n\n    fn index(&self, index: usize) -> &Self::Output {\n        match self {\n            HasManyModel::NotSet => {\n                panic!(\"index out of bounds: the HasManyModel is NotSet (index: {index})\")\n            }\n            HasManyModel::Replace(models) | HasManyModel::Append(models) => models.index(index),\n        }\n    }\n}\n\nimpl<E: EntityTrait> IndexMut<usize> for HasManyModel<E> {\n    fn index_mut(&mut self, index: usize) -> &mut Self::Output {\n        match self {\n            HasManyModel::NotSet => {\n                panic!(\"index out of bounds: the HasManyModel is NotSet (index: {index})\")\n            }\n            HasManyModel::Replace(models) | HasManyModel::Append(models) => models.index_mut(index),\n        }\n    }\n}\n\nimpl<E: EntityTrait> IntoIterator for HasManyModel<E> {\n    type Item = E::ActiveModelEx;\n    type IntoIter = std::vec::IntoIter<E::ActiveModelEx>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        match self {\n            HasManyModel::Replace(models) | HasManyModel::Append(models) => models.into_iter(),\n            HasManyModel::NotSet => Vec::new().into_iter(),\n        }\n    }\n}\n\n/// Converts from a set of models into `Append`, which performs non-destructive action\nimpl<E: EntityTrait> From<Vec<E::ActiveModelEx>> for HasManyModel<E> {\n    fn from(value: Vec<E::ActiveModelEx>) -> Self {\n        HasManyModel::Append(value)\n    }\n}\n"
  },
  {
    "path": "src/entity/active_value.rs",
    "content": "use crate::Value;\nuse sea_query::Nullable;\nuse std::fmt::Debug;\n\npub use ActiveValue::{NotSet, Set, Unchanged};\n\n/// The state of a field in an [ActiveModel][ActiveModelTrait].\n///\n/// There are three possible states represented by three enum variants:\n///\n/// - [Set] - a value that's explicitly set by the application and sent to the database.\n/// - [Unchanged] - an existing, unchanged value from the database.\n/// - [NotSet] - an undefined value (nothing is sent to the database).\n///\n/// The difference between these states is useful\n/// when constructing `INSERT` and `UPDATE` SQL statements (see an example below).\n/// It's also useful for knowing which fields have changed in a record.\n///\n/// # Examples\n///\n/// ```\n/// use sea_orm::tests_cfg::{cake, fruit};\n/// use sea_orm::{DbBackend, entity::*, query::*};\n///\n/// // Here, we use `NotSet` to let the database automatically generate an `id`.\n/// // This is different from `Set(None)` that explicitly sets `cake_id` to `NULL`.\n/// assert_eq!(\n///     Insert::one(fruit::ActiveModel {\n///         id: ActiveValue::NotSet,\n///         name: ActiveValue::Set(\"Orange\".to_owned()),\n///         cake_id: ActiveValue::Set(None),\n///     })\n///     .build(DbBackend::Postgres)\n///     .to_string(),\n///     r#\"INSERT INTO \"fruit\" (\"name\", \"cake_id\") VALUES ('Orange', NULL)\"#\n/// );\n///\n/// // Here, we update the record, set `cake_id` to the new value\n/// // and use `NotSet` to avoid updating the `name` field.\n/// // `id` is the primary key, so it's used in the condition and not updated.\n/// assert_eq!(\n///     Update::one(fruit::ActiveModel {\n///         id: ActiveValue::Unchanged(1),\n///         name: ActiveValue::NotSet,\n///         cake_id: ActiveValue::Set(Some(2)),\n///     })\n///     .validate()\n///     .unwrap()\n///     .build(DbBackend::Postgres)\n///     .to_string(),\n///     r#\"UPDATE \"fruit\" SET \"cake_id\" = 2 WHERE \"fruit\".\"id\" = 1\"#\n/// );\n/// ```\n#[derive(Clone, Debug)]\npub enum ActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    /// A [Value] that's explicitly set by the application and sent to the database.\n    ///\n    /// Use this to insert or set a specific value.\n    ///\n    /// When editing an existing value, you can use [set_if_not_equals][ActiveValue::set_if_not_equals]\n    /// to preserve the [Unchanged] state when the new value is the same as the old one.\n    /// Then you can meaningfully use methods like [ActiveModelTrait::is_changed].\n    Set(V),\n    /// An existing, unchanged [Value] from the database.\n    ///\n    /// You get these when you query an existing [Model][crate::ModelTrait]\n    /// from the database and convert it into an [ActiveModel][ActiveModelTrait].\n    ///\n    /// When you edit it, you can use [set_if_not_equals][ActiveValue::set_if_not_equals]\n    /// to preserve this \"unchanged\" state if the new value is the same as the old one.\n    /// Then you can meaningfully use methods like [ActiveModelTrait::is_changed].\n    Unchanged(V),\n    /// An undefined [Value]. Nothing is sent to the database.\n    ///\n    /// When you create a new [ActiveModel][ActiveModelTrait],\n    /// its fields are [NotSet][ActiveValue::NotSet] by default.\n    ///\n    /// This can be useful when:\n    ///\n    /// - You insert a new record and want the database to generate a default value (e.g., an id).\n    /// - In an `UPDATE` statement, you don't want to update some field.\n    NotSet,\n}\n\n/// Defines an not set operation on an [ActiveValue]\n#[deprecated(\n    since = \"0.5.0\",\n    note = \"Please use [`ActiveValue::NotSet`] or [`NotSet`]\"\n)]\n#[allow(non_snake_case)]\npub fn Unset<V>(_: Option<bool>) -> ActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    ActiveValue::not_set()\n}\n\n/// Any type that can be converted into an [ActiveValue]\npub trait IntoActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    /// Method to perform the conversion\n    fn into_active_value(self) -> ActiveValue<V>;\n}\n\nimpl<V> IntoActiveValue<V> for Option<V>\nwhere\n    V: IntoActiveValue<V> + Into<Value> + Nullable,\n{\n    fn into_active_value(self) -> ActiveValue<V> {\n        match self {\n            Some(value) => Set(value),\n            None => NotSet,\n        }\n    }\n}\n\nimpl<V> IntoActiveValue<Option<V>> for Option<Option<V>>\nwhere\n    V: IntoActiveValue<V> + Into<Value> + Nullable,\n{\n    fn into_active_value(self) -> ActiveValue<Option<V>> {\n        match self {\n            Some(value) => Set(value),\n            None => NotSet,\n        }\n    }\n}\n\nmacro_rules! impl_into_active_value {\n    ($ty: ty) => {\n        impl IntoActiveValue<$ty> for $ty {\n            fn into_active_value(self) -> ActiveValue<$ty> {\n                Set(self)\n            }\n        }\n    };\n}\n\nimpl_into_active_value!(bool);\nimpl_into_active_value!(i8);\nimpl_into_active_value!(i16);\nimpl_into_active_value!(i32);\nimpl_into_active_value!(i64);\nimpl_into_active_value!(u8);\nimpl_into_active_value!(u16);\nimpl_into_active_value!(u32);\nimpl_into_active_value!(u64);\nimpl_into_active_value!(f32);\nimpl_into_active_value!(f64);\nimpl_into_active_value!(&'static str);\nimpl_into_active_value!(String);\nimpl_into_active_value!(Vec<u8>);\n\n#[cfg(feature = \"with-json\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-json\")))]\nimpl_into_active_value!(crate::prelude::Json);\n\n#[cfg(feature = \"with-chrono\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-chrono\")))]\nimpl_into_active_value!(crate::prelude::Date);\n\n#[cfg(feature = \"with-chrono\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-chrono\")))]\nimpl_into_active_value!(crate::prelude::Time);\n\n#[cfg(feature = \"with-chrono\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-chrono\")))]\nimpl_into_active_value!(crate::prelude::DateTime);\n\n#[cfg(feature = \"with-chrono\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-chrono\")))]\nimpl_into_active_value!(crate::prelude::DateTimeWithTimeZone);\n\n#[cfg(feature = \"with-chrono\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-chrono\")))]\nimpl_into_active_value!(crate::prelude::DateTimeUtc);\n\n#[cfg(feature = \"with-chrono\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-chrono\")))]\nimpl_into_active_value!(crate::prelude::DateTimeLocal);\n\n#[cfg(feature = \"with-rust_decimal\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-rust_decimal\")))]\nimpl_into_active_value!(crate::prelude::Decimal);\n\n#[cfg(feature = \"with-bigdecimal\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-bigdecimal\")))]\nimpl_into_active_value!(crate::prelude::BigDecimal);\n\n#[cfg(feature = \"with-uuid\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-uuid\")))]\nimpl_into_active_value!(crate::prelude::Uuid);\n\n#[cfg(feature = \"with-time\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-time\")))]\nimpl_into_active_value!(crate::prelude::TimeDate);\n\n#[cfg(feature = \"with-time\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-time\")))]\nimpl_into_active_value!(crate::prelude::TimeTime);\n\n#[cfg(feature = \"with-time\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-time\")))]\nimpl_into_active_value!(crate::prelude::TimeDateTime);\n\n#[cfg(feature = \"with-time\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-time\")))]\nimpl_into_active_value!(crate::prelude::TimeDateTimeWithTimeZone);\n\n#[cfg(feature = \"with-ipnetwork\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"with-ipnetwork\")))]\nimpl_into_active_value!(crate::prelude::IpNetwork);\n\nimpl<V> Default for ActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    /// Create an [ActiveValue::NotSet]\n    fn default() -> Self {\n        Self::NotSet\n    }\n}\n\nimpl<V> ActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    /// Create an [ActiveValue::Set]\n    pub fn set(value: V) -> Self {\n        Self::Set(value)\n    }\n\n    /// Check if the [ActiveValue] is [ActiveValue::Set]\n    pub fn is_set(&self) -> bool {\n        matches!(self, Self::Set(_))\n    }\n\n    /// Create an [ActiveValue::Unchanged]\n    pub fn unchanged(value: V) -> Self {\n        Self::Unchanged(value)\n    }\n\n    /// Check if the [ActiveValue] is [ActiveValue::Unchanged]\n    pub fn is_unchanged(&self) -> bool {\n        matches!(self, Self::Unchanged(_))\n    }\n\n    /// Create an [ActiveValue::NotSet]\n    pub fn not_set() -> Self {\n        Self::default()\n    }\n\n    /// Check if the [ActiveValue] is [ActiveValue::NotSet]\n    pub fn is_not_set(&self) -> bool {\n        matches!(self, Self::NotSet)\n    }\n\n    /// Take ownership of the inner value, also setting self to `NotSet`\n    pub fn take(&mut self) -> Option<V> {\n        match std::mem::take(self) {\n            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => Some(value),\n            ActiveValue::NotSet => None,\n        }\n    }\n\n    /// Get an owned value of the [ActiveValue]\n    ///\n    /// # Panics\n    ///\n    /// Panics if it is [ActiveValue::NotSet]\n    pub fn unwrap(self) -> V {\n        match self {\n            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => value,\n            ActiveValue::NotSet => panic!(\"Cannot unwrap ActiveValue::NotSet\"),\n        }\n    }\n\n    /// Take ownership of the inner value, consuming self\n    pub fn into_value(self) -> Option<Value> {\n        match self {\n            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => Some(value.into()),\n            ActiveValue::NotSet => None,\n        }\n    }\n\n    /// Wrap the [Value] into a `ActiveValue<Value>`\n    pub fn into_wrapped_value(self) -> ActiveValue<Value> {\n        match self {\n            Self::Set(value) => ActiveValue::set(value.into()),\n            Self::Unchanged(value) => ActiveValue::unchanged(value.into()),\n            Self::NotSet => ActiveValue::not_set(),\n        }\n    }\n\n    /// Reset the value from [ActiveValue::Unchanged] to [ActiveValue::Set],\n    /// leaving [ActiveValue::NotSet] untouched.\n    pub fn reset(&mut self) {\n        *self = match self.take() {\n            Some(value) => ActiveValue::Set(value),\n            None => ActiveValue::NotSet,\n        };\n    }\n\n    /// `Set(value)`, except when [`self.is_unchanged()`][ActiveValue#method.is_unchanged]\n    /// and `value` equals the current [Unchanged][ActiveValue::Unchanged] value.\n    ///\n    /// This is useful when you have an [Unchanged][ActiveValue::Unchanged] value from the database,\n    /// then update it using this method,\n    /// and then use [`.is_unchanged()`][ActiveValue#method.is_unchanged] to see whether it has *actually* changed.\n    ///\n    /// The same nice effect applies to the entire `ActiveModel`.\n    /// You can now meaningfully use [ActiveModelTrait::is_changed][ActiveModelTrait#method.is_changed]\n    /// to see whether are any changes that need to be saved to the database.\n    ///\n    /// ## Examples\n    ///\n    /// ```\n    /// # use sea_orm::ActiveValue;\n    /// #\n    /// let mut value = ActiveValue::Unchanged(\"old\");\n    ///\n    /// // This wouldn't be the case if we used plain `value = Set(\"old\");`\n    /// value.set_if_not_equals(\"old\");\n    /// assert!(value.is_unchanged());\n    ///\n    /// // Only when we change the actual `&str` value, it becomes `Set`\n    /// value.set_if_not_equals(\"new\");\n    /// assert_eq!(value.is_unchanged(), false);\n    /// assert_eq!(value, ActiveValue::Set(\"new\"));\n    /// ```\n    pub fn set_if_not_equals(&mut self, value: V)\n    where\n        V: PartialEq,\n    {\n        match self {\n            ActiveValue::Unchanged(current) if &value == current => {}\n            _ => *self = ActiveValue::Set(value),\n        }\n    }\n\n    /// `Set(value)`, except when [`self.is_unchanged()`][ActiveValue#method.is_unchanged],\n    /// `value` equals the current [Unchanged][ActiveValue::Unchanged] value, and `value`\n    /// does not match a given predicate.\n    ///\n    /// This is useful in the same situations as [ActiveValue#method.set_if_not_equals] as\n    /// well as when you want to leave an existing [Set][ActiveValue::Set] value alone\n    /// depending on a condition, such as ensuring a `None` value never replaced an\n    /// existing `Some` value. This can come up when trying to merge two [ActiveValue]s.\n    ///\n    /// ## Examples\n    ///\n    /// ```\n    /// # use sea_orm::ActiveValue;\n    /// #\n    /// let mut value = ActiveValue::Set(Some(\"old\"));\n    ///\n    /// // since Option::is_some(None) == false, we leave the existing set value alone\n    /// value.set_if_not_equals_and(None, Option::is_some);\n    /// assert_eq!(value, ActiveValue::Set(Some(\"old\")));\n    ///\n    /// // since Option::is_some(Some(\"new\")) == true, we replace the set value\n    /// value.set_if_not_equals_and(Some(\"new\"), Option::is_some);\n    /// assert_eq!(value, ActiveValue::Set(Some(\"new\")));\n    /// ```\n    pub fn set_if_not_equals_and(&mut self, value: V, f: impl FnOnce(&V) -> bool)\n    where\n        V: PartialEq,\n    {\n        match self {\n            ActiveValue::Unchanged(current) if &value == current => {}\n            ActiveValue::Set(_) if !f(&value) => {}\n            _ => *self = ActiveValue::Set(value),\n        }\n    }\n\n    /// Get the inner value, unless `self` is [NotSet][ActiveValue::NotSet].\n    ///\n    /// There's also a panicking version: [ActiveValue::as_ref].\n    ///\n    /// ## Examples\n    ///\n    /// ```\n    /// # use sea_orm::ActiveValue;\n    /// #\n    /// assert_eq!(ActiveValue::Unchanged(42).try_as_ref(), Some(&42));\n    /// assert_eq!(ActiveValue::Set(42).try_as_ref(), Some(&42));\n    /// assert_eq!(ActiveValue::NotSet.try_as_ref(), None::<&i32>);\n    /// ```\n    pub fn try_as_ref(&self) -> Option<&V> {\n        match self {\n            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => Some(value),\n            ActiveValue::NotSet => None,\n        }\n    }\n}\n\nimpl<V> std::convert::AsRef<V> for ActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    /// # Panics\n    ///\n    /// Panics if it is [ActiveValue::NotSet].\n    ///\n    /// See [ActiveValue::try_as_ref] for a fallible non-panicking version.\n    fn as_ref(&self) -> &V {\n        match self {\n            ActiveValue::Set(value) | ActiveValue::Unchanged(value) => value,\n            ActiveValue::NotSet => panic!(\"Cannot borrow ActiveValue::NotSet\"),\n        }\n    }\n}\n\nimpl<V> PartialEq for ActiveValue<V>\nwhere\n    V: Into<Value> + std::cmp::PartialEq,\n{\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (ActiveValue::Set(l), ActiveValue::Set(r)) => l == r,\n            (ActiveValue::Unchanged(l), ActiveValue::Unchanged(r)) => l == r,\n            (ActiveValue::NotSet, ActiveValue::NotSet) => true,\n            _ => false,\n        }\n    }\n}\n\nimpl<V> From<ActiveValue<V>> for ActiveValue<Option<V>>\nwhere\n    V: Into<Value> + Nullable,\n{\n    fn from(value: ActiveValue<V>) -> Self {\n        match value {\n            ActiveValue::Set(value) => ActiveValue::set(Some(value)),\n            ActiveValue::Unchanged(value) => ActiveValue::unchanged(Some(value)),\n            ActiveValue::NotSet => ActiveValue::not_set(),\n        }\n    }\n}\n"
  },
  {
    "path": "src/entity/arrow_schema.rs",
    "content": "/// Trait for Entities with Arrow integration\npub trait ArrowSchema {\n    /// Get the Arrow schema for this Entity\n    fn arrow_schema() -> sea_orm_arrow::arrow::datatypes::Schema;\n}\n"
  },
  {
    "path": "src/entity/base_entity.rs",
    "content": "use crate::{\n    ActiveModelBehavior, ActiveModelTrait, ColumnTrait, Delete, DeleteMany, DeleteOne,\n    FromQueryResult, Identity, Insert, InsertMany, ModelTrait, PrimaryKeyArity, PrimaryKeyToColumn,\n    PrimaryKeyTrait, QueryFilter, Related, RelationBuilder, RelationTrait, RelationType, Select,\n    Update, UpdateMany, UpdateOne, ValidatedDeleteOne,\n};\nuse sea_query::{Iden, IntoIden, IntoTableRef, IntoValueTuple, TableRef};\nuse std::fmt::Debug;\npub use strum::IntoEnumIterator as Iterable;\n\n/// Ensure the identifier for an Entity can be converted to a static str\npub trait IdenStatic: Iden + Copy + Debug + Send + Sync + 'static {\n    /// Method to call to get the static string identity\n    fn as_str(&self) -> &'static str;\n}\n\n/// A Trait for mapping an Entity to a database table\npub trait EntityName: IdenStatic + Default {\n    /// Method to get the name for the schema, defaults to [Option::None] if not set\n    fn schema_name(&self) -> Option<&str> {\n        None\n    }\n\n    /// Method to get the comment for the schema, defaults to [Option::None] if not set\n    fn comment(&self) -> Option<&str> {\n        None\n    }\n\n    /// Get the name of the table\n    fn table_name(&self) -> &'static str;\n\n    /// Get the [TableRef] from invoking the `self.schema_name()`\n    fn table_ref(&self) -> TableRef {\n        match self.schema_name() {\n            Some(schema) => (schema.to_owned(), self.into_iden()).into_table_ref(),\n            None => self.into_table_ref(),\n        }\n    }\n}\n\n/// An abstract base class for defining Entities.\n///\n/// This trait provides an API for you to inspect it's properties\n/// - Column (implemented [`ColumnTrait`])\n/// - Relation (implemented [`RelationTrait`])\n/// - Primary Key (implemented [`PrimaryKeyTrait`] and [`PrimaryKeyToColumn`])\n///\n/// This trait also provides an API for CRUD actions\n/// - Select: `find`, `find_*`\n/// - Insert: `insert`, `insert_*`\n/// - Update: `update`, `update_*`\n/// - Delete: `delete`, `delete_*`\npub trait EntityTrait: EntityName {\n    #[allow(missing_docs)]\n    type Model: ModelTrait<Entity = Self> + FromQueryResult;\n\n    #[allow(missing_docs)]\n    type ModelEx: ModelTrait<Entity = Self>;\n\n    #[allow(missing_docs)]\n    type ActiveModel: ActiveModelBehavior<Entity = Self>;\n\n    #[allow(missing_docs)]\n    type ActiveModelEx: ActiveModelTrait<Entity = Self>;\n\n    #[allow(missing_docs)]\n    type Column: ColumnTrait;\n\n    #[allow(missing_docs)]\n    type Relation: RelationTrait;\n\n    #[allow(missing_docs)]\n    type PrimaryKey: PrimaryKeyTrait + PrimaryKeyToColumn<Column = Self::Column>;\n\n    /// Construct a belongs to relation, where this table has a foreign key to\n    /// another table.\n    fn belongs_to<R>(related: R) -> RelationBuilder<Self, R>\n    where\n        R: EntityTrait,\n    {\n        RelationBuilder::new(RelationType::HasOne, Self::default(), related, false)\n    }\n\n    /// Construct a has one relation\n    fn has_one<R>(_: R) -> RelationBuilder<Self, R>\n    where\n        R: EntityTrait + Related<Self>,\n    {\n        RelationBuilder::from_rel(RelationType::HasOne, R::to().rev(), true)\n    }\n\n    /// Construct a has many relation\n    fn has_many<R>(_: R) -> RelationBuilder<Self, R>\n    where\n        R: EntityTrait + Related<Self>,\n    {\n        RelationBuilder::from_rel(RelationType::HasMany, R::to().rev(), true)\n    }\n\n    /// Construct a has many relation, with the Relation provided.\n    /// This is for the case where `Related<Self>` is not possible.\n    fn has_many_via<R, T>(_: R, rel: T) -> RelationBuilder<Self, R>\n    where\n        R: EntityTrait,\n        T: RelationTrait,\n    {\n        RelationBuilder::from_rel(RelationType::HasMany, rel.def().rev(), true)\n    }\n\n    /// Construct select statement to find one / all models\n    ///\n    /// - To select columns, join tables and group by expressions, see [`QuerySelect`](crate::query::QuerySelect)\n    /// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)\n    /// - To apply order by expressions, see [`QueryOrder`](crate::query::QueryOrder)\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         vec![\n    /// #             cake::Model {\n    /// #                 id: 1,\n    /// #                 name: \"New York Cheese\".to_owned(),\n    /// #             },\n    /// #         ],\n    /// #         vec![\n    /// #             cake::Model {\n    /// #                 id: 1,\n    /// #                 name: \"New York Cheese\".to_owned(),\n    /// #             },\n    /// #             cake::Model {\n    /// #                 id: 2,\n    /// #                 name: \"Chocolate Forest\".to_owned(),\n    /// #             },\n    /// #         ],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find().one(&db).await?,\n    ///     Some(cake::Model {\n    ///         id: 1,\n    ///         name: \"New York Cheese\".to_owned(),\n    ///     })\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find().all(&db).await?,\n    ///     [\n    ///         cake::Model {\n    ///             id: 1,\n    ///             name: \"New York Cheese\".to_owned(),\n    ///         },\n    ///         cake::Model {\n    ///             id: 2,\n    ///             name: \"Chocolate Forest\".to_owned(),\n    ///         },\n    ///     ]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::Postgres,\n    ///             r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" LIMIT $1\"#,\n    ///             [1u64.into()]\n    ///         ),\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::Postgres,\n    ///             r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n    ///             []\n    ///         ),\n    ///     ]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn find() -> Select<Self> {\n        Select::new()\n    }\n\n    /// Same as `find_related`, but using the other Entity's relation definition.\n    /// Not stable.\n    #[doc(hidden)]\n    fn find_related_rev<R>() -> Select<R>\n    where\n        R: EntityTrait,\n        R: Related<Self>,\n    {\n        use crate::{JoinType, QuerySelect};\n        Select::<R>::new().join_join(JoinType::InnerJoin, R::to(), R::via())\n    }\n\n    /// Find a model by primary key\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [\n    /// #             cake::Model {\n    /// #                 id: 11,\n    /// #                 name: \"Sponge Cake\".to_owned(),\n    /// #             },\n    /// #         ],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find_by_id(11).all(&db).await?,\n    ///     [cake::Model {\n    ///         id: 11,\n    ///         name: \"Sponge Cake\".to_owned(),\n    ///     }]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = $1\"#,\n    ///         [11i32.into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    /// Find by composite key\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [\n    /// #             cake_filling::Model {\n    /// #                 cake_id: 2,\n    /// #                 filling_id: 3,\n    /// #             },\n    /// #         ],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake_filling};\n    ///\n    /// assert_eq!(\n    ///     cake_filling::Entity::find_by_id((2, 3)).all(&db).await?,\n    ///     [cake_filling::Model {\n    ///         cake_id: 2,\n    ///         filling_id: 3,\n    ///     }]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         [\n    ///             r#\"SELECT \"cake_filling\".\"cake_id\", \"cake_filling\".\"filling_id\" FROM \"cake_filling\"\"#,\n    ///             r#\"WHERE \"cake_filling\".\"cake_id\" = $1 AND \"cake_filling\".\"filling_id\" = $2\"#,\n    ///         ].join(\" \").as_str(),\n    ///         [2i32.into(), 3i32.into()]\n    ///     )]);\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn find_by_id<T>(values: T) -> Select<Self>\n    where\n        T: Into<<Self::PrimaryKey as PrimaryKeyTrait>::ValueType>,\n    {\n        let mut select = Self::find();\n        let mut keys = Self::PrimaryKey::iter();\n        for v in values.into().into_value_tuple() {\n            if let Some(key) = keys.next() {\n                let col = key.into_column();\n                select = select.filter(col.eq(v));\n            } else {\n                unreachable!(\"primary key arity mismatch\");\n            }\n        }\n        select\n    }\n\n    /// Get primary key as Identity\n    fn primary_key_identity() -> Identity {\n        let mut cols = Self::PrimaryKey::iter();\n        macro_rules! next {\n            () => {\n                cols.next()\n                    .expect(\"Already checked arity\")\n                    .into_column()\n                    .as_column_ref()\n                    .1\n            };\n        }\n        match <<Self::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n            1 => {\n                let s1 = next!();\n                Identity::Unary(s1)\n            }\n            2 => {\n                let s1 = next!();\n                let s2 = next!();\n                Identity::Binary(s1, s2)\n            }\n            3 => {\n                let s1 = next!();\n                let s2 = next!();\n                let s3 = next!();\n                Identity::Ternary(s1, s2, s3)\n            }\n            len => {\n                let mut vec = Vec::with_capacity(len);\n                for _ in 0..len {\n                    let s = next!();\n                    vec.push(s);\n                }\n                Identity::Many(vec)\n            }\n        }\n    }\n\n    /// Insert a model into database\n    ///\n    /// # Example (Postgres)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[maplit::btreemap! {\n    /// #         \"id\" => Into::<Value>::into(15),\n    /// #     }]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let apple = cake::ActiveModel {\n    ///     name: Set(\"Apple Pie\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// let insert_result = cake::Entity::insert(apple).exec(&db).await?;\n    ///\n    /// assert_eq!(dbg!(insert_result.last_insert_id), 15);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"INSERT INTO \"cake\" (\"name\") VALUES ($1) RETURNING \"id\"\"#,\n    ///         [\"Apple Pie\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// # Example (MySQL)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::MySql)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 15,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let apple = cake::ActiveModel {\n    ///     name: Set(\"Apple Pie\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// let insert_result = cake::Entity::insert(apple).exec(&db).await?;\n    ///\n    /// assert_eq!(insert_result.last_insert_id, 15);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::MySql,\n    ///         r#\"INSERT INTO `cake` (`name`) VALUES (?)\"#,\n    ///         [\"Apple Pie\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// To get back inserted Model\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Apple Pie\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::insert(cake::ActiveModel {\n    ///         id: NotSet,\n    ///         name: Set(\"Apple Pie\".to_owned()),\n    ///     })\n    ///     .exec_with_returning(&db)\n    ///     .await?,\n    ///     cake::Model {\n    ///         id: 1,\n    ///         name: \"Apple Pie\".to_owned(),\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log()[0].statements()[0].sql,\n    ///     r#\"INSERT INTO \"cake\" (\"name\") VALUES ($1) RETURNING \"id\", \"name\"\"#\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn insert<A>(model: A) -> Insert<A>\n    where\n        A: ActiveModelTrait<Entity = Self>,\n    {\n        Insert::one(model)\n    }\n\n    /// Insert many models into database\n    ///\n    /// # Example (Postgres)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[maplit::btreemap! {\n    /// #         \"id\" => Into::<Value>::into(28),\n    /// #     }]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let apple = cake::ActiveModel {\n    ///     name: Set(\"Apple Pie\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    /// let orange = cake::ActiveModel {\n    ///     name: Set(\"Orange Scone\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// let insert_result = cake::Entity::insert_many::<cake::ActiveModel, _>([])\n    ///     .exec(&db)\n    ///     .await?;\n    ///\n    /// assert_eq!(insert_result.last_insert_id, None);\n    ///\n    /// let insert_result = cake::Entity::insert_many([apple, orange]).exec(&db).await?;\n    ///\n    /// assert_eq!(insert_result.last_insert_id, Some(28));\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"INSERT INTO \"cake\" (\"name\") VALUES ($1), ($2) RETURNING \"id\"\"#,\n    ///         [\"Apple Pie\".into(), \"Orange Scone\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// # Example (MySQL)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::MySql)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 28,\n    /// #             rows_affected: 2,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let apple = cake::ActiveModel {\n    ///     name: Set(\"Apple Pie\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    /// let orange = cake::ActiveModel {\n    ///     name: Set(\"Orange Scone\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// let insert_result = cake::Entity::insert_many([apple, orange]).exec(&db).await?;\n    ///\n    /// assert_eq!(insert_result.last_insert_id, Some(28));\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::MySql,\n    ///         r#\"INSERT INTO `cake` (`name`) VALUES (?), (?)\"#,\n    ///         [\"Apple Pie\".into(), \"Orange Scone\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// Before 1.1.3, if the active models have different column set, this method would panic.\n    /// Now, it'd attempt to fill in the missing columns with null\n    /// (which may or may not be correct, depending on whether the column is nullable):\n    ///\n    /// ```\n    /// use sea_orm::{\n    ///     DbBackend,\n    ///     entity::*,\n    ///     query::*,\n    ///     tests_cfg::{cake, cake_filling},\n    /// };\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::insert_many([\n    ///         cake::ActiveModel {\n    ///             id: NotSet,\n    ///             name: Set(\"Apple Pie\".to_owned()),\n    ///         },\n    ///         cake::ActiveModel {\n    ///             id: NotSet,\n    ///             name: Set(\"Orange Scone\".to_owned()),\n    ///         }\n    ///     ])\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"name\") VALUES ('Apple Pie'), ('Orange Scone')\"#,\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake_filling::Entity::insert_many([\n    ///         cake_filling::ActiveModel {\n    ///             cake_id: ActiveValue::set(2),\n    ///             filling_id: ActiveValue::NotSet,\n    ///         },\n    ///         cake_filling::ActiveModel {\n    ///             cake_id: ActiveValue::NotSet,\n    ///             filling_id: ActiveValue::set(3),\n    ///         }\n    ///     ])\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"INSERT INTO \"cake_filling\" (\"cake_id\", \"filling_id\") VALUES (2, NULL), (NULL, 3)\"#,\n    /// );\n    /// ```\n    ///\n    /// To get back inserted Models\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Apple Pie\".to_owned(),\n    /// #         }, cake::Model {\n    /// #             id: 2,\n    /// #             name: \"Choco Pie\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::insert_many([\n    ///         cake::ActiveModel {\n    ///             id: NotSet,\n    ///             name: Set(\"Apple Pie\".to_owned()),\n    ///         },\n    ///         cake::ActiveModel {\n    ///             id: NotSet,\n    ///             name: Set(\"Choco Pie\".to_owned()),\n    ///         },\n    ///     ])\n    ///     .exec_with_returning(&db)\n    ///     .await?,\n    ///     [\n    ///         cake::Model {\n    ///             id: 1,\n    ///             name: \"Apple Pie\".to_owned(),\n    ///         },\n    ///         cake::Model {\n    ///             id: 2,\n    ///             name: \"Choco Pie\".to_owned(),\n    ///         }\n    ///     ]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log()[0].statements()[0].sql,\n    ///     r#\"INSERT INTO \"cake\" (\"name\") VALUES ($1), ($2) RETURNING \"id\", \"name\"\"#\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn insert_many<A, I>(models: I) -> InsertMany<A>\n    where\n        A: ActiveModelTrait<Entity = Self>,\n        I: IntoIterator<Item = A>,\n    {\n        InsertMany::many(models)\n    }\n\n    /// Update a model in database\n    ///\n    /// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)\n    ///\n    /// # Example (Postgres)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [fruit::Model {\n    /// #             id: 1,\n    /// #             name: \"Orange\".to_owned(),\n    /// #             cake_id: None,\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let orange = fruit::ActiveModel {\n    ///     id: Set(1),\n    ///     name: Set(\"Orange\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// assert_eq!(\n    ///     fruit::Entity::update(orange.clone())\n    ///         .validate()?\n    ///         .filter(fruit::Column::Name.contains(\"orange\"))\n    ///         .exec(&db)\n    ///         .await?,\n    ///     fruit::Model {\n    ///         id: 1,\n    ///         name: \"Orange\".to_owned(),\n    ///         cake_id: None,\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"UPDATE \"fruit\" SET \"name\" = $1 WHERE \"fruit\".\"id\" = $2 AND \"fruit\".\"name\" LIKE $3 RETURNING \"id\", \"name\", \"cake_id\"\"#,\n    ///         [\"Orange\".into(), 1i32.into(), \"%orange%\".into()]\n    ///     )]);\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// # Example (MySQL)\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::MySql)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .append_query_results([\n    /// #         [fruit::Model {\n    /// #             id: 1,\n    /// #             name: \"Orange\".to_owned(),\n    /// #             cake_id: None,\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let orange = fruit::ActiveModel {\n    ///     id: Set(1),\n    ///     name: Set(\"Orange\".to_owned()),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// assert_eq!(\n    ///     fruit::Entity::update(orange.clone())\n    ///         .validate()?\n    ///         .filter(fruit::Column::Name.contains(\"orange\"))\n    ///         .exec(&db)\n    ///         .await?,\n    ///     fruit::Model {\n    ///         id: 1,\n    ///         name: \"Orange\".to_owned(),\n    ///         cake_id: None,\n    ///     }\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::MySql,\n    ///             r#\"UPDATE `fruit` SET `name` = ? WHERE `fruit`.`id` = ? AND `fruit`.`name` LIKE ?\"#,\n    ///             [\"Orange\".into(), 1i32.into(), \"%orange%\".into()]\n    ///         ),\n    ///         Transaction::from_sql_and_values(\n    ///             DbBackend::MySql,\n    ///             r#\"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = ? LIMIT ?\"#,\n    ///             [1i32.into(), 1u64.into()]\n    ///         )]);\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn update<A>(model: A) -> UpdateOne<A>\n    where\n        A: ActiveModelTrait<Entity = Self>,\n    {\n        Update::one(model)\n    }\n\n    /// Update many models in database\n    ///\n    /// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 5,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{\n    ///     entity::*,\n    ///     query::*,\n    ///     sea_query::{Expr, Value},\n    ///     tests_cfg::fruit,\n    /// };\n    ///\n    /// let update_result = fruit::Entity::update_many()\n    ///     .col_expr(fruit::Column::CakeId, Expr::value(Value::Int(None)))\n    ///     .filter(fruit::Column::Name.contains(\"Apple\"))\n    ///     .exec(&db)\n    ///     .await?;\n    ///\n    /// assert_eq!(update_result.rows_affected, 5);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"UPDATE \"fruit\" SET \"cake_id\" = $1 WHERE \"fruit\".\"name\" LIKE $2\"#,\n    ///         [Value::Int(None), \"%Apple%\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn update_many() -> UpdateMany<Self> {\n        Update::many(Self::default())\n    }\n\n    /// Delete a model from database\n    ///\n    /// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let orange = fruit::ActiveModel {\n    ///     id: Set(3),\n    ///     ..Default::default()\n    /// };\n    ///\n    /// let delete_result = fruit::Entity::delete(orange).exec(&db).await?;\n    ///\n    /// assert_eq!(delete_result.rows_affected, 1);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"DELETE FROM \"fruit\" WHERE \"fruit\".\"id\" = $1\"#,\n    ///         [3i32.into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn delete<A>(model: A) -> DeleteOne<Self>\n    where\n        A: ActiveModelTrait<Entity = Self>,\n    {\n        Delete::one(model)\n    }\n\n    /// Delete many models from database\n    ///\n    /// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 5,\n    /// #         },\n    /// #     ])\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 15,\n    /// #             name: \"Apple Pie\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let delete_result = fruit::Entity::delete_many()\n    ///     .filter(fruit::Column::Name.contains(\"Apple\"))\n    ///     .exec(&db)\n    ///     .await?;\n    ///\n    /// assert_eq!(delete_result.rows_affected, 5);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"DELETE FROM \"fruit\" WHERE \"fruit\".\"name\" LIKE $1\"#,\n    ///         [\"%Apple%\".into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn delete_many() -> DeleteMany<Self> {\n        Delete::many(Self::default())\n    }\n\n    /// Delete a model based on primary key\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// let delete_result = fruit::Entity::delete_by_id(1).exec(&db).await?;\n    ///\n    /// assert_eq!(delete_result.rows_affected, 1);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"DELETE FROM \"fruit\" WHERE \"fruit\".\"id\" = $1\"#,\n    ///         [1i32.into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    /// Delete by composite key\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    ///\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_exec_results([\n    /// #         MockExecResult {\n    /// #             last_insert_id: 0,\n    /// #             rows_affected: 1,\n    /// #         },\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake_filling};\n    ///\n    /// let delete_result = cake_filling::Entity::delete_by_id((2, 3)).exec(&db).await?;\n    ///\n    /// assert_eq!(delete_result.rows_affected, 1);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"DELETE FROM \"cake_filling\" WHERE \"cake_filling\".\"cake_id\" = $1 AND \"cake_filling\".\"filling_id\" = $2\"#,\n    ///         [2i32.into(), 3i32.into()]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn delete_by_id<T>(values: T) -> ValidatedDeleteOne<Self>\n    where\n        T: Into<<Self::PrimaryKey as PrimaryKeyTrait>::ValueType>,\n    {\n        let mut am = Self::ActiveModel::default();\n        let mut keys = Self::PrimaryKey::iter();\n        for v in values.into().into_value_tuple() {\n            if let Some(key) = keys.next() {\n                let col = key.into_column();\n                am.set(col, v);\n            } else {\n                unreachable!(\"primary key arity mismatch\");\n            }\n        }\n        Delete::one(am).validate().expect(\"Must be valid\")\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    #[test]\n    fn test_delete_by_id_1() {\n        use crate::tests_cfg::cake;\n        use crate::{DbBackend, entity::*, query::*};\n        assert_eq!(\n            cake::Entity::delete_by_id(1)\n                .build(DbBackend::Sqlite)\n                .to_string(),\n            r#\"DELETE FROM \"cake\" WHERE \"cake\".\"id\" = 1\"#,\n        );\n    }\n\n    #[test]\n    fn test_delete_by_id_2() {\n        use crate::tests_cfg::cake_filling_price;\n        use crate::{DbBackend, entity::*, query::*};\n        assert_eq!(\n            cake_filling_price::Entity::delete_by_id((1, 2))\n                .build(DbBackend::Sqlite)\n                .to_string(),\n            r#\"DELETE FROM \"public\".\"cake_filling_price\" WHERE \"cake_filling_price\".\"cake_id\" = 1 AND \"cake_filling_price\".\"filling_id\" = 2\"#,\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn entity_model_1() {\n        use crate::entity::*;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Entity.table_name(), \"hello\");\n        assert_eq!(hello::Entity.schema_name(), None);\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn entity_model_2() {\n        use crate::entity::*;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\", schema_name = \"world\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Entity.table_name(), \"hello\");\n        assert_eq!(hello::Entity.schema_name(), Some(\"world\"));\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn entity_model_3() {\n        use crate::{DbBackend, entity::*, query::*};\n        use std::borrow::Cow;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\", schema_name = \"world\")]\n            pub struct Model {\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        fn delete_by_id<T>(value: T)\n        where\n            T: Into<<<hello::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType>,\n        {\n            assert_eq!(\n                hello::Entity::delete_by_id(value)\n                    .build(DbBackend::Sqlite)\n                    .to_string(),\n                r#\"DELETE FROM \"world\".\"hello\" WHERE \"hello\".\"id\" = 'UUID'\"#\n            );\n        }\n\n        delete_by_id(\"UUID\".to_string());\n        delete_by_id(\"UUID\");\n        delete_by_id(Cow::from(\"UUID\"));\n    }\n\n    #[smol_potat::test]\n    async fn test_find_by_id() {\n        use crate::tests_cfg::{cake, cake_filling};\n        use crate::{DbBackend, EntityTrait, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::MySql).into_connection();\n\n        cake::Entity::find_by_id(1).all(&db).await.ok();\n        cake_filling::Entity::find_by_id((2, 3)).all(&db).await.ok();\n\n        // below does not compile:\n\n        // cake::Entity::find_by_id((1, 2)).all(&db).await.ok();\n        // cake_filling::Entity::find_by_id(1).all(&db).await.ok();\n        // cake_filling::Entity::find_by_id((1, 2, 3))\n        //     .all(&db)\n        //     .await\n        //     .ok();\n    }\n\n    #[test]\n    fn test_triangle() {\n        mod triangle {\n            use crate as sea_orm;\n            use sea_orm::entity::prelude::*;\n            use serde::{Deserialize, Serialize};\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"triangle\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                pub p1: Point,\n                pub p2: Point,\n                pub p3: Point,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n\n            #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, FromJsonQueryResult)]\n            pub struct Point {\n                pub x: f64,\n                pub y: f64,\n            }\n        }\n        use triangle::{Model as Triangle, Point};\n\n        impl Triangle {\n            fn area(&self) -> f64 {\n                let a = self.p1.distance_to(&self.p2);\n                let b = self.p2.distance_to(&self.p3);\n                let c = self.p3.distance_to(&self.p1);\n                let s = (a + b + c) / 2.0;\n                (s * (s - a) * (s - b) * (s - c)).sqrt()\n            }\n        }\n\n        impl Point {\n            fn distance_to(&self, p: &Point) -> f64 {\n                let dx = self.x - p.x;\n                let dy = self.y - p.y;\n                (dx * dx + dy * dy).sqrt()\n            }\n        }\n\n        assert!(\n            (Triangle {\n                id: 1,\n                p1: Point { x: 0., y: 0. },\n                p2: Point { x: 2., y: 0. },\n                p3: Point { x: 0., y: 2. },\n            }\n            .area()\n                - 2.)\n                .abs()\n                < 0.00000001\n        );\n    }\n}\n"
  },
  {
    "path": "src/entity/column/types/postgres_array.rs",
    "content": "use super::*;\nuse crate::ExprTrait;\n\nmacro_rules! bind_array_oper {\n    ($vis:vis $op:ident) => {\n        /// Postgres only.\n        $vis fn $op<V, I>(&self, v: I) -> Expr\n        where\n            V: Into<Value> + sea_query::ValueType + sea_query::postgres_array::NotU8,\n            I: IntoIterator<Item = V>,\n        {\n            let vec: Vec<_> = v.into_iter().collect();\n            Expr::col(self.as_column_ref()).$op(self.0.save_as(Expr::val(vec)))\n        }\n    };\n    ($vis:vis $op:ident, trait $value_ty:ident) => {\n        /// Postgres only.\n        $vis fn $op<V, I>(&self, v: I) -> Expr\n        where\n            V: Into<Value> + $value_ty + sea_query::ValueType + sea_query::postgres_array::NotU8,\n            I: IntoIterator<Item = V>,\n        {\n            let vec: Vec<_> = v.into_iter().collect();\n            Expr::col(self.as_column_ref()).$op(self.0.save_as(Expr::val(vec)))\n        }\n    };\n    ($vis:vis $op:ident, $func:ident) => {\n        /// Postgres only.\n        $vis fn $op<V, I>(&self, v: I) -> Expr\n        where\n            V: Into<Value> + sea_query::ValueType + sea_query::postgres_array::NotU8,\n            I: IntoIterator<Item = V>,\n        {\n            self.0.$func(v)\n        }\n    };\n    ($vis:vis $op:ident, $func:ident, trait $value_ty:ident) => {\n        /// Postgres only.\n        $vis fn $op<V, I>(&self, v: I) -> Expr\n        where\n            V: Into<Value> + $value_ty + sea_query::ValueType + sea_query::postgres_array::NotU8,\n            I: IntoIterator<Item = V>,\n        {\n            self.0.$func(v)\n        }\n    };\n}\n\nimpl<E: EntityTrait> NumericArrayColumn<E> {\n    boilerplate!(pub);\n\n    bind_array_oper!(pub eq, trait NumericValue);\n    bind_array_oper!(pub ne, trait NumericValue);\n    bind_array_oper!(pub contains, array_contains, trait NumericValue);\n    bind_array_oper!(pub contained, array_contained, trait NumericValue);\n    bind_array_oper!(pub overlap, array_overlap, trait NumericValue);\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n\nimpl<E: EntityTrait> GenericArrayColumn<E> {\n    boilerplate!(pub);\n\n    bind_array_oper!(pub eq);\n    bind_array_oper!(pub ne);\n    bind_array_oper!(pub contains, array_contains);\n    bind_array_oper!(pub contained, array_contained);\n    bind_array_oper!(pub overlap, array_overlap);\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n"
  },
  {
    "path": "src/entity/column/types/with_datetime.rs",
    "content": "use super::*;\nuse sea_query::{DateLikeValue, DateTimeLikeValue, TimeLikeValue};\n\nimpl<E: EntityTrait> DateLikeColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait DateLikeValue);\n    bind_oper!(pub ne, ne, trait DateLikeValue);\n    bind_oper!(pub gt, gt, trait DateLikeValue);\n    bind_oper!(pub gte, gte, trait DateLikeValue);\n    bind_oper!(pub lt, lt, trait DateLikeValue);\n    bind_oper!(pub lte, lte, trait DateLikeValue);\n\n    bind_oper_2!(pub between, between, trait DateLikeValue);\n    bind_oper_2!(pub not_between, not_between, trait DateLikeValue);\n\n    bind_oper_0!(pub max, max);\n    bind_oper_0!(pub min, min);\n    bind_oper_0!(pub sum, sum);\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait DateLikeValue);\n\n    bind_vec_func!(pub is_in, is_in, trait DateLikeValue);\n    bind_vec_func!(pub is_not_in, is_not_in, trait DateLikeValue);\n\n    /// `= ANY(..)` operator. Postgres only.\n    #[cfg(feature = \"postgres-array\")]\n    pub fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + DateLikeValue + sea_query::ValueType + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        self.0.eq_any(v)\n    }\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n\nimpl<E: EntityTrait> TimeLikeColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait TimeLikeValue);\n    bind_oper!(pub ne, ne, trait TimeLikeValue);\n    bind_oper!(pub gt, gt, trait TimeLikeValue);\n    bind_oper!(pub gte, gte, trait TimeLikeValue);\n    bind_oper!(pub lt, lt, trait TimeLikeValue);\n    bind_oper!(pub lte, lte, trait TimeLikeValue);\n\n    bind_oper_2!(pub between, between, trait TimeLikeValue);\n    bind_oper_2!(pub not_between, not_between, trait TimeLikeValue);\n\n    bind_oper_0!(pub max, max);\n    bind_oper_0!(pub min, min);\n    bind_oper_0!(pub sum, sum);\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait TimeLikeValue);\n\n    bind_vec_func!(pub is_in, is_in, trait TimeLikeValue);\n    bind_vec_func!(pub is_not_in, is_not_in, trait TimeLikeValue);\n\n    /// `= ANY(..)` operator. Postgres only.\n    #[cfg(feature = \"postgres-array\")]\n    pub fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + TimeLikeValue + sea_query::ValueType + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        self.0.eq_any(v)\n    }\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n\nimpl<E: EntityTrait> DateTimeLikeColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait DateTimeLikeValue);\n    bind_oper!(pub ne, ne, trait DateTimeLikeValue);\n    bind_oper!(pub gt, gt, trait DateTimeLikeValue);\n    bind_oper!(pub gte, gte, trait DateTimeLikeValue);\n    bind_oper!(pub lt, lt, trait DateTimeLikeValue);\n    bind_oper!(pub lte, lte, trait DateTimeLikeValue);\n\n    bind_oper_2!(pub between, between, trait DateTimeLikeValue);\n    bind_oper_2!(pub not_between, not_between, trait DateTimeLikeValue);\n\n    bind_oper_0!(pub max, max);\n    bind_oper_0!(pub min, min);\n    bind_oper_0!(pub sum, sum);\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait DateTimeLikeValue);\n\n    bind_vec_func!(pub is_in, is_in, trait DateTimeLikeValue);\n    bind_vec_func!(pub is_not_in, is_not_in, trait DateTimeLikeValue);\n\n    /// `= ANY(..)` operator. Postgres only.\n    #[cfg(feature = \"postgres-array\")]\n    pub fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + DateTimeLikeValue + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        self.0.eq_any(v)\n    }\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n"
  },
  {
    "path": "src/entity/column/types/with_ipnetwork.rs",
    "content": "use super::*;\nuse crate::prelude::IpNetwork;\n\nimpl<E: EntityTrait> IpNetworkColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait Into<IpNetwork>);\n    bind_oper!(pub ne, ne, trait Into<IpNetwork>);\n    bind_oper!(pub gt, gt, trait Into<IpNetwork>);\n    bind_oper!(pub gte, gte, trait Into<IpNetwork>);\n    bind_oper!(pub lt, lt, trait Into<IpNetwork>);\n    bind_oper!(pub lte, lte, trait Into<IpNetwork>);\n\n    bind_oper_2!(pub between, between, trait Into<IpNetwork>);\n    bind_oper_2!(pub not_between, not_between, trait Into<IpNetwork>);\n\n    bind_oper_0!(pub max, max);\n    bind_oper_0!(pub min, min);\n    bind_oper_0!(pub sum, sum);\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait Into<IpNetwork>);\n\n    bind_vec_func!(pub is_in, is_in, trait Into<IpNetwork>);\n    bind_vec_func!(pub is_not_in, is_not_in, trait Into<IpNetwork>);\n\n    /// `= ANY(..)` operator. Postgres only.\n    #[cfg(feature = \"postgres-array\")]\n    pub fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + Into<IpNetwork> + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        self.0.eq_any(v)\n    }\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n"
  },
  {
    "path": "src/entity/column/types/with_json.rs",
    "content": "use super::*;\nuse crate::prelude::Json;\n\nimpl<E: EntityTrait> JsonColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait Into<Json>);\n    bind_oper!(pub ne, ne, trait Into<Json>);\n\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait Into<Json>);\n\n    bind_vec_func!(pub is_in, is_in, trait Into<Json>);\n    bind_vec_func!(pub is_not_in, is_not_in, trait Into<Json>);\n\n    /// `= ANY(..)` operator. Postgres only.\n    #[cfg(feature = \"postgres-array\")]\n    pub fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + Into<Json> + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        self.0.eq_any(v)\n    }\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n"
  },
  {
    "path": "src/entity/column/types/with_uuid.rs",
    "content": "use super::*;\nuse crate::prelude::{TextUuid, Uuid};\n\nimpl<E: EntityTrait> UuidColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait Into<Uuid>);\n    bind_oper!(pub ne, ne, trait Into<Uuid>);\n    bind_oper!(pub gt, gt, trait Into<Uuid>);\n    bind_oper!(pub gte, gte, trait Into<Uuid>);\n    bind_oper!(pub lt, lt, trait Into<Uuid>);\n    bind_oper!(pub lte, lte, trait Into<Uuid>);\n\n    bind_oper_2!(pub between, between, trait Into<Uuid>);\n    bind_oper_2!(pub not_between, not_between, trait Into<Uuid>);\n\n    bind_oper_0!(pub max, max);\n    bind_oper_0!(pub min, min);\n    bind_oper_0!(pub sum, sum);\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait Into<Uuid>);\n\n    bind_vec_func!(pub is_in, is_in, trait Into<Uuid>);\n    bind_vec_func!(pub is_not_in, is_not_in, trait Into<Uuid>);\n\n    /// `= ANY(..)` operator. Postgres only.\n    #[cfg(feature = \"postgres-array\")]\n    pub fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + Into<Uuid> + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        self.0.eq_any(v)\n    }\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n\nimpl<E: EntityTrait> TextUuidColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, type TextUuid);\n    bind_oper!(pub ne, ne, type TextUuid);\n    bind_oper!(pub gt, gt, type TextUuid);\n    bind_oper!(pub gte, gte, type TextUuid);\n    bind_oper!(pub lt, lt, type TextUuid);\n    bind_oper!(pub lte, lte, type TextUuid);\n\n    bind_oper_2!(pub between, between, type TextUuid);\n    bind_oper_2!(pub not_between, not_between, type TextUuid);\n\n    bind_oper_0!(pub max, max);\n    bind_oper_0!(pub min, min);\n    bind_oper_0!(pub sum, sum);\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, type TextUuid);\n\n    bind_vec_func!(pub is_in, is_in, type TextUuid);\n    bind_vec_func!(pub is_not_in, is_not_in, type TextUuid);\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n"
  },
  {
    "path": "src/entity/column/types.rs",
    "content": "#![allow(missing_docs)]\n\nuse crate::{ColumnDef, ColumnTrait, DynIden, EntityTrait, ExprTrait, Iden, IntoSimpleExpr, Value};\nuse sea_query::{Expr, NumericValue, NumericValueNullable, SelectStatement};\nuse std::borrow::Cow;\n\npub trait IntoOption<T> {\n    #[allow(dead_code)]\n    fn into_option(self) -> Option<T>;\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct BoolColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(BoolColumn);\n\n/// A column of numeric type, including integer, float and decimal\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct NumericColumn<E: EntityTrait>(pub E::Column);\n/// A column of numeric type, including integer, float and decimal that is also nullable\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct NumericColumnNullable<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(NumericColumn);\nimpl_expr_traits!(NumericColumnNullable);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct StringColumn<E: EntityTrait>(pub E::Column);\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct StringColumnNullable<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(StringColumn);\nimpl_expr_traits!(StringColumnNullable);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct BytesColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(BytesColumn);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct JsonColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(JsonColumn);\n// we dont need JsonColumnNullable because None can be converted to Json\n\n/// Supports both chrono and time Date\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct DateLikeColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(DateLikeColumn);\n\n/// Supports both chrono and time Time\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct TimeLikeColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(TimeLikeColumn);\n\n/// Supports both chrono and time DateTime\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct DateTimeLikeColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(DateTimeLikeColumn);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct UuidColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(UuidColumn);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct TextUuidColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(TextUuidColumn);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct IpNetworkColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(IpNetworkColumn);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct NumericArrayColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(NumericArrayColumn);\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]\npub struct GenericArrayColumn<E: EntityTrait>(pub E::Column);\nimpl_expr_traits!(GenericArrayColumn);\n\n#[cfg(feature = \"with-json\")]\nmod with_json;\n\n#[cfg(any(feature = \"with-chrono\", feature = \"with-time\"))]\nmod with_datetime;\n\n#[cfg(feature = \"with-uuid\")]\nmod with_uuid;\n\n#[cfg(feature = \"with-ipnetwork\")]\nmod with_ipnetwork;\n\n#[cfg(feature = \"postgres-array\")]\nmod postgres_array;\n\nmod macros {\n    macro_rules! impl_expr_traits {\n        ($ty:ident) => {\n            impl<E: EntityTrait> Iden for $ty<E> {\n                fn quoted(&self) -> std::borrow::Cow<'static, str> {\n                    self.0.quoted()\n                }\n                fn unquoted(&self) -> &str {\n                    self.0.unquoted()\n                }\n            }\n\n            impl<E: EntityTrait> IntoSimpleExpr for $ty<E> {\n                fn into_simple_expr(self) -> Expr {\n                    self.0.into_simple_expr()\n                }\n            }\n        };\n    }\n\n    macro_rules! bind_oper_0 {\n        ($vis:vis $op:ident, $bind_op:ident) => {\n            $vis fn $op(&self) -> Expr {\n                self.0.$bind_op()\n            }\n        };\n    }\n\n    macro_rules! bind_oper {\n        ($vis:vis $op:ident, $bind_op:ident, trait $value_ty:path) => {\n            $vis fn $op<V>(&self, v: V) -> Expr\n            where\n                V: Into<Value> + $value_ty,\n            {\n                self.0.$bind_op(v)\n            }\n        };\n        ($vis:vis $op:ident, $bind_op:ident, type $value_ty:path) => {\n            $vis fn $op<V>(&self, v: V) -> Expr\n            where\n                V: Into<$value_ty>,\n            {\n                self.0.$bind_op(v.into())\n            }\n        };\n    }\n\n    macro_rules! bind_expr_oper {\n        ($vis:vis $op:ident, $bind_op:ident) => {\n            $vis fn $op<T>(&self, expr: T) -> Expr\n            where\n                T: Into<Expr>,\n            {\n                Expr::col(self.as_column_ref()).$bind_op(expr)\n            }\n        };\n    }\n\n    macro_rules! bind_oper_2 {\n        ($vis:vis $op:ident, $bind_op:ident, trait $value_ty:path) => {\n            $vis fn $op<V>(&self, v1: V, v2: V) -> Expr\n            where\n                V: Into<Value> + $value_ty,\n            {\n                self.0.$bind_op(v1, v2)\n            }\n        };\n        ($vis:vis $op:ident, $bind_op:ident, type $value_ty:path) => {\n            $vis fn $op<V>(&self, v1: V, v2: V) -> Expr\n            where\n                V: Into<$value_ty>,\n            {\n                self.0.$bind_op(v1.into(), v2.into())\n            }\n        };\n    }\n\n    macro_rules! bind_vec_func {\n        ($vis:vis $op:ident, $bind_op:ident, trait $value_ty:path) => {\n            #[allow(clippy::wrong_self_convention)]\n            $vis fn $op<V, I>(&self, v: I) -> Expr\n            where\n                V: Into<Value> + $value_ty,\n                I: IntoIterator<Item = V>,\n            {\n                self.0.$bind_op(v)\n            }\n        };\n        ($vis:vis $op:ident, $bind_op:ident, type $value_ty:path) => {\n            #[allow(clippy::wrong_self_convention)]\n            $vis fn $op<V, I>(&self, v: I) -> Expr\n            where\n                V: Into<$value_ty>,\n                I: IntoIterator<Item = V>,\n            {\n                self.0.$bind_op(v.into_iter().map(|v| v.into()))\n            }\n        };\n    }\n\n    macro_rules! bind_subquery_func {\n        ($vis:vis $func:ident) => {\n            #[allow(clippy::wrong_self_convention)]\n            $vis fn $func(&self, s: SelectStatement) -> Expr {\n                self.0.$func(s)\n            }\n        };\n    }\n\n    macro_rules! boilerplate {\n        ($vis:vis) => {\n            /// Get the column definition with SQL attributes\n            $vis fn def(&self) -> ColumnDef {\n                self.0.def()\n            }\n\n            /// Get the enum type name if this is a enum column\n            $vis fn enum_type_name(&self) -> Option<&'static str> {\n                self.0.enum_type_name()\n            }\n\n            /// Get the name of the entity the column belongs to\n            $vis fn entity_name(&self) -> DynIden {\n                self.0.entity_name()\n            }\n\n            /// Get the table.column reference\n            $vis fn as_column_ref(&self) -> (DynIden, DynIden) {\n                self.0.as_column_ref()\n            }\n        };\n    }\n\n    pub(super) use bind_expr_oper;\n    pub(super) use bind_oper;\n    pub(super) use bind_oper_0;\n    pub(super) use bind_oper_2;\n    pub(super) use bind_subquery_func;\n    pub(super) use bind_vec_func;\n    pub(super) use boilerplate;\n    pub(super) use impl_expr_traits;\n}\n\nuse macros::*;\n\nimpl<E: EntityTrait> BoolColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait Into<bool>);\n    bind_oper!(pub ne, ne, trait Into<bool>);\n\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait Into<bool>);\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n\nmacro_rules! impl_numeric_column {\n    ($ty:ident, $trait:ident) => {\n    impl<E: EntityTrait> $ty<E> {\n        boilerplate!(pub);\n\n        bind_oper!(pub eq, eq, trait $trait);\n        bind_oper!(pub ne, ne, trait $trait);\n        bind_oper!(pub gt, gt, trait NumericValue);\n        bind_oper!(pub gte, gte, trait NumericValue);\n        bind_oper!(pub lt, lt, trait NumericValue);\n        bind_oper!(pub lte, lte, trait NumericValue);\n\n        bind_expr_oper!(pub add, add);\n        bind_expr_oper!(pub sub, sub);\n        bind_expr_oper!(pub div, div);\n        bind_expr_oper!(pub mul, mul);\n\n        bind_oper_2!(pub between, between, trait NumericValue);\n        bind_oper_2!(pub not_between, not_between, trait NumericValue);\n\n        bind_oper_0!(pub max, max);\n        bind_oper_0!(pub min, min);\n        bind_oper_0!(pub sum, sum);\n        bind_oper_0!(pub count, count);\n        bind_oper_0!(pub is_null, is_null);\n        bind_oper_0!(pub is_not_null, is_not_null);\n\n        bind_oper!(pub if_null, if_null, trait $trait);\n\n        bind_vec_func!(pub is_in, is_in, trait $trait);\n        bind_vec_func!(pub is_not_in, is_not_in, trait $trait);\n\n        /// `= ANY(..)` operator. Postgres only.\n        #[cfg(feature = \"postgres-array\")]\n        pub fn eq_any<V, I>(&self, v: I) -> Expr\n        where\n            V: Into<Value> + $trait + sea_query::postgres_array::NotU8,\n            I: IntoIterator<Item = V>,\n        {\n            self.0.eq_any(v)\n        }\n\n        bind_subquery_func!(pub in_subquery);\n        bind_subquery_func!(pub not_in_subquery);\n    }\n};}\nimpl_numeric_column!(NumericColumn, NumericValue);\nimpl_numeric_column!(NumericColumnNullable, NumericValueNullable);\n\nmacro_rules! impl_string_column {\n    ($ty:ident, $trait:path) => {\n    impl<E: EntityTrait> $ty<E> {\n        boilerplate!(pub);\n\n        bind_oper!(pub eq, eq, trait $trait);\n        bind_oper!(pub ne, ne, trait $trait);\n        bind_oper!(pub gt, gt, trait Into<String>);\n        bind_oper!(pub gte, gte, trait Into<String>);\n        bind_oper!(pub lt, lt, trait Into<String>);\n        bind_oper!(pub lte, lte, trait Into<String>);\n\n        bind_oper_2!(pub between, between, trait Into<String>);\n        bind_oper_2!(pub not_between, not_between, trait Into<String>);\n\n        bind_oper!(pub like, like, trait Into<String>);\n        bind_oper!(pub not_like, not_like, trait Into<String>);\n        bind_oper!(pub ilike, ilike, trait Into<String>);\n        bind_oper!(pub not_ilike, not_ilike, trait Into<String>);\n        bind_oper!(pub starts_with, starts_with, trait Into<String>);\n        bind_oper!(pub ends_with, ends_with, trait Into<String>);\n        bind_oper!(pub contains, contains, trait Into<String>);\n\n        bind_oper_0!(pub count, count);\n        bind_oper_0!(pub is_null, is_null);\n        bind_oper_0!(pub is_not_null, is_not_null);\n\n        bind_oper!(pub if_null, if_null, trait $trait);\n\n        bind_vec_func!(pub is_in, is_in, trait $trait);\n        bind_vec_func!(pub is_not_in, is_not_in, trait $trait);\n\n        /// `= ANY(..)` operator. Postgres only.\n        #[cfg(feature = \"postgres-array\")]\n        pub fn eq_any<V, I>(&self, v: I) -> Expr\n        where\n            V: Into<Value> + Into<String> + sea_query::postgres_array::NotU8,\n            I: IntoIterator<Item = V>,\n        {\n            self.0.eq_any(v)\n        }\n\n        bind_subquery_func!(pub in_subquery);\n        bind_subquery_func!(pub not_in_subquery);\n    }\n};}\n\nimpl IntoOption<String> for Cow<'_, str> {\n    fn into_option(self) -> Option<String> {\n        Some(self.into())\n    }\n}\nimpl IntoOption<String> for &'_ str {\n    fn into_option(self) -> Option<String> {\n        Some(self.into())\n    }\n}\nimpl IntoOption<String> for String {\n    fn into_option(self) -> Option<String> {\n        Some(self)\n    }\n}\nimpl IntoOption<String> for Option<&'_ str> {\n    fn into_option(self) -> Option<String> {\n        self.map(Into::into)\n    }\n}\nimpl IntoOption<String> for Option<Cow<'_, str>> {\n    fn into_option(self) -> Option<String> {\n        self.map(Into::into)\n    }\n}\nimpl IntoOption<String> for Option<String> {\n    fn into_option(self) -> Option<String> {\n        self\n    }\n}\n\nimpl_string_column!(StringColumn, Into<String>);\nimpl_string_column!(StringColumnNullable, IntoOption<String>);\n\nimpl<E: EntityTrait> BytesColumn<E> {\n    boilerplate!(pub);\n\n    bind_oper!(pub eq, eq, trait Into<Vec<u8>>);\n    bind_oper!(pub ne, ne, trait Into<Vec<u8>>);\n\n    bind_oper_0!(pub count, count);\n    bind_oper_0!(pub is_null, is_null);\n    bind_oper_0!(pub is_not_null, is_not_null);\n\n    bind_oper!(pub if_null, if_null, trait Into<Vec<u8>>);\n\n    bind_subquery_func!(pub in_subquery);\n    bind_subquery_func!(pub not_in_subquery);\n}\n"
  },
  {
    "path": "src/entity/column.rs",
    "content": "use crate::{\n    ColumnDef, ColumnType, DbBackend, EntityName, Iden, IdenStatic, IntoSimpleExpr, Iterable,\n};\nuse sea_query::{\n    BinOper, DynIden, Expr, ExprTrait, IntoIden, IntoLikeExpr, SeaRc, SelectStatement, Value,\n};\nuse std::{borrow::Cow, str::FromStr};\n\nmod types;\npub use types::*;\n\npub(crate) mod macros {\n    macro_rules! bind_oper {\n        ($vis:vis $op:ident, $bin_op:ident) => {\n            #[allow(missing_docs)]\n            $vis fn $op<V>(&self, v: V) -> Expr\n            where\n                V: Into<Value>,\n            {\n                let expr = self.save_as(Expr::val(v));\n                Expr::col(self.as_column_ref()).binary(BinOper::$bin_op, expr)\n            }\n        };\n    }\n\n    macro_rules! bind_func_no_params {\n        ($vis:vis $func:ident) => {\n            /// See also SeaQuery's method with same name.\n            $vis fn $func(&self) -> Expr {\n                Expr::col(self.as_column_ref()).$func()\n            }\n        };\n    }\n\n    macro_rules! bind_vec_func {\n        ($vis:vis $func:ident) => {\n            #[allow(missing_docs)]\n            #[allow(clippy::wrong_self_convention)]\n            $vis fn $func<V, I>(&self, v: I) -> Expr\n            where\n                V: Into<Value>,\n                I: IntoIterator<Item = V>,\n            {\n                let v_with_enum_cast = v.into_iter().map(|v| self.save_as(Expr::val(v)));\n                Expr::col(self.as_column_ref()).$func(v_with_enum_cast)\n            }\n        };\n    }\n\n    macro_rules! bind_subquery_func {\n        ($vis:vis $func:ident) => {\n            #[allow(clippy::wrong_self_convention)]\n            #[allow(missing_docs)]\n            $vis fn $func(&self, s: SelectStatement) -> Expr {\n                Expr::col(self.as_column_ref()).$func(s)\n            }\n        };\n    }\n\n    macro_rules! bind_array_oper {\n        ($vis:vis $op:ident, $oper:ident) => {\n            #[cfg(feature = \"postgres-array\")]\n            /// Array operator. Postgres only.\n            $vis fn $op<V, I>(&self, v: I) -> Expr\n            where\n                V: Into<Value> + sea_query::ValueType + sea_query::postgres_array::NotU8,\n                I: IntoIterator<Item = V>,\n            {\n                use sea_query::extension::postgres::PgBinOper;\n\n                let vec: Vec<_> = v.into_iter().collect();\n                Expr::col(self.as_column_ref()).binary(PgBinOper::$oper, self.save_as(Expr::val(vec)))\n            }\n        };\n    }\n\n    pub(crate) use bind_array_oper;\n    pub(crate) use bind_func_no_params;\n    pub(crate) use bind_oper;\n    pub(crate) use bind_subquery_func;\n    pub(crate) use bind_vec_func;\n}\n\nuse macros::*;\n\n/// API for working with a `Column`. Mostly a wrapper of the identically named methods in [`sea_query::Expr`]\npub trait ColumnTrait: IdenStatic + Iterable + FromStr {\n    #[allow(missing_docs)]\n    type EntityName: EntityName;\n\n    /// Get the column definition with SQL attributes\n    fn def(&self) -> ColumnDef;\n\n    /// Get the enum type name if this is a enum column\n    fn enum_type_name(&self) -> Option<&'static str> {\n        None\n    }\n\n    /// Get the name of the entity the column belongs to\n    fn entity_name(&self) -> DynIden {\n        SeaRc::new(Self::EntityName::default())\n    }\n\n    /// Get the table.column reference\n    fn as_column_ref(&self) -> (DynIden, DynIden) {\n        (self.entity_name(), SeaRc::new(*self))\n    }\n\n    /// Perform equality against a Value. `None` will be converted to `IS NULL`.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .filter(fruit::COLUMN.cake_id.eq(2))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`cake_id` = 2\"\n    /// );\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .filter(fruit::COLUMN.cake_id.eq(Option::<i32>::None))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`cake_id` IS NULL\"\n    /// );\n    /// ```\n    fn eq<V>(&self, v: V) -> Expr\n    where\n        V: Into<Value>,\n    {\n        let v = v.into();\n        if v == v.as_null() {\n            Expr::col(self.as_column_ref()).is_null()\n        } else {\n            let expr = self.save_as(Expr::val(v));\n            Expr::col(self.as_column_ref()).eq(expr)\n        }\n    }\n\n    /// Perform inequality against a Value. `None` will be converted to `IS NOT NULL`.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .filter(fruit::COLUMN.cake_id.ne(2))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`cake_id` <> 2\"\n    /// );\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .filter(fruit::COLUMN.cake_id.ne(Option::<i32>::None))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`cake_id` IS NOT NULL\"\n    /// );\n    /// ```\n    fn ne<V>(&self, v: V) -> Expr\n    where\n        V: Into<Value>,\n    {\n        let v = v.into();\n        if v == v.as_null() {\n            Expr::col(self.as_column_ref()).is_not_null()\n        } else {\n            let expr = self.save_as(Expr::val(v));\n            Expr::col(self.as_column_ref()).ne(expr)\n        }\n    }\n\n    bind_oper!(gt, GreaterThan);\n    bind_oper!(gte, GreaterThanOrEqual);\n    bind_oper!(lt, SmallerThan);\n    bind_oper!(lte, SmallerThanOrEqual);\n\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.between(2, 3))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` BETWEEN 2 AND 3\"\n    /// );\n    /// ```\n    fn between<V>(&self, a: V, b: V) -> Expr\n    where\n        V: Into<Value>,\n    {\n        Expr::col(self.as_column_ref()).between(a, b)\n    }\n\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.not_between(2, 3))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` NOT BETWEEN 2 AND 3\"\n    /// );\n    /// ```\n    fn not_between<V>(&self, a: V, b: V) -> Expr\n    where\n        V: Into<Value>,\n    {\n        Expr::col(self.as_column_ref()).not_between(a, b)\n    }\n\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.like(\"cheese\"))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE 'cheese'\"\n    /// );\n    /// ```\n    fn like<T>(&self, s: T) -> Expr\n    where\n        T: IntoLikeExpr,\n    {\n        Expr::col(self.as_column_ref()).like(s)\n    }\n\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.not_like(\"cheese\"))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` NOT LIKE 'cheese'\"\n    /// );\n    /// ```\n    fn not_like<T>(&self, s: T) -> Expr\n    where\n        T: IntoLikeExpr,\n    {\n        Expr::col(self.as_column_ref()).not_like(s)\n    }\n\n    /// Postgres Only.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.ilike(\"cheese\"))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"name\" ILIKE 'cheese'\"#\n    /// );\n    /// ```\n    fn ilike<T>(&self, s: T) -> Expr\n    where\n        T: IntoLikeExpr,\n    {\n        use sea_query::extension::postgres::PgExpr;\n\n        Expr::col(self.as_column_ref()).ilike(s)\n    }\n\n    /// Postgres Only.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.not_ilike(\"cheese\"))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"name\" NOT ILIKE 'cheese'\"#\n    /// );\n    /// ```\n    fn not_ilike<T>(&self, s: T) -> Expr\n    where\n        T: IntoLikeExpr,\n    {\n        use sea_query::extension::postgres::PgExpr;\n\n        Expr::col(self.as_column_ref()).not_ilike(s)\n    }\n\n    /// This is a simplified shorthand for a more general `like` method.\n    /// Use `like` if you need something more complex, like specifying an escape character.\n    ///\n    /// ## Examples\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.starts_with(\"cheese\"))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE 'cheese%'\"\n    /// );\n    /// ```\n    fn starts_with<T>(&self, s: T) -> Expr\n    where\n        T: Into<String>,\n    {\n        let pattern = format!(\"{}%\", s.into());\n        Expr::col(self.as_column_ref()).like(pattern)\n    }\n\n    /// This is a simplified shorthand for a more general `like` method.\n    /// Use `like` if you need something more complex, like specifying an escape character.\n    ///\n    /// ## Examples\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.ends_with(\"cheese\"))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE '%cheese'\"\n    /// );\n    /// ```\n    fn ends_with<T>(&self, s: T) -> Expr\n    where\n        T: Into<String>,\n    {\n        let pattern = format!(\"%{}\", s.into());\n        Expr::col(self.as_column_ref()).like(pattern)\n    }\n\n    /// This is a simplified shorthand for a more general `like` method.\n    /// Use `like` if you need something more complex, like specifying an escape character.\n    ///\n    /// ## Examples\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.contains(\"cheese\"))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE '%cheese%'\"\n    /// );\n    /// ```\n    fn contains<T>(&self, s: T) -> Expr\n    where\n        T: Into<String>,\n    {\n        let pattern = format!(\"%{}%\", s.into());\n        Expr::col(self.as_column_ref()).like(pattern)\n    }\n\n    bind_func_no_params!(max);\n    bind_func_no_params!(min);\n    bind_func_no_params!(sum);\n    bind_func_no_params!(avg);\n    bind_func_no_params!(count);\n    bind_func_no_params!(is_null);\n    bind_func_no_params!(is_not_null);\n\n    /// Provide fallback value if the column is null (null coalescing)\n    fn if_null<V>(&self, v: V) -> Expr\n    where\n        V: Into<Value>,\n    {\n        Expr::col(self.as_column_ref()).if_null(v)\n    }\n\n    bind_vec_func!(is_in);\n    bind_vec_func!(is_not_in);\n\n    /// Postgres only.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// // Compare with MySQL\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.is_in(std::iter::empty::<i32>()))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE 1 = 2\"\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.is_in(vec![4, 5]))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` IN (4, 5)\"\n    /// );\n    /// // Postgres Array\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.eq_any(std::iter::empty::<i32>()))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE 1 = 2\"#\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.eq_any(vec![4, 5]))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = ANY(ARRAY [4,5])\"#\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Name.eq_any(&[\"Apple\".to_owned(), \"Chocolate\".to_owned()]))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"name\" = ANY(ARRAY ['Apple','Chocolate'])\"#\n    /// );\n    /// ```\n    #[cfg(feature = \"postgres-array\")]\n    fn eq_any<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        use sea_query::extension::postgres::PgFunc;\n\n        let values: Vec<Value> = v.into_iter().map(|v| v.into()).collect();\n\n        if let Some(first) = values.first() {\n            Expr::col(self.as_column_ref()).eq(PgFunc::any(Value::Array(\n                first.array_type(),\n                Some(Box::new(values)),\n            )))\n        } else {\n            Expr::col(self.as_column_ref()).is_in(std::iter::empty::<V>())\n        }\n    }\n\n    /// Postgres only. Opposite of `eq_any` (equivalent to `is_not_in`).\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.ne_all(std::iter::empty::<i32>()))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE 1 = 1\"#\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.ne_all(vec![4, 5]))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" <> ALL(ARRAY [4,5])\"#\n    /// );\n    /// ```\n    #[cfg(feature = \"postgres-array\")]\n    fn ne_all<V, I>(&self, v: I) -> Expr\n    where\n        V: Into<Value> + sea_query::postgres_array::NotU8,\n        I: IntoIterator<Item = V>,\n    {\n        use sea_query::extension::postgres::PgFunc;\n\n        let values: Vec<Value> = v.into_iter().map(|v| v.into()).collect();\n\n        if let Some(first) = values.first() {\n            Expr::col(self.as_column_ref()).ne(PgFunc::all(Value::Array(\n                first.array_type(),\n                Some(Box::new(values)),\n            )))\n        } else {\n            Expr::col(self.as_column_ref()).is_not_in(std::iter::empty::<V>())\n        }\n    }\n\n    bind_subquery_func!(in_subquery);\n    bind_subquery_func!(not_in_subquery);\n\n    bind_array_oper!(array_contains, Contains);\n    bind_array_oper!(array_contained, Contained);\n    bind_array_oper!(array_overlap, Overlap);\n\n    /// Construct a [`Expr::Column`] wrapped in [`Expr`].\n    fn into_expr(self) -> Expr {\n        self.into_simple_expr()\n    }\n\n    /// Construct a returning [`Expr`].\n    #[allow(clippy::match_single_binding)]\n    fn into_returning_expr(self, db_backend: DbBackend) -> Expr {\n        match db_backend {\n            _ => Expr::col(self),\n        }\n    }\n\n    /// Cast column expression used in select statement.\n    /// It only cast database enum as text if it's an enum column.\n    fn select_as(&self, expr: Expr) -> Expr {\n        self.select_enum_as(expr)\n    }\n\n    /// Cast enum column as text; do nothing if `self` is not an enum.\n    fn select_enum_as(&self, expr: Expr) -> Expr {\n        cast_enum_as(expr, &self.def(), select_enum_as)\n    }\n\n    /// Cast value of a column into the correct type for database storage.\n    /// By default, it only cast text as enum type if it's an enum column.\n    fn save_as(&self, val: Expr) -> Expr {\n        self.save_enum_as(val)\n    }\n\n    /// Cast value of an enum column as enum type; do nothing if `self` is not an enum.\n    fn save_enum_as(&self, val: Expr) -> Expr {\n        cast_enum_as(val, &self.def(), save_enum_as)\n    }\n\n    /// Get the JSON key for deserialization.\n    #[cfg(feature = \"with-json\")]\n    fn json_key(&self) -> &'static str {\n        self.as_str()\n    }\n}\n\n/// SeaORM's utility methods that act on [ColumnType]\npub trait ColumnTypeTrait {\n    /// Instantiate a new [ColumnDef]\n    fn def(self) -> ColumnDef;\n\n    /// Get the name of the enum if this is a enum column\n    fn get_enum_name(&self) -> Option<&DynIden>;\n}\n\nimpl ColumnTypeTrait for ColumnType {\n    fn def(self) -> ColumnDef {\n        ColumnDef {\n            col_type: self,\n            null: false,\n            unique: false,\n            indexed: false,\n            default: None,\n            comment: None,\n            unique_key: None,\n            renamed_from: None,\n            extra: None,\n            seaography: Default::default(),\n        }\n    }\n\n    fn get_enum_name(&self) -> Option<&DynIden> {\n        enum_name(self)\n    }\n}\n\nimpl ColumnTypeTrait for ColumnDef {\n    fn def(self) -> ColumnDef {\n        self\n    }\n\n    fn get_enum_name(&self) -> Option<&DynIden> {\n        enum_name(&self.col_type)\n    }\n}\n\nfn enum_name(col_type: &ColumnType) -> Option<&DynIden> {\n    match col_type {\n        ColumnType::Enum { name, .. } => Some(name),\n        ColumnType::Array(col_type) => enum_name(col_type),\n        _ => None,\n    }\n}\n\nstruct Text;\nstruct TextArray;\n\nimpl Iden for Text {\n    fn quoted(&self) -> Cow<'static, str> {\n        Cow::Borrowed(\"text\")\n    }\n\n    fn unquoted(&self) -> &str {\n        match self.quoted() {\n            Cow::Borrowed(s) => s,\n            _ => unreachable!(),\n        }\n    }\n}\n\nimpl Iden for TextArray {\n    fn quoted(&self) -> Cow<'static, str> {\n        // This is Postgres only and it has a special handling for quoting this\n        Cow::Borrowed(\"text[]\")\n    }\n\n    fn unquoted(&self) -> &str {\n        match self.quoted() {\n            Cow::Borrowed(s) => s,\n            _ => unreachable!(),\n        }\n    }\n}\n\npub(crate) fn select_enum_as(col: Expr, _: DynIden, col_type: &ColumnType) -> Expr {\n    let type_name = match col_type {\n        ColumnType::Array(_) => TextArray.into_iden(),\n        _ => Text.into_iden(),\n    };\n    col.as_enum(type_name)\n}\n\npub(crate) fn save_enum_as(col: Expr, enum_name: DynIden, col_type: &ColumnType) -> Expr {\n    let type_name = match col_type {\n        ColumnType::Array(_) => format!(\"{enum_name}[]\").into_iden(),\n        _ => enum_name,\n    };\n    col.as_enum(type_name)\n}\n\npub(crate) fn cast_enum_as<F>(expr: Expr, col_def: &ColumnDef, f: F) -> Expr\nwhere\n    F: Fn(Expr, DynIden, &ColumnType) -> Expr,\n{\n    let col_type = col_def.get_column_type();\n\n    match col_type {\n        #[cfg(all(feature = \"with-json\", feature = \"postgres-array\"))]\n        ColumnType::Json | ColumnType::JsonBinary => {\n            use sea_query::ArrayType;\n            use serde_json::Value as Json;\n\n            match expr {\n                Expr::Value(Value::Array(ArrayType::Json, Some(json_vec))) => {\n                    // flatten Array(Vec<Json>) into Json\n                    let json_vec: Vec<Json> = json_vec\n                        .into_iter()\n                        .filter_map(|val| match val {\n                            Value::Json(Some(json)) => Some(*json),\n                            _ => None,\n                        })\n                        .collect();\n                    Expr::Value(Value::Json(Some(Box::new(json_vec.into()))))\n                }\n                Expr::Value(Value::Array(ArrayType::Json, None)) => Expr::Value(Value::Json(None)),\n                _ => expr,\n            }\n        }\n        _ => match col_type.get_enum_name() {\n            Some(enum_name) => f(expr, enum_name.clone(), col_type),\n            None => expr,\n        },\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        ColumnTrait, Condition, DbBackend, EntityTrait, QueryFilter, QueryTrait, tests_cfg::*,\n    };\n    use sea_query::Query;\n\n    #[test]\n    fn test_in_subquery_1() {\n        assert_eq!(\n            cake::Entity::find()\n                .filter(\n                    Condition::any().add(\n                        cake::Column::Id.in_subquery(\n                            Query::select()\n                                .expr(cake::Column::Id.max())\n                                .from(cake::Entity)\n                                .to_owned()\n                        )\n                    )\n                )\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"WHERE `cake`.`id` IN (SELECT MAX(`cake`.`id`) FROM `cake`)\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn test_in_subquery_2() {\n        assert_eq!(\n            cake::Entity::find()\n                .filter(\n                    Condition::any().add(\n                        cake::Column::Id.in_subquery(\n                            Query::select()\n                                .column(cake_filling::Column::CakeId)\n                                .from(cake_filling::Entity)\n                                .to_owned()\n                        )\n                    )\n                )\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"WHERE `cake`.`id` IN (SELECT `cake_id` FROM `cake_filling`)\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn select_as_1() {\n        use crate::{ActiveModelTrait, ActiveValue, Update};\n\n        mod hello_expanded {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n            use crate::sea_query::{Expr, ExprTrait};\n\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n\n            impl EntityName for Entity {\n                fn table_name(&self) -> &'static str {\n                    \"hello\"\n                }\n            }\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n            pub struct Model {\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            pub enum Column {\n                Id,\n                One1,\n                Two,\n                Three3,\n            }\n\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        Column::Id => ColumnType::Integer.def(),\n                        Column::One1 => ColumnType::Integer.def(),\n                        Column::Two => ColumnType::Integer.def(),\n                        Column::Three3 => ColumnType::Integer.def(),\n                    }\n                }\n\n                fn select_as(&self, expr: Expr) -> Expr {\n                    match self {\n                        Self::Two => expr.cast_as(\"integer\"),\n                        _ => self.select_enum_as(expr),\n                    }\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                Id,\n            }\n\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = i32;\n\n                fn auto_increment() -> bool {\n                    true\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        #[allow(clippy::enum_variant_names)]\n        mod hello_compact {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                #[sea_orm(select_as = \"integer\")]\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        fn assert_it<E, A>(active_model: A)\n        where\n            E: EntityTrait,\n            A: ActiveModelTrait<Entity = E>,\n        {\n            assert_eq!(\n                E::find().build(DbBackend::Postgres).to_string(),\n                r#\"SELECT \"hello\".\"id\", \"hello\".\"one1\", CAST(\"hello\".\"two\" AS integer), \"hello\".\"three3\" FROM \"hello\"\"#,\n            );\n            assert_eq!(\n                Update::one(active_model)\n                    .validate()\n                    .unwrap()\n                    .build(DbBackend::Postgres)\n                    .to_string(),\n                r#\"UPDATE \"hello\" SET \"one1\" = 1, \"two\" = 2, \"three3\" = 3 WHERE \"hello\".\"id\" = 1\"#,\n            );\n        }\n\n        assert_it(hello_expanded::ActiveModel {\n            id: ActiveValue::set(1),\n            one: ActiveValue::set(1),\n            two: ActiveValue::set(2),\n            three: ActiveValue::set(3),\n        });\n        assert_it(hello_compact::ActiveModel {\n            id: ActiveValue::set(1),\n            one: ActiveValue::set(1),\n            two: ActiveValue::set(2),\n            three: ActiveValue::set(3),\n        });\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn save_as_1() {\n        use crate::{ActiveModelTrait, ActiveValue, Update};\n\n        mod hello_expanded {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n            use crate::sea_query::{Expr, ExprTrait};\n\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n\n            impl EntityName for Entity {\n                fn table_name(&self) -> &'static str {\n                    \"hello\"\n                }\n            }\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n            pub struct Model {\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            pub enum Column {\n                Id,\n                One1,\n                Two,\n                Three3,\n            }\n\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        Column::Id => ColumnType::Integer.def(),\n                        Column::One1 => ColumnType::Integer.def(),\n                        Column::Two => ColumnType::Integer.def(),\n                        Column::Three3 => ColumnType::Integer.def(),\n                    }\n                }\n\n                fn save_as(&self, val: Expr) -> Expr {\n                    match self {\n                        Self::Two => val.cast_as(\"text\"),\n                        _ => self.save_enum_as(val),\n                    }\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                Id,\n            }\n\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = i32;\n\n                fn auto_increment() -> bool {\n                    true\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        #[allow(clippy::enum_variant_names)]\n        mod hello_compact {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                #[sea_orm(save_as = \"text\")]\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        fn assert_it<E, A>(active_model: A)\n        where\n            E: EntityTrait,\n            A: ActiveModelTrait<Entity = E>,\n        {\n            assert_eq!(\n                E::find().build(DbBackend::Postgres).to_string(),\n                r#\"SELECT \"hello\".\"id\", \"hello\".\"one1\", \"hello\".\"two\", \"hello\".\"three3\" FROM \"hello\"\"#,\n            );\n            assert_eq!(\n                Update::one(active_model)\n                    .validate()\n                    .unwrap()\n                    .build(DbBackend::Postgres)\n                    .to_string(),\n                r#\"UPDATE \"hello\" SET \"one1\" = 1, \"two\" = CAST(2 AS text), \"three3\" = 3 WHERE \"hello\".\"id\" = 1\"#,\n            );\n        }\n\n        assert_it(hello_expanded::ActiveModel {\n            id: ActiveValue::set(1),\n            one: ActiveValue::set(1),\n            two: ActiveValue::set(2),\n            three: ActiveValue::set(3),\n        });\n        assert_it(hello_compact::ActiveModel {\n            id: ActiveValue::set(1),\n            one: ActiveValue::set(1),\n            two: ActiveValue::set(2),\n            three: ActiveValue::set(3),\n        });\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn select_as_and_value_1() {\n        use crate::{ActiveModelTrait, ActiveValue, Update};\n\n        mod hello_expanded {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n            use crate::sea_query::{Expr, ExprTrait};\n\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n\n            impl EntityName for Entity {\n                fn table_name(&self) -> &'static str {\n                    \"hello\"\n                }\n            }\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n            pub struct Model {\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            pub enum Column {\n                Id,\n                One1,\n                Two,\n                Three3,\n            }\n\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        Column::Id => ColumnType::Integer.def(),\n                        Column::One1 => ColumnType::Integer.def(),\n                        Column::Two => ColumnType::Integer.def(),\n                        Column::Three3 => ColumnType::Integer.def(),\n                    }\n                }\n\n                fn select_as(&self, expr: Expr) -> Expr {\n                    match self {\n                        Self::Two => expr.cast_as(\"integer\"),\n                        _ => self.select_enum_as(expr),\n                    }\n                }\n\n                fn save_as(&self, val: Expr) -> Expr {\n                    match self {\n                        Self::Two => val.cast_as(\"text\"),\n                        _ => self.save_enum_as(val),\n                    }\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                Id,\n            }\n\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = i32;\n\n                fn auto_increment() -> bool {\n                    true\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        #[allow(clippy::enum_variant_names)]\n        mod hello_compact {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                #[sea_orm(select_as = \"integer\", save_as = \"text\")]\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        fn assert_it<E, A>(active_model: A)\n        where\n            E: EntityTrait,\n            A: ActiveModelTrait<Entity = E>,\n        {\n            assert_eq!(\n                E::find().build(DbBackend::Postgres).to_string(),\n                r#\"SELECT \"hello\".\"id\", \"hello\".\"one1\", CAST(\"hello\".\"two\" AS integer), \"hello\".\"three3\" FROM \"hello\"\"#,\n            );\n            assert_eq!(\n                Update::one(active_model)\n                    .validate()\n                    .unwrap()\n                    .build(DbBackend::Postgres)\n                    .to_string(),\n                r#\"UPDATE \"hello\" SET \"one1\" = 1, \"two\" = CAST(2 AS text), \"three3\" = 3 WHERE \"hello\".\"id\" = 1\"#,\n            );\n        }\n\n        assert_it(hello_expanded::ActiveModel {\n            id: ActiveValue::set(1),\n            one: ActiveValue::set(1),\n            two: ActiveValue::set(2),\n            three: ActiveValue::set(3),\n        });\n        assert_it(hello_compact::ActiveModel {\n            id: ActiveValue::set(1),\n            one: ActiveValue::set(1),\n            two: ActiveValue::set(2),\n            three: ActiveValue::set(3),\n        });\n    }\n}\n"
  },
  {
    "path": "src/entity/column_def.rs",
    "content": "use sea_query::{SimpleExpr, Value};\n\n// The original `sea_orm::ColumnType` enum was dropped since 0.11.0\n// It was replaced by `sea_query::ColumnType`, we reexport it here to keep the `ColumnType` symbol\npub use sea_query::ColumnType;\n\n/// Defines a Column for an Entity\n#[derive(Debug, Clone, PartialEq)]\npub struct ColumnDef {\n    pub(crate) col_type: ColumnType,\n    pub(crate) null: bool,\n    pub(crate) unique: bool,\n    pub(crate) indexed: bool,\n    pub(crate) default: Option<SimpleExpr>,\n    pub(crate) comment: Option<String>,\n    pub(crate) unique_key: Option<String>,\n    pub(crate) renamed_from: Option<String>,\n    pub(crate) extra: Option<String>,\n    pub(crate) seaography: SeaographyColumnAttr,\n}\n\n/// Seaography specific attributes\n#[non_exhaustive]\n#[derive(Debug, Default, Clone, PartialEq)]\npub struct SeaographyColumnAttr {\n    /// Ignore this column in seaography\n    pub ignore: bool,\n}\n\nimpl ColumnDef {\n    /// Marks the column as `UNIQUE`\n    pub fn unique(mut self) -> Self {\n        self.unique = true;\n        self\n    }\n\n    /// Set Seaography ignore\n    pub fn seaography_ignore(mut self) -> Self {\n        self.seaography.ignore = true;\n        self\n    }\n\n    /// This column belongs to a unique key\n    pub fn unique_key(mut self, key: &str) -> Self {\n        self.unique_key = Some(key.into());\n        self\n    }\n\n    /// This column is renamed from a previous name\n    pub fn renamed_from(mut self, col: &str) -> Self {\n        self.renamed_from = Some(col.into());\n        self\n    }\n\n    /// Set column comment\n    pub fn comment(mut self, v: &str) -> Self {\n        self.comment = Some(v.into());\n        self\n    }\n\n    /// Mark the column as nullable\n    pub fn null(self) -> Self {\n        self.nullable()\n    }\n\n    /// Mark the column as nullable\n    pub fn nullable(mut self) -> Self {\n        self.null = true;\n        self\n    }\n\n    /// Set the `indexed` field  to `true`\n    pub fn indexed(mut self) -> Self {\n        self.indexed = true;\n        self\n    }\n\n    /// Set the default value\n    pub fn default_value<T>(mut self, value: T) -> Self\n    where\n        T: Into<Value>,\n    {\n        self.default = Some(value.into().into());\n        self\n    }\n\n    /// Set the default value or expression of a column\n    pub fn default<T>(mut self, default: T) -> Self\n    where\n        T: Into<SimpleExpr>,\n    {\n        self.default = Some(default.into());\n        self\n    }\n\n    /// Set the extra SQL string for the column (e.g. \"COLLATE NOCASE\")\n    pub fn extra(mut self, value: &str) -> Self {\n        self.extra = Some(value.into());\n        self\n    }\n\n    /// Get [ColumnType] as reference\n    pub fn get_column_type(&self) -> &ColumnType {\n        &self.col_type\n    }\n\n    /// Get [Option<SimpleExpr>] as reference\n    pub fn get_column_default(&self) -> Option<&SimpleExpr> {\n        self.default.as_ref()\n    }\n\n    /// Returns true if the column is nullable\n    pub fn is_null(&self) -> bool {\n        self.null\n    }\n\n    /// Returns true if the column is unique\n    pub fn is_unique(&self) -> bool {\n        self.unique\n    }\n\n    /// Get Seaography attribute\n    pub fn seaography(&self) -> &SeaographyColumnAttr {\n        &self.seaography\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::*;\n\n    #[test]\n    fn test_col_from_str() {\n        use crate::IdenStatic;\n        use std::str::FromStr;\n\n        assert!(matches!(\n            fruit::Column::from_str(\"id\"),\n            Ok(fruit::Column::Id)\n        ));\n        assert!(matches!(\n            fruit::Column::from_str(\"name\"),\n            Ok(fruit::Column::Name)\n        ));\n        assert!(matches!(\n            fruit::Column::from_str(\"cake_id\"),\n            Ok(fruit::Column::CakeId)\n        ));\n        assert!(matches!(\n            fruit::Column::from_str(\"cakeId\"),\n            Ok(fruit::Column::CakeId)\n        ));\n        assert!(matches!(\n            fruit::Column::from_str(\"CakeId\"),\n            Err(crate::ColumnFromStrErr(_))\n        ));\n        assert!(matches!(\n            fruit::Column::from_str(\"does_not_exist\"),\n            Err(crate::ColumnFromStrErr(_))\n        ));\n        assert!(matches!(fruit::Column::CakeId.as_str(), \"cake_id\"));\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn entity_model_column_1() {\n        use crate::prelude::*;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                pub one: i32,\n                #[sea_orm(unique)]\n                pub two: i8,\n                #[sea_orm(indexed)]\n                pub three: i16,\n                #[sea_orm(nullable)]\n                pub four: i32,\n                #[sea_orm(unique, indexed, nullable)]\n                pub five: i64,\n                #[sea_orm(unique)]\n                pub six: u8,\n                #[sea_orm(indexed)]\n                pub seven: u16,\n                #[sea_orm(nullable)]\n                pub eight: u32,\n                #[sea_orm(unique, indexed, nullable)]\n                pub nine: u64,\n                #[sea_orm(default_expr = \"Expr::current_timestamp()\")]\n                pub ten: DateTimeUtc,\n                #[sea_orm(default_value = 7)]\n                pub eleven: u8,\n                #[sea_orm(default_value = \"twelve_value\")]\n                pub twelve: String,\n                #[sea_orm(default_expr = \"\\\"twelve_value\\\"\")]\n                pub twelve_two: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::One.def(), ColumnType::Integer.def());\n        assert_eq!(\n            hello::Column::Two.def(),\n            ColumnType::TinyInteger.def().unique()\n        );\n        assert_eq!(\n            hello::Column::Three.def(),\n            ColumnType::SmallInteger.def().indexed()\n        );\n        assert_eq!(\n            hello::Column::Four.def(),\n            ColumnType::Integer.def().nullable()\n        );\n        assert_eq!(\n            hello::Column::Five.def(),\n            ColumnType::BigInteger.def().unique().indexed().nullable()\n        );\n        assert_eq!(\n            hello::Column::Six.def(),\n            ColumnType::TinyUnsigned.def().unique()\n        );\n        assert_eq!(\n            hello::Column::Seven.def(),\n            ColumnType::SmallUnsigned.def().indexed()\n        );\n        assert_eq!(\n            hello::Column::Eight.def(),\n            ColumnType::Unsigned.def().nullable()\n        );\n        assert_eq!(\n            hello::Column::Nine.def(),\n            ColumnType::BigUnsigned.def().unique().indexed().nullable()\n        );\n        assert_eq!(\n            hello::Column::Ten.def(),\n            ColumnType::TimestampWithTimeZone\n                .def()\n                .default(Expr::current_timestamp())\n        );\n        assert_eq!(\n            hello::Column::Eleven.def(),\n            ColumnType::TinyUnsigned.def().default(7)\n        );\n        assert_eq!(\n            hello::Column::Twelve.def(),\n            ColumnType::String(StringLen::None)\n                .def()\n                .default(\"twelve_value\")\n        );\n        assert_eq!(\n            hello::Column::TwelveTwo.def(),\n            ColumnType::String(StringLen::None)\n                .def()\n                .default(\"twelve_value\")\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_name_1() {\n        use crate::ColumnTrait;\n        use sea_query::Iden;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                #[sea_orm(column_name = \"ONE\")]\n                pub one: i32,\n                #[seaography(ignore)]\n                pub two: i32,\n                #[sea_orm(column_name = \"3\")]\n                #[seaography(ignore)]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::One.to_string().as_str(), \"ONE\");\n        assert_eq!(hello::Column::Two.to_string().as_str(), \"two\");\n        assert_eq!(hello::Column::Three.to_string().as_str(), \"3\");\n\n        assert!(!hello::Column::One.def().seaography().ignore);\n        assert!(hello::Column::Two.def().seaography().ignore);\n        assert!(hello::Column::Three.def().seaography().ignore);\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_name_2() {\n        use sea_query::Iden;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n\n            impl EntityName for Entity {\n                fn table_name(&self) -> &'static str {\n                    \"hello\"\n                }\n            }\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n            pub struct Model {\n                pub id: i32,\n                pub one: i32,\n                pub two: i32,\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            pub enum Column {\n                Id,\n                #[sea_orm(column_name = \"ONE\")]\n                One,\n                Two,\n                #[sea_orm(column_name = \"3\")]\n                Three,\n            }\n\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        Column::Id => ColumnType::Integer.def(),\n                        Column::One => ColumnType::Integer.def(),\n                        Column::Two => ColumnType::Integer.def(),\n                        Column::Three => ColumnType::Integer.def(),\n                    }\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                Id,\n            }\n\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = i32;\n\n                fn auto_increment() -> bool {\n                    true\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::One.to_string().as_str(), \"ONE\");\n        assert_eq!(hello::Column::Two.to_string().as_str(), \"two\");\n        assert_eq!(hello::Column::Three.to_string().as_str(), \"3\");\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn enum_name_1() {\n        use sea_query::Iden;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::One1.to_string().as_str(), \"one1\");\n        assert_eq!(hello::Column::Two.to_string().as_str(), \"two\");\n        assert_eq!(hello::Column::Three3.to_string().as_str(), \"three3\");\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn enum_name_2() {\n        use sea_query::Iden;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n\n            impl EntityName for Entity {\n                fn table_name(&self) -> &'static str {\n                    \"hello\"\n                }\n            }\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n            pub struct Model {\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            pub enum Column {\n                Id,\n                One1,\n                Two,\n                Three3,\n            }\n\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        Column::Id => ColumnType::Integer.def(),\n                        Column::One1 => ColumnType::Integer.def(),\n                        Column::Two => ColumnType::Integer.def(),\n                        Column::Three3 => ColumnType::Integer.def(),\n                    }\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                Id,\n            }\n\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = i32;\n\n                fn auto_increment() -> bool {\n                    true\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::One1.to_string().as_str(), \"one1\");\n        assert_eq!(hello::Column::Two.to_string().as_str(), \"two\");\n        assert_eq!(hello::Column::Three3.to_string().as_str(), \"three3\");\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_name_enum_name_1() {\n        use sea_query::Iden;\n\n        #[allow(clippy::enum_variant_names)]\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"hello\")]\n            pub struct Model {\n                #[sea_orm(primary_key, column_name = \"ID\", enum_name = \"IdentityColumn\")]\n                pub id: i32,\n                #[sea_orm(column_name = \"ONE\", enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(column_name = \"THREE\", enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::IdentityColumn.to_string().as_str(), \"ID\");\n        assert_eq!(hello::Column::One1.to_string().as_str(), \"ONE\");\n        assert_eq!(hello::Column::Two.to_string().as_str(), \"two\");\n        assert_eq!(hello::Column::Three3.to_string().as_str(), \"THREE\");\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_name_enum_name_2() {\n        use sea_query::Iden;\n\n        mod hello {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n            pub struct Entity;\n\n            impl EntityName for Entity {\n                fn table_name(&self) -> &'static str {\n                    \"hello\"\n                }\n            }\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n            pub struct Model {\n                #[sea_orm(enum_name = \"IdentityCol\")]\n                pub id: i32,\n                #[sea_orm(enum_name = \"One1\")]\n                pub one: i32,\n                pub two: i32,\n                #[sea_orm(enum_name = \"Three3\")]\n                pub three: i32,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n            pub enum Column {\n                #[sea_orm(column_name = \"ID\")]\n                IdentityCol,\n                #[sea_orm(column_name = \"ONE\")]\n                One1,\n                Two,\n                #[sea_orm(column_name = \"THREE\")]\n                Three3,\n            }\n\n            impl ColumnTrait for Column {\n                type EntityName = Entity;\n\n                fn def(&self) -> ColumnDef {\n                    match self {\n                        Column::IdentityCol => ColumnType::Integer.def(),\n                        Column::One1 => ColumnType::Integer.def(),\n                        Column::Two => ColumnType::Integer.def(),\n                        Column::Three3 => ColumnType::Integer.def(),\n                    }\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n            pub enum PrimaryKey {\n                IdentityCol,\n            }\n\n            impl PrimaryKeyTrait for PrimaryKey {\n                type ValueType = i32;\n\n                fn auto_increment() -> bool {\n                    true\n                }\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(hello::Column::IdentityCol.to_string().as_str(), \"ID\");\n        assert_eq!(hello::Column::One1.to_string().as_str(), \"ONE\");\n        assert_eq!(hello::Column::Two.to_string().as_str(), \"two\");\n        assert_eq!(hello::Column::Three3.to_string().as_str(), \"THREE\");\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_name_enum_name_3() {\n        use sea_query::Iden;\n\n        mod my_entity {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"my_entity\")]\n            pub struct Model {\n                #[sea_orm(primary_key, enum_name = \"IdentityColumn\", column_name = \"id\")]\n                pub id: i32,\n                #[sea_orm(column_name = \"type\")]\n                pub type_: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(my_entity::Column::IdentityColumn.to_string().as_str(), \"id\");\n        assert_eq!(my_entity::Column::Type.to_string().as_str(), \"type\");\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_def_unique_key() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"my_entity\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(column_name = \"my_a\", unique_key = \"my_unique\")]\n            pub a: String,\n            #[sea_orm(unique_key = \"my_unique\")]\n            pub b: String,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n\n        assert_eq!(\n            Column::A.def(),\n            ColumnType::string(None).def().unique_key(\"my_unique\")\n        );\n        assert_eq!(\n            Column::B.def(),\n            ColumnType::string(None).def().unique_key(\"my_unique\")\n        );\n    }\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn column_def_renamed_from() {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"my_entity\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(column_name = \"new_a\", renamed_from = \"old_a\")]\n            pub a: String,\n            #[sea_orm(renamed_from = \"old_b\")]\n            pub b: String,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n\n        assert_eq!(Column::A.to_string(), \"new_a\");\n        assert_eq!(Column::B.to_string(), \"b\");\n\n        assert_eq!(\n            Column::A.def(),\n            ColumnType::string(None).def().renamed_from(\"old_a\")\n        );\n        assert_eq!(\n            Column::B.def(),\n            ColumnType::string(None).def().renamed_from(\"old_b\")\n        );\n    }\n}\n"
  },
  {
    "path": "src/entity/compound/has_many.rs",
    "content": "use crate::HasManyModel;\nuse core::ops::Index;\nuse std::hash::{Hash, Hasher};\nuse std::slice;\n\nuse super::super::EntityTrait;\n\n#[derive(Debug, Default, Clone)]\npub enum HasMany<E: EntityTrait> {\n    #[default]\n    Unloaded,\n    Loaded(Vec<E::ModelEx>),\n}\n\nimpl<E> PartialEq for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq,\n{\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (HasMany::Unloaded, HasMany::Unloaded) => true,\n            (HasMany::Loaded(a), HasMany::Loaded(b)) => a == b,\n            _ => false,\n        }\n    }\n}\n\nimpl<E> Eq for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: Eq,\n{\n}\n\nimpl<E: EntityTrait> HasMany<E> {\n    /// Return true if variant is `Loaded`\n    pub fn is_loaded(&self) -> bool {\n        matches!(self, HasMany::Loaded(_))\n    }\n\n    /// Return true if variant is `Unloaded`\n    pub fn is_unloaded(&self) -> bool {\n        matches!(self, HasMany::Unloaded)\n    }\n\n    /// Return true if variant is `Unloaded` or underlying vector is empty\n    pub fn is_empty(&self) -> bool {\n        match self {\n            HasMany::Unloaded => true,\n            HasMany::Loaded(models) => models.is_empty(),\n        }\n    }\n\n    /// Like `Vec::get`\n    pub fn get(&self, index: usize) -> Option<&E::ModelEx> {\n        match self {\n            HasMany::Loaded(models) => models.get(index),\n            HasMany::Unloaded => None,\n        }\n    }\n\n    /// Length of underlying vector\n    pub fn len(&self) -> usize {\n        match self {\n            HasMany::Loaded(models) => models.len(),\n            HasMany::Unloaded => 0,\n        }\n    }\n}\n\nimpl<E> HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: From<E::ModelEx>,\n{\n    pub fn into_active_model(self) -> HasManyModel<E> {\n        match self {\n            HasMany::Loaded(models) => {\n                HasManyModel::Append(models.into_iter().map(Into::into).collect())\n            }\n            HasMany::Unloaded => HasManyModel::NotSet,\n        }\n    }\n}\n\nimpl<E: EntityTrait> From<HasMany<E>> for Option<Vec<E::ModelEx>> {\n    fn from(value: HasMany<E>) -> Self {\n        match value {\n            HasMany::Loaded(models) => Some(models),\n            HasMany::Unloaded => None,\n        }\n    }\n}\n\nimpl<E: EntityTrait> Index<usize> for HasMany<E> {\n    type Output = E::ModelEx;\n\n    fn index(&self, index: usize) -> &Self::Output {\n        match self {\n            HasMany::Unloaded => {\n                panic!(\"index out of bounds: the HasMany is Unloaded (index: {index})\")\n            }\n            HasMany::Loaded(items) => items.index(index),\n        }\n    }\n}\n\nimpl<E: EntityTrait> IntoIterator for HasMany<E> {\n    type Item = E::ModelEx;\n    type IntoIter = std::vec::IntoIter<E::ModelEx>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        match self {\n            HasMany::Loaded(models) => models.into_iter(),\n            HasMany::Unloaded => Vec::new().into_iter(),\n        }\n    }\n}\n\nimpl<E: EntityTrait> From<Vec<E::ModelEx>> for HasMany<E> {\n    fn from(value: Vec<E::ModelEx>) -> Self {\n        HasMany::Loaded(value)\n    }\n}\n\nimpl<E, const N: usize> PartialEq<[<E as EntityTrait>::Model; N]> for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq<<E as EntityTrait>::Model>,\n    <E as EntityTrait>::Model: PartialEq<E::ModelEx>,\n{\n    fn eq(&self, other: &[<E as EntityTrait>::Model; N]) -> bool {\n        match self {\n            HasMany::Loaded(models) => models.as_slice() == other.as_slice(),\n            HasMany::Unloaded => false,\n        }\n    }\n}\n\nimpl<E, const N: usize> PartialEq<HasMany<E>> for [<E as EntityTrait>::Model; N]\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq<<E as EntityTrait>::Model>,\n    <E as EntityTrait>::Model: PartialEq<E::ModelEx>,\n{\n    fn eq(&self, other: &HasMany<E>) -> bool {\n        other == self\n    }\n}\n\nimpl<E> PartialEq<[<E as EntityTrait>::Model]> for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq<<E as EntityTrait>::Model>,\n    <E as EntityTrait>::Model: PartialEq<E::ModelEx>,\n{\n    fn eq(&self, other: &[<E as EntityTrait>::Model]) -> bool {\n        match self {\n            HasMany::Loaded(models) => models.as_slice() == other,\n            HasMany::Unloaded => false,\n        }\n    }\n}\n\nimpl<E> PartialEq<HasMany<E>> for [<E as EntityTrait>::Model]\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq<<E as EntityTrait>::Model>,\n    <E as EntityTrait>::Model: PartialEq<E::ModelEx>,\n{\n    fn eq(&self, other: &HasMany<E>) -> bool {\n        other == self\n    }\n}\n\n#[derive(Debug, Clone)]\npub struct Iter<'a, E: EntityTrait> {\n    inner: Option<slice::Iter<'a, E::ModelEx>>,\n}\n\nimpl<E: EntityTrait> HasMany<E> {\n    pub fn iter(&self) -> Iter<'_, E> {\n        Iter {\n            inner: match self {\n                HasMany::Loaded(models) => Some(models.iter()),\n                HasMany::Unloaded => None,\n            },\n        }\n    }\n}\n\nimpl<'a, E: EntityTrait> Iterator for Iter<'a, E> {\n    type Item = &'a E::ModelEx;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.inner.as_mut().and_then(|iter| iter.next())\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.inner\n            .as_ref()\n            .map(|iter| iter.size_hint())\n            .unwrap_or((0, Some(0)))\n    }\n\n    fn count(self) -> usize\n    where\n        Self: Sized,\n    {\n        self.inner.map(|iter| iter.count()).unwrap_or(0)\n    }\n\n    fn last(self) -> Option<Self::Item>\n    where\n        Self: Sized,\n    {\n        self.inner.and_then(|iter| iter.last())\n    }\n}\n\nimpl<'a, E: EntityTrait> ExactSizeIterator for Iter<'a, E> {\n    fn len(&self) -> usize {\n        self.inner.as_ref().map(|iter| iter.len()).unwrap_or(0)\n    }\n}\n\nimpl<'a, E: EntityTrait> DoubleEndedIterator for Iter<'a, E> {\n    fn next_back(&mut self) -> Option<Self::Item> {\n        self.inner.as_mut().and_then(|iter| iter.next_back())\n    }\n}\n\nimpl<'a, E: EntityTrait> IntoIterator for &'a HasMany<E> {\n    type Item = &'a E::ModelEx;\n    type IntoIter = Iter<'a, E>;\n\n    fn into_iter(self) -> Self::IntoIter {\n        Iter {\n            inner: match self {\n                HasMany::Loaded(models) => Some(models.iter()),\n                HasMany::Unloaded => None,\n            },\n        }\n    }\n}\n\nimpl<E> Hash for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: Hash,\n{\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        std::mem::discriminant(self).hash(state);\n        match self {\n            HasMany::Loaded(model) => model.hash(state),\n            HasMany::Unloaded => {}\n        }\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl<E> serde::Serialize for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: serde::Serialize,\n{\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        match self {\n            HasMany::Unloaded => None,\n            HasMany::Loaded(models) => Some(models.as_slice()),\n        }\n        .serialize(serializer)\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl<'de, E> serde::Deserialize<'de> for HasMany<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: serde::Deserialize<'de>,\n{\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        match <Option<Vec<E::ModelEx>>>::deserialize(deserializer)? {\n            Some(models) => Ok(HasMany::Loaded(models)),\n            None => Ok(HasMany::Unloaded),\n        }\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use crate::compound::{HasMany, HasOne};\n    use crate::tests_cfg::{cake, filling, fruit};\n\n    #[test]\n    fn test_serde_compound() {\n        let cake = cake::ModelEx {\n            id: 1,\n            name: \"A\".into(),\n            fruit: Default::default(),\n            fillings: Default::default(),\n        };\n\n        assert_eq!(\n            filling::Model {\n                id: 2,\n                name: \"C\".into(),\n                vendor_id: None,\n                ignored_attr: 3,\n            }\n            .into_ex(),\n            filling::ModelEx {\n                id: 2,\n                name: \"C\".into(),\n                vendor_id: None,\n                ignored_attr: 3,\n                ingredients: HasMany::Unloaded,\n            }\n        );\n\n        assert_eq!(\n            serde_json::to_string(&cake).unwrap(),\n            r#\"{\"id\":1,\"name\":\"A\",\"fruit\":null,\"fillings\":null}\"#\n        );\n        assert_eq!(\n            serde_json::from_str::<cake::ModelEx>(&serde_json::to_string(&cake).unwrap()).unwrap(),\n            cake\n        );\n\n        let cake = cake::ModelEx {\n            id: 1,\n            name: \"A\".into(),\n            fruit: Default::default(),\n            fillings: HasMany::Loaded(vec![]),\n        };\n\n        assert_eq!(\n            serde_json::to_string(&cake).unwrap(),\n            r#\"{\"id\":1,\"name\":\"A\",\"fruit\":null,\"fillings\":[]}\"#\n        );\n        assert_eq!(\n            serde_json::from_str::<cake::ModelEx>(&serde_json::to_string(&cake).unwrap()).unwrap(),\n            cake\n        );\n\n        let mut cake = cake::ModelEx {\n            id: 1,\n            name: \"A\".into(),\n            fruit: HasOne::Loaded(\n                fruit::ModelEx {\n                    id: 2,\n                    name: \"B\".into(),\n                    cake_id: None,\n                }\n                .into(),\n            ),\n            fillings: HasMany::Unloaded,\n        };\n\n        assert_eq!(\n            serde_json::to_string(&cake).unwrap(),\n            r#\"{\"id\":1,\"name\":\"A\",\"fruit\":{\"id\":2,\"name\":\"B\",\"cake_id\":null},\"fillings\":null}\"#\n        );\n        // fruit has skip_deserializing on id\n        cake.fruit.as_mut().unwrap().id = 0;\n        assert_eq!(\n            serde_json::from_str::<cake::ModelEx>(&serde_json::to_string(&cake).unwrap()).unwrap(),\n            cake\n        );\n\n        let cake = cake::ModelEx {\n            id: 1,\n            name: \"A\".into(),\n            fruit: HasOne::Loaded(\n                fruit::ModelEx {\n                    id: 0,\n                    name: \"B\".into(),\n                    cake_id: None,\n                }\n                .into(),\n            ),\n            fillings: HasMany::Loaded(vec![\n                filling::Model {\n                    id: 2,\n                    name: \"C\".into(),\n                    vendor_id: None,\n                    ignored_attr: 3,\n                }\n                .into_ex(),\n            ]),\n        };\n\n        assert_eq!(\n            serde_json::to_string(&cake).unwrap(),\n            r#\"{\"id\":1,\"name\":\"A\",\"fruit\":{\"id\":0,\"name\":\"B\",\"cake_id\":null},\"fillings\":[{\"id\":2,\"name\":\"C\",\"vendor_id\":null,\"ignored_attr\":3,\"ingredients\":null}]}\"#\n        );\n        assert_eq!(\n            serde_json::from_str::<cake::ModelEx>(&serde_json::to_string(&cake).unwrap()).unwrap(),\n            cake\n        );\n    }\n}\n"
  },
  {
    "path": "src/entity/compound/has_one.rs",
    "content": "use crate::{EntityTrait, HasOneModel};\nuse std::hash::{Hash, Hasher};\n\n#[derive(Debug, Default, Clone)]\npub enum HasOne<E: EntityTrait> {\n    #[default]\n    Unloaded,\n    NotFound,\n    Loaded(Box<E::ModelEx>),\n}\n\nimpl<E: EntityTrait> HasOne<E> {\n    /// Construct a `HasOne::Loaded` value\n    pub fn loaded<M: Into<E::ModelEx>>(model: M) -> Self {\n        Self::Loaded(Box::new(model.into()))\n    }\n\n    /// Return true if variant is `Unloaded`\n    pub fn is_unloaded(&self) -> bool {\n        matches!(self, HasOne::Unloaded)\n    }\n\n    /// Return true if variant is `NotFound`\n    pub fn is_not_found(&self) -> bool {\n        matches!(self, HasOne::NotFound)\n    }\n\n    /// Return true if variant is `Loaded`\n    pub fn is_loaded(&self) -> bool {\n        matches!(self, HasOne::Loaded(_))\n    }\n\n    /// True if variant is `Unloaded` or `NotFound`\n    pub fn is_none(&self) -> bool {\n        matches!(self, HasOne::Unloaded | HasOne::NotFound)\n    }\n\n    /// Get a reference, if loaded\n    pub fn as_ref(&self) -> Option<&E::ModelEx> {\n        match self {\n            HasOne::Loaded(model) => Some(model.as_ref()),\n            HasOne::Unloaded | HasOne::NotFound => None,\n        }\n    }\n\n    /// Get a mutable reference, if loaded\n    pub fn as_mut(&mut self) -> Option<&mut E::ModelEx> {\n        match self {\n            HasOne::Loaded(model) => Some(model),\n            HasOne::Unloaded | HasOne::NotFound => None,\n        }\n    }\n\n    /// Convert into an `Option<ModelEx>`\n    pub fn into_option(self) -> Option<E::ModelEx> {\n        match self {\n            HasOne::Loaded(model) => Some(*model),\n            HasOne::Unloaded | HasOne::NotFound => None,\n        }\n    }\n\n    /// Take ownership of the contained Model, leaving `Unloaded` in place.\n    pub fn take(&mut self) -> Option<E::ModelEx> {\n        std::mem::take(self).into_option()\n    }\n\n    /// # Panics\n    ///\n    /// Panics if called on `Unloaded` or `NotFound` values.\n    pub fn unwrap(self) -> E::ModelEx {\n        match self {\n            HasOne::Loaded(model) => *model,\n            HasOne::Unloaded => panic!(\"called `HasOne::unwrap()` on an `Unloaded` value\"),\n            HasOne::NotFound => panic!(\"called `HasOne::unwrap()` on a `NotFound` value\"),\n        }\n    }\n}\n\nimpl<E> HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ActiveModelEx: From<E::ModelEx>,\n{\n    pub fn into_active_model(self) -> HasOneModel<E> {\n        match self {\n            HasOne::Loaded(_) => {\n                let model = self.unwrap();\n                let active_model: E::ActiveModelEx = model.into();\n                HasOneModel::Set(active_model.into())\n            }\n            HasOne::Unloaded => HasOneModel::NotSet,\n            HasOne::NotFound => HasOneModel::NotSet,\n        }\n    }\n}\n\nimpl<E> PartialEq for HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq,\n{\n    fn eq(&self, other: &Self) -> bool {\n        match (self, other) {\n            (HasOne::Unloaded, HasOne::Unloaded) => true,\n            (HasOne::NotFound, HasOne::NotFound) => true,\n            (HasOne::Loaded(a), HasOne::Loaded(b)) => a == b,\n            _ => false,\n        }\n    }\n}\n\nimpl<E> Eq for HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: Eq,\n{\n}\n\n// Option<Box<ModelEx<E>>> <-> HasOne<E> conversions and comparisons\nimpl<E: EntityTrait> From<HasOne<E>> for Option<Box<E::ModelEx>> {\n    fn from(value: HasOne<E>) -> Self {\n        match value {\n            HasOne::Loaded(model) => Some(model),\n            HasOne::Unloaded | HasOne::NotFound => None,\n        }\n    }\n}\n\nimpl<E: EntityTrait> From<Option<Box<E::ModelEx>>> for HasOne<E> {\n    fn from(value: Option<Box<E::ModelEx>>) -> Self {\n        match value {\n            Some(model) => HasOne::Loaded(model),\n            None => HasOne::NotFound,\n        }\n    }\n}\n\nimpl<E> PartialEq<Option<Box<E::ModelEx>>> for HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq,\n{\n    fn eq(&self, other: &Option<Box<E::ModelEx>>) -> bool {\n        match (self, other) {\n            (HasOne::Loaded(a), Some(b)) => a.as_ref() == b.as_ref(),\n            (HasOne::Unloaded | HasOne::NotFound, None) => true,\n            _ => false,\n        }\n    }\n}\n\nimpl<E> PartialEq<HasOne<E>> for Option<Box<E::ModelEx>>\nwhere\n    E: EntityTrait,\n    E::ModelEx: PartialEq,\n{\n    fn eq(&self, other: &HasOne<E>) -> bool {\n        other == self\n    }\n}\n\nimpl<E> Hash for HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: Hash,\n{\n    fn hash<H: Hasher>(&self, state: &mut H) {\n        std::mem::discriminant(self).hash(state);\n        match self {\n            Self::Loaded(model) => model.hash(state),\n            Self::Unloaded => {}\n            Self::NotFound => {}\n        }\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl<E> serde::Serialize for HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: serde::Serialize,\n{\n    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: serde::Serializer,\n    {\n        match self {\n            HasOne::Unloaded => None,\n            HasOne::NotFound => None,\n            HasOne::Loaded(model) => Some(model),\n        }\n        .serialize(serializer)\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl<'de, E> serde::Deserialize<'de> for HasOne<E>\nwhere\n    E: EntityTrait,\n    E::ModelEx: serde::Deserialize<'de>,\n{\n    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>\n    where\n        D: serde::Deserializer<'de>,\n    {\n        match <Option<E::ModelEx>>::deserialize(deserializer)? {\n            Some(model) => Ok(HasOne::Loaded(Box::new(model))),\n            None => Ok(HasOne::Unloaded),\n        }\n    }\n}\n"
  },
  {
    "path": "src/entity/compound.rs",
    "content": "#![allow(missing_docs)]\nuse super::{ColumnTrait, EntityTrait, PrimaryKeyToColumn, PrimaryKeyTrait};\nuse crate::{\n    ConnectionTrait, DbErr, IntoSimpleExpr, ItemsAndPagesNumber, Iterable, ModelTrait, QueryFilter,\n    QueryOrder,\n};\nuse sea_query::{IntoValueTuple, Order, TableRef};\nuse std::marker::PhantomData;\n\nmod has_many;\nmod has_one;\n\npub use has_many::{HasMany, Iter as HasManyIter};\npub use has_one::HasOne;\n\n#[async_trait::async_trait]\npub trait EntityLoaderTrait<E: EntityTrait>: QueryFilter + QueryOrder + Clone {\n    /// The return type of this loader\n    type ModelEx: ModelTrait<Entity = E>;\n\n    /// Find a model by primary key\n    fn filter_by_id<T>(mut self, values: T) -> Self\n    where\n        T: Into<<E::PrimaryKey as PrimaryKeyTrait>::ValueType>,\n    {\n        let mut keys = E::PrimaryKey::iter();\n        for v in values.into().into_value_tuple() {\n            if let Some(key) = keys.next() {\n                let col = key.into_column();\n                self.filter_mut(col.eq(v));\n            } else {\n                unreachable!(\"primary key arity mismatch\");\n            }\n        }\n        self\n    }\n\n    /// Apply order by primary key to the query statement\n    fn order_by_id_asc(self) -> Self {\n        self.order_by_id(Order::Asc)\n    }\n\n    /// Apply order by primary key to the query statement\n    fn order_by_id_desc(self) -> Self {\n        self.order_by_id(Order::Desc)\n    }\n\n    /// Apply order by primary key to the query statement\n    fn order_by_id(mut self, order: Order) -> Self {\n        for key in E::PrimaryKey::iter() {\n            let col = key.into_column();\n            <Self as QueryOrder>::query(&mut self)\n                .order_by_expr(col.into_simple_expr(), order.clone());\n        }\n        self\n    }\n\n    /// Paginate query.\n    fn paginate<'db, C: ConnectionTrait>(\n        self,\n        db: &'db C,\n        page_size: u64,\n    ) -> EntityLoaderPaginator<'db, C, E, Self> {\n        EntityLoaderPaginator {\n            loader: self,\n            page: 0,\n            page_size,\n            db,\n            phantom: PhantomData,\n        }\n    }\n\n    #[doc(hidden)]\n    async fn fetch<C: ConnectionTrait>(\n        self,\n        db: &C,\n        page: u64,\n        page_size: u64,\n    ) -> Result<Vec<Self::ModelEx>, DbErr>;\n\n    #[doc(hidden)]\n    async fn num_items<C: ConnectionTrait>(self, db: &C, page_size: u64) -> Result<u64, DbErr>;\n}\n\n#[derive(Debug)]\npub struct EntityLoaderPaginator<'db, C, E, L>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait,\n    L: EntityLoaderTrait<E>,\n{\n    pub(crate) loader: L,\n    pub(crate) page: u64,\n    pub(crate) page_size: u64,\n    pub(crate) db: &'db C,\n    pub(crate) phantom: PhantomData<E>,\n}\n\n/// Just a marker trait on EntityReverse\npub trait EntityReverse {\n    type Entity: EntityTrait;\n}\n\n/// Subject to change, not yet stable\n#[derive(Debug, Copy, Clone, PartialEq)]\npub struct EntityLoaderWithSelf<R: EntityTrait, S: EntityTrait>(pub R, pub S);\n\n/// Subject to change, not yet stable\n#[derive(Debug, Copy, Clone, PartialEq)]\npub struct EntityLoaderWithSelfRev<R: EntityTrait, S: EntityReverse>(pub R, pub S);\n\n#[derive(Debug, Clone, PartialEq)]\npub enum LoadTarget {\n    TableRef(TableRef),\n    TableRefRev(TableRef),\n    Relation(String),\n}\n\nimpl<'db, C, E, L> EntityLoaderPaginator<'db, C, E, L>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait,\n    L: EntityLoaderTrait<E>,\n{\n    /// Fetch a specific page; page index starts from zero\n    pub async fn fetch_page(&self, page: u64) -> Result<Vec<L::ModelEx>, DbErr> {\n        self.loader\n            .clone()\n            .fetch(self.db, page, self.page_size)\n            .await\n    }\n\n    /// Fetch the current page\n    pub async fn fetch(&self) -> Result<Vec<L::ModelEx>, DbErr> {\n        self.fetch_page(self.page).await\n    }\n\n    /// Get the total number of items\n    pub async fn num_items(&self) -> Result<u64, DbErr> {\n        self.loader.clone().num_items(self.db, self.page_size).await\n    }\n\n    /// Get the total number of pages\n    pub async fn num_pages(&self) -> Result<u64, DbErr> {\n        let num_items = self.num_items().await?;\n        let num_pages = self.compute_pages_number(num_items);\n        Ok(num_pages)\n    }\n\n    /// Get the total number of items and pages\n    pub async fn num_items_and_pages(&self) -> Result<ItemsAndPagesNumber, DbErr> {\n        let number_of_items = self.num_items().await?;\n        let number_of_pages = self.compute_pages_number(number_of_items);\n\n        Ok(ItemsAndPagesNumber {\n            number_of_items,\n            number_of_pages,\n        })\n    }\n\n    /// Compute the number of pages for the current page\n    fn compute_pages_number(&self, num_items: u64) -> u64 {\n        (num_items / self.page_size) + (num_items % self.page_size > 0) as u64\n    }\n\n    /// Increment the page counter\n    pub fn next(&mut self) {\n        self.page += 1;\n    }\n\n    /// Get current page number\n    pub fn cur_page(&self) -> u64 {\n        self.page\n    }\n\n    /// Fetch one page and increment the page counter\n    pub async fn fetch_and_next(&mut self) -> Result<Option<Vec<L::ModelEx>>, DbErr> {\n        let vec = self.fetch().await?;\n        self.next();\n        let opt = if !vec.is_empty() { Some(vec) } else { None };\n        Ok(opt)\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use crate::ModelTrait;\n    use crate::tests_cfg::cake;\n\n    #[test]\n    fn test_model_ex_convert() {\n        let cake = cake::Model {\n            id: 12,\n            name: \"hello\".into(),\n        };\n        let cake_ex: cake::ModelEx = cake.clone().into();\n\n        assert_eq!(cake, cake_ex);\n        assert_eq!(cake_ex, cake);\n        assert_eq!(cake.id, cake_ex.id);\n        assert_eq!(cake.name, cake_ex.name);\n\n        assert_eq!(cake_ex.get(cake::Column::Id), 12i32.into());\n        assert_eq!(cake_ex.get(cake::Column::Name), \"hello\".into());\n\n        assert_eq!(cake::Model::from(cake_ex), cake);\n    }\n}\n"
  },
  {
    "path": "src/entity/identity.rs",
    "content": "use crate::{ColumnTrait, EntityTrait, IdenStatic};\nuse sea_query::{Alias, DynIden, Iden, IntoIden, SeaRc};\nuse std::{borrow::Cow, fmt::Write};\n\n/// List of column identifier\n#[derive(Debug, Clone, PartialEq, Eq, Hash)]\npub enum Identity {\n    /// Column identifier consists of 1 column\n    Unary(DynIden),\n    /// Column identifier consists of 2 columns\n    Binary(DynIden, DynIden),\n    /// Column identifier consists of 3 columns\n    Ternary(DynIden, DynIden, DynIden),\n    /// Column identifier consists of more than 3 columns\n    Many(Vec<DynIden>),\n}\n\nimpl Identity {\n    /// Get arity for this value\n    pub fn arity(&self) -> usize {\n        match self {\n            Self::Unary(_) => 1,\n            Self::Binary(_, _) => 2,\n            Self::Ternary(_, _, _) => 3,\n            Self::Many(vec) => vec.len(),\n        }\n    }\n\n    /// Iterate components of Identity\n    pub fn iter(&self) -> BorrowedIdentityIter<'_> {\n        BorrowedIdentityIter {\n            identity: self,\n            index: 0,\n        }\n    }\n\n    /// Check if this identity contains a component column\n    pub fn contains(&self, col: &DynIden) -> bool {\n        self.iter().any(|c| c == col)\n    }\n\n    /// Check if this identity is a superset of another identity\n    pub fn fully_contains(&self, other: &Identity) -> bool {\n        for col in other.iter() {\n            if !self.contains(col) {\n                return false;\n            }\n        }\n        true\n    }\n}\n\nimpl IntoIterator for Identity {\n    type Item = DynIden;\n    type IntoIter = OwnedIdentityIter;\n\n    fn into_iter(self) -> Self::IntoIter {\n        OwnedIdentityIter {\n            identity: self,\n            index: 0,\n        }\n    }\n}\n\nimpl Iden for Identity {\n    fn quoted(&self) -> Cow<'static, str> {\n        match self {\n            Identity::Unary(iden) => iden.inner(),\n            Identity::Binary(iden1, iden2) => Cow::Owned(format!(\"{iden1}{iden2}\")),\n            Identity::Ternary(iden1, iden2, iden3) => Cow::Owned(format!(\"{iden1}{iden2}{iden3}\")),\n            Identity::Many(vec) => {\n                let mut s = String::new();\n                for iden in vec.iter() {\n                    write!(&mut s, \"{iden}\").expect(\"Infallible\");\n                }\n                Cow::Owned(s)\n            }\n        }\n    }\n\n    fn to_string(&self) -> String {\n        match self.quoted() {\n            Cow::Borrowed(s) => s.to_owned(),\n            Cow::Owned(s) => s,\n        }\n    }\n\n    fn unquoted(&self) -> &str {\n        panic!(\"Should not call this\")\n    }\n}\n\n/// Iterator for [`Identity`]\n#[derive(Debug)]\npub struct BorrowedIdentityIter<'a> {\n    identity: &'a Identity,\n    index: usize,\n}\n\n/// Iterator for [`Identity`]\n#[derive(Debug)]\npub struct OwnedIdentityIter {\n    identity: Identity,\n    index: usize,\n}\n\nimpl<'a> Iterator for BorrowedIdentityIter<'a> {\n    type Item = &'a DynIden;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let result = match self.identity {\n            Identity::Unary(iden1) => {\n                if self.index == 0 {\n                    Some(iden1)\n                } else {\n                    None\n                }\n            }\n            Identity::Binary(iden1, iden2) => match self.index {\n                0 => Some(iden1),\n                1 => Some(iden2),\n                _ => None,\n            },\n            Identity::Ternary(iden1, iden2, iden3) => match self.index {\n                0 => Some(iden1),\n                1 => Some(iden2),\n                2 => Some(iden3),\n                _ => None,\n            },\n            Identity::Many(vec) => vec.get(self.index),\n        };\n        self.index += 1;\n        result\n    }\n}\n\nimpl Iterator for OwnedIdentityIter {\n    type Item = DynIden;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        let result = match &self.identity {\n            Identity::Unary(iden1) => {\n                if self.index == 0 {\n                    Some(iden1.clone())\n                } else {\n                    None\n                }\n            }\n            Identity::Binary(iden1, iden2) => match self.index {\n                0 => Some(iden1.clone()),\n                1 => Some(iden2.clone()),\n                _ => None,\n            },\n            Identity::Ternary(iden1, iden2, iden3) => match self.index {\n                0 => Some(iden1.clone()),\n                1 => Some(iden2.clone()),\n                2 => Some(iden3.clone()),\n                _ => None,\n            },\n            Identity::Many(vec) => vec.get(self.index).cloned(),\n        };\n        self.index += 1;\n        result\n    }\n}\n\n/// Performs a conversion into an [Identity]\npub trait IntoIdentity {\n    /// Method to perform the conversion\n    fn into_identity(self) -> Identity;\n}\n\n/// Check the [Identity] of an Entity\npub trait IdentityOf<E>\nwhere\n    E: EntityTrait,\n{\n    /// Method to call to perform this check\n    fn identity_of(self) -> Identity;\n}\n\nimpl IntoIdentity for Identity {\n    fn into_identity(self) -> Identity {\n        self\n    }\n}\n\nimpl IntoIdentity for String {\n    fn into_identity(self) -> Identity {\n        self.as_str().into_identity()\n    }\n}\n\nimpl IntoIdentity for &str {\n    fn into_identity(self) -> Identity {\n        Identity::Unary(SeaRc::new(Alias::new(self)))\n    }\n}\n\nimpl<T> IntoIdentity for T\nwhere\n    T: IdenStatic,\n{\n    fn into_identity(self) -> Identity {\n        Identity::Unary(self.into_iden())\n    }\n}\n\nimpl<T, C> IntoIdentity for (T, C)\nwhere\n    T: IdenStatic,\n    C: IdenStatic,\n{\n    fn into_identity(self) -> Identity {\n        Identity::Binary(self.0.into_iden(), self.1.into_iden())\n    }\n}\n\nimpl<T, C, R> IntoIdentity for (T, C, R)\nwhere\n    T: IdenStatic,\n    C: IdenStatic,\n    R: IdenStatic,\n{\n    fn into_identity(self) -> Identity {\n        Identity::Ternary(self.0.into_iden(), self.1.into_iden(), self.2.into_iden())\n    }\n}\n\nmacro_rules! impl_into_identity {\n    ( $($T:ident : $N:tt),+ $(,)? ) => {\n        impl< $($T),+ > IntoIdentity for ( $($T),+ )\n        where\n            $($T: IdenStatic),+\n        {\n            fn into_identity(self) -> Identity {\n                Identity::Many(vec![\n                    $(self.$N.into_iden()),+\n                ])\n            }\n        }\n    };\n}\n\n#[rustfmt::skip]\nmod impl_into_identity {\n    use super::*;\n\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9, T10:10);\n    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9, T10:10, T11:11);\n}\n\nimpl<E, C> IdentityOf<E> for C\nwhere\n    E: EntityTrait<Column = C>,\n    C: ColumnTrait,\n{\n    fn identity_of(self) -> Identity {\n        self.into_identity()\n    }\n}\n\nmacro_rules! impl_identity_of {\n    ( $($T:ident),+ $(,)? ) => {\n        impl<E, C> IdentityOf<E> for ( $($T),+ )\n        where\n            E: EntityTrait<Column = C>,\n            C: ColumnTrait,\n        {\n            fn identity_of(self) -> Identity {\n                self.into_identity()\n            }\n        }\n    };\n}\n\n#[rustfmt::skip]\nmod impl_identity_of {\n    use super::*;\n\n    impl_identity_of!(C, C);\n    impl_identity_of!(C, C, C);\n    impl_identity_of!(C, C, C, C);\n    impl_identity_of!(C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C, C, C, C, C, C);\n    impl_identity_of!(C, C, C, C, C, C, C, C, C, C, C, C);\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn test_identity_contains() {\n        let abc = Identity::Ternary(\"a\".into(), \"b\".into(), \"c\".into());\n        let a = Identity::Unary(\"a\".into());\n        let ab = Identity::Binary(\"a\".into(), \"b\".into());\n        let bc = Identity::Binary(\"b\".into(), \"c\".into());\n        let d = Identity::Unary(\"d\".into());\n        let bcd = Identity::Ternary(\"b\".into(), \"c\".into(), \"d\".into());\n\n        assert!(abc.contains(&\"a\".into()));\n        assert!(abc.contains(&\"b\".into()));\n        assert!(abc.contains(&\"c\".into()));\n        assert!(!abc.contains(&\"d\".into()));\n\n        assert!(abc.fully_contains(&a));\n        assert!(abc.fully_contains(&ab));\n        assert!(abc.fully_contains(&bc));\n        assert!(!abc.fully_contains(&d));\n        assert!(!abc.fully_contains(&bcd));\n    }\n}\n"
  },
  {
    "path": "src/entity/link.rs",
    "content": "use crate::{EntityTrait, QuerySelect, RelationDef, Select, join_tbl_on_condition};\nuse sea_query::{\n    Alias, CommonTableExpression, Condition, IntoIden, IntoTableRef, JoinType, UnionType,\n};\n\n/// Same as [RelationDef]\npub type LinkDef = RelationDef;\n\n/// A Trait for links between Entities\npub trait Linked {\n    #[allow(missing_docs)]\n    type FromEntity: EntityTrait;\n\n    #[allow(missing_docs)]\n    type ToEntity: EntityTrait;\n\n    /// Link for an Entity\n    fn link(&self) -> Vec<LinkDef>;\n\n    /// Find all the Entities that are linked to the Entity\n    fn find_linked(&self) -> Select<Self::ToEntity> {\n        find_linked(self.link().into_iter().rev(), JoinType::InnerJoin)\n    }\n}\n\npub(crate) fn find_linked<I, E>(links: I, join: JoinType) -> Select<E>\nwhere\n    I: Iterator<Item = LinkDef>,\n    E: EntityTrait,\n{\n    let mut select = Select::new();\n    for (i, mut rel) in links.enumerate() {\n        let from_tbl = format!(\"r{i}\").into_iden();\n        let to_tbl = if i > 0 {\n            format!(\"r{}\", i - 1).into_iden()\n        } else {\n            rel.to_tbl.sea_orm_table().clone()\n        };\n        let table_ref = rel.from_tbl;\n\n        let mut condition = Condition::all().add(join_tbl_on_condition(\n            from_tbl.clone(),\n            to_tbl.clone(),\n            rel.from_col,\n            rel.to_col,\n        ));\n        if let Some(f) = rel.on_condition.take() {\n            condition = condition.add(f(from_tbl.clone(), to_tbl.clone()));\n        }\n\n        select.query().join_as(join, table_ref, from_tbl, condition);\n    }\n    select\n}\n\npub(crate) fn find_linked_recursive<E>(\n    mut initial_query: Select<E>,\n    mut link: Vec<LinkDef>,\n) -> Select<E>\nwhere\n    E: EntityTrait,\n{\n    let cte_name = Alias::new(\"cte\");\n\n    let Some(first) = link.first_mut() else {\n        return initial_query;\n    };\n    first.from_tbl = cte_name.clone().into_table_ref();\n    let mut recursive_query: Select<E> =\n        find_linked(link.into_iter().rev(), JoinType::InnerJoin).select_only();\n    initial_query.query.exprs_mut_for_each(|expr| {\n        recursive_query.query.expr(expr.clone());\n    });\n\n    let mut cte_query = initial_query.query.clone();\n    cte_query.union(UnionType::All, recursive_query.query);\n\n    let cte = CommonTableExpression::new()\n        .table_name(cte_name.clone())\n        .query(cte_query)\n        .to_owned();\n\n    let mut select = E::find().select_only();\n    initial_query.query.exprs_mut_for_each(|expr| {\n        select.query.expr(expr.clone());\n    });\n    select\n        .query\n        .from_clear()\n        .from_as(cte_name, E::default())\n        .with_cte(cte);\n    select\n}\n"
  },
  {
    "path": "src/entity/mod.rs",
    "content": "/// This modules contains types and traits for an  Entity, ActiveMode, Model, PrimaryKey, ForeignKey and Relations.\n///\n/// // An Entity\n/// A unit struct implements [EntityTrait](crate::EntityTrait) representing a table in the database.\n///\n/// This trait contains the properties of an entity including\n///\n/// - The Table Name which is implemented by [EntityName](crate::EntityName)\n/// - The Column which is implemented by [ColumnTrait](crate::ColumnTrait)\n/// - A Relation which is implemented by [RelationTrait](crate::RelationTrait)\n/// - The Primary Key which is implemented by [PrimaryKeyTrait](crate::PrimaryKeyTrait)\n///   and [PrimaryKeyToColumn](crate::PrimaryKeyToColumn)\n///\n/// This trait also provides an API for CRUD actions\n///\n/// #### Example for creating an Entity, Model and ActiveModel\n/// ```\n/// #[cfg(feature = \"macros\")]\n/// # use sea_orm::entity::prelude::*;\n/// use sea_orm::ActiveModelBehavior;\n/// use sea_orm::ColumnDef;\n/// use sea_orm::ColumnTrait;\n/// use sea_orm::ColumnType;\n/// use sea_orm::EntityName;\n/// use sea_orm::PrimaryKeyTrait;\n/// use sea_orm::RelationDef;\n/// use sea_orm::RelationTrait;\n///\n/// // Use [DeriveEntity] to derive the EntityTrait automatically\n/// #[derive(Copy, Clone, Default, Debug, DeriveEntity)]\n/// pub struct Entity;\n///\n/// /// The [EntityName] describes the name of a table\n/// impl EntityName for Entity {\n///     fn table_name(&self) -> &'static str {\n///         \"filling\"\n///     }\n/// }\n///\n/// // Create a Model for the Entity through [DeriveModel].\n/// // The `Model` handles `READ` operations on a table in a database.\n/// // The [DeriveActiveModel] creates a way to perform `CREATE` , `READ` and `UPDATE` operations\n/// // in a database\n/// #[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel)]\n/// pub struct Model {\n///     pub id: i32,\n///     pub name: String,\n/// }\n///\n/// // Use the [DeriveColumn] to create a Column for an the table called Entity\n/// // The [EnumIter] which creates a new type that iterates of the variants of a Column.\n/// #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n/// pub enum Column {\n///     Id,\n///     Name,\n/// }\n///\n/// // Create a PrimaryKey for the Entity using the [PrimaryKeyTrait]\n/// // The [EnumIter] which creates a new type that iterates of the variants of a PrimaryKey.\n/// #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n/// pub enum PrimaryKey {\n///     Id,\n/// }\n///\n/// // Or implement the [PrimaryKeyTrait] manually instead of using the macro [DerivePrimaryKey]\n/// impl PrimaryKeyTrait for PrimaryKey {\n///     type ValueType = i32;\n///\n///     fn auto_increment() -> bool {\n///         true\n///     }\n/// }\n///\n/// #[derive(Copy, Clone, Debug, EnumIter)]\n/// pub enum Relation {}\n///\n/// impl ColumnTrait for Column {\n///     type EntityName = Entity;\n///\n///     fn def(&self) -> ColumnDef {\n///         match self {\n///             Self::Id => ColumnType::Integer.def(),\n///             Self::Name => ColumnType::String(StringLen::None).def(),\n///         }\n///     }\n/// }\n///\n/// // Create a Relation for the Entity\n/// impl RelationTrait for Relation {\n///     fn def(&self) -> RelationDef {\n///         unimplemented!()\n///     }\n/// }\n///\n/// // Implement user defined operations for CREATE, UPDATE and DELETE operations\n/// // to create an ActiveModel using the [ActiveModelBehavior]\n/// impl ActiveModelBehavior for ActiveModel {}\n/// ```\nmod active_enum;\nmod active_model;\nmod active_model_ex;\nmod active_value;\n#[cfg(feature = \"with-arrow\")]\nmod arrow_schema;\nmod base_entity;\npub(crate) mod column;\nmod column_def;\npub mod compound;\nmod identity;\nmod link;\nmod model;\nmod partial_model;\n/// Re-export common types from the entity\npub mod prelude;\nmod primary_key;\n#[cfg(feature = \"entity-registry\")]\nmod registry;\nmod relation;\n#[cfg(feature = \"with-arrow\")]\npub(crate) mod with_arrow;\n\npub use active_enum::*;\npub use active_model::*;\npub use active_model_ex::*;\npub use active_value::*;\n#[cfg(feature = \"with-arrow\")]\npub use arrow_schema::*;\npub use base_entity::*;\npub use column::*;\npub use column_def::*;\npub use compound::EntityLoaderTrait;\npub use identity::*;\npub use link::*;\npub use model::*;\npub use partial_model::*;\npub use primary_key::*;\n#[cfg(feature = \"entity-registry\")]\npub use registry::*;\npub use relation::*;\n"
  },
  {
    "path": "src/entity/model.rs",
    "content": "use crate::{\n    ActiveModelBehavior, ActiveModelTrait, ColumnTrait, ConnectionTrait, DbErr, DeleteResult,\n    EntityTrait, IntoActiveModel, Iterable, Linked, PrimaryKeyArity, PrimaryKeyToColumn,\n    PrimaryKeyTrait, QueryFilter, QueryResult, Related, Select, SelectModel, SelectorRaw,\n    Statement, TryGetError, find_linked_recursive,\n};\npub use sea_query::Value;\nuse sea_query::{ArrayType, ValueTuple};\nuse std::fmt::Debug;\n\n/// The interface for Model, implemented by data structs\n#[async_trait::async_trait]\npub trait ModelTrait: Clone + Send + Debug {\n    #[allow(missing_docs)]\n    type Entity: EntityTrait;\n\n    /// Get the [Value] of a column from a Model\n    fn get(&self, c: <Self::Entity as EntityTrait>::Column) -> Value;\n\n    /// Get the Value Type of a column from the Model\n    fn get_value_type(c: <Self::Entity as EntityTrait>::Column) -> ArrayType;\n\n    /// Set the Value of a Model field, panic if failed\n    fn set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) {\n        self.try_set(c, v)\n            .unwrap_or_else(|e| panic!(\"Failed to set value for {:?}: {e:?}\", c.as_column_ref()))\n    }\n\n    /// Set the Value of a Model field, return error if failed\n    fn try_set(&mut self, c: <Self::Entity as EntityTrait>::Column, v: Value) -> Result<(), DbErr>;\n\n    /// Find related Models belonging to self\n    fn find_related<R>(&self, _: R) -> Select<R>\n    where\n        R: EntityTrait,\n        Self::Entity: Related<R>,\n    {\n        <Self::Entity as Related<R>>::find_related().belongs_to(self)\n    }\n\n    /// Find linked Models belonging to self\n    fn find_linked<L>(&self, l: L) -> Select<L::ToEntity>\n    where\n        L: Linked<FromEntity = Self::Entity>,\n    {\n        let tbl_alias = &format!(\"r{}\", l.link().len() - 1);\n        l.find_linked().belongs_to_tbl_alias(self, tbl_alias)\n    }\n\n    #[doc(hidden)]\n    /// Find linked Models with a recursive CTE for self-referencing relation chains\n    fn find_linked_recursive<L>(&self, l: L) -> Select<L::ToEntity>\n    where\n        L: Linked<FromEntity = Self::Entity, ToEntity = Self::Entity>,\n    {\n        // Have to do this because L is not Clone\n        let link = l.link();\n        let initial_query = self.find_linked(l);\n        find_linked_recursive(initial_query, link)\n    }\n\n    /// Delete a model\n    async fn delete<'a, A, C>(self, db: &'a C) -> Result<DeleteResult, DbErr>\n    where\n        Self: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: ActiveModelTrait<Entity = Self::Entity> + ActiveModelBehavior + Send + 'a,\n    {\n        self.into_active_model().delete(db).await\n    }\n\n    /// Get the primary key value of the Model\n    fn get_primary_key_value(&self) -> ValueTuple {\n        let mut cols = <Self::Entity as EntityTrait>::PrimaryKey::iter();\n        macro_rules! next {\n            () => {\n                self.get(cols.next().expect(\"Already checked arity\").into_column())\n            };\n        }\n        match <<<Self::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n            1 => {\n                let s1 = next!();\n                ValueTuple::One(s1)\n            }\n            2 => {\n                let s1 = next!();\n                let s2 = next!();\n                ValueTuple::Two(s1, s2)\n            }\n            3 => {\n                let s1 = next!();\n                let s2 = next!();\n                let s3 = next!();\n                ValueTuple::Three(s1, s2, s3)\n            }\n            len => {\n                let mut vec = Vec::with_capacity(len);\n                for _ in 0..len {\n                    let s = next!();\n                    vec.push(s);\n                }\n                ValueTuple::Many(vec)\n            }\n        }\n    }\n}\n\n/// A Trait for implementing a [QueryResult]\npub trait FromQueryResult: Sized {\n    /// Instantiate a Model from a [QueryResult]\n    ///\n    /// NOTE: Please also override `from_query_result_nullable` when manually implementing.\n    ///       The future default implementation will be along the lines of:\n    ///\n    /// ```rust,ignore\n    /// fn from_query_result(res: &QueryResult, pre: &str) -> Result<Self, DbErr> {\n    ///     (Self::from_query_result_nullable(res, pre)?)\n    /// }\n    /// ```\n    fn from_query_result(res: &QueryResult, pre: &str) -> Result<Self, DbErr>;\n\n    /// Transform the error from instantiating a Model from a [QueryResult]\n    /// and converting it to an [Option]\n    fn from_query_result_optional(res: &QueryResult, pre: &str) -> Result<Option<Self>, DbErr> {\n        Ok(Self::from_query_result(res, pre).ok())\n\n        // would really like to do the following, but can't without version bump:\n        // match Self::from_query_result_nullable(res, pre) {\n        //     Ok(v) => Ok(Some(v)),\n        //     Err(TryGetError::Null(_)) => Ok(None),\n        //     Err(TryGetError::DbErr(err)) => Err(err),\n        // }\n    }\n\n    /// Transform the error from instantiating a Model from a [QueryResult]\n    /// and converting it to an [Option]\n    ///\n    /// NOTE: This will most likely stop being a provided method in the next major version!\n    fn from_query_result_nullable(res: &QueryResult, pre: &str) -> Result<Self, TryGetError> {\n        Self::from_query_result(res, pre).map_err(TryGetError::DbErr)\n    }\n\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(2),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{FromQueryResult, query::*};\n    ///\n    /// #[derive(Debug, PartialEq, FromQueryResult)]\n    /// struct SelectResult {\n    ///     name: String,\n    ///     num_of_cakes: i32,\n    /// }\n    ///\n    /// let res: Vec<SelectResult> = SelectResult::find_by_statement(Statement::from_sql_and_values(\n    ///     DbBackend::Postgres,\n    ///     r#\"SELECT \"name\", COUNT(*) AS \"num_of_cakes\" FROM \"cake\" GROUP BY(\"name\")\"#,\n    ///     [],\n    /// ))\n    /// .all(&db)\n    /// .await?;\n    ///\n    /// assert_eq!(\n    ///     res,\n    ///     [SelectResult {\n    ///         name: \"Chocolate Forest\".to_owned(),\n    ///         num_of_cakes: 2,\n    ///     },]\n    /// );\n    /// #\n    /// # assert_eq!(\n    /// #     db.into_transaction_log(),\n    /// #     [Transaction::from_sql_and_values(\n    /// #         DbBackend::Postgres,\n    /// #         r#\"SELECT \"name\", COUNT(*) AS \"num_of_cakes\" FROM \"cake\" GROUP BY(\"name\")\"#,\n    /// #         []\n    /// #     ),]\n    /// # );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn find_by_statement(stmt: Statement) -> SelectorRaw<SelectModel<Self>> {\n        SelectorRaw::<SelectModel<Self>>::from_statement(stmt)\n    }\n}\n\nimpl<T: FromQueryResult> FromQueryResult for Option<T> {\n    fn from_query_result(res: &QueryResult, pre: &str) -> Result<Self, DbErr> {\n        Ok(Self::from_query_result_nullable(res, pre)?)\n    }\n\n    fn from_query_result_optional(res: &QueryResult, pre: &str) -> Result<Option<Self>, DbErr> {\n        match Self::from_query_result_nullable(res, pre) {\n            Ok(v) => Ok(Some(v)),\n            Err(TryGetError::Null(_)) => Ok(None),\n            Err(TryGetError::DbErr(err)) => Err(err),\n        }\n    }\n\n    fn from_query_result_nullable(res: &QueryResult, pre: &str) -> Result<Self, TryGetError> {\n        match T::from_query_result_nullable(res, pre) {\n            Ok(v) => Ok(Some(v)),\n            Err(TryGetError::Null(_)) => Ok(None),\n            Err(err @ TryGetError::DbErr(_)) => Err(err),\n        }\n    }\n}\n\n/// A Trait for any type that can be converted into an Model\npub trait TryIntoModel<M>\nwhere\n    M: ModelTrait,\n{\n    /// Method to call to perform the conversion\n    fn try_into_model(self) -> Result<M, DbErr>;\n}\n\nimpl<M> TryIntoModel<M> for M\nwhere\n    M: ModelTrait,\n{\n    fn try_into_model(self) -> Result<M, DbErr> {\n        Ok(self)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        IntoActiveModel, Unchanged,\n        prelude::*,\n        tests_cfg::{cake, filling, fruit, post},\n    };\n\n    #[test]\n    fn test_model() {\n        fn filter_by_column(col: post::Column) -> Expr {\n            col.eq(\"attribute\")\n        }\n\n        fn get_value_from(model: &post::Model, col: post::Column) {\n            let value: i32 = model.get(col).unwrap();\n            assert_eq!(value, 12);\n        }\n\n        let model = post::Model {\n            id: 12,\n            user_id: 14,\n            title: \"hello\".into(),\n        };\n\n        get_value_from(&model, post::COLUMN.id.0);\n        filter_by_column(post::COLUMN.title.0);\n\n        let filling = filling::Model {\n            id: 12,\n            name: \"\".into(),\n            vendor_id: None,\n            ignored_attr: 24,\n        };\n\n        let filling_am = filling::ActiveModel {\n            id: Unchanged(12),\n            name: Unchanged(\"\".into()),\n            vendor_id: Unchanged(None),\n        };\n\n        assert_eq!(filling.into_active_model(), filling_am);\n\n        let filling_ex = filling::ActiveModelEx {\n            id: Unchanged(12),\n            name: Unchanged(\"\".into()),\n            vendor_id: Unchanged(None),\n            ingredients: HasManyModel::NotSet,\n        };\n\n        assert_eq!(filling_am.into_ex(), filling_ex);\n\n        let cake_ex = cake::ModelEx {\n            id: 12,\n            name: \"C\".into(),\n            fruit: HasOne::loaded(fruit::Model {\n                id: 13,\n                name: \"F\".into(),\n                cake_id: Some(12),\n            }),\n            fillings: HasMany::Loaded(vec![\n                filling::Model {\n                    id: 14,\n                    name: \"FF\".into(),\n                    vendor_id: None,\n                    ignored_attr: 1,\n                }\n                .into(),\n            ]),\n        };\n\n        let cake_am = cake::ActiveModelEx {\n            id: Unchanged(12),\n            name: Unchanged(\"C\".into()),\n            fruit: HasOneModel::Set(\n                fruit::ActiveModelEx {\n                    id: Unchanged(13),\n                    name: Unchanged(\"F\".into()),\n                    cake_id: Unchanged(Some(12)),\n                }\n                .into(),\n            ),\n            fillings: HasManyModel::Append(vec![filling::ActiveModelEx {\n                id: Unchanged(14),\n                name: Unchanged(\"FF\".into()),\n                vendor_id: Unchanged(None),\n                ingredients: HasManyModel::NotSet,\n            }]),\n        };\n\n        assert_eq!(cake_ex.into_active_model(), cake_am);\n    }\n}\n"
  },
  {
    "path": "src/entity/partial_model.rs",
    "content": "use crate::{EntityTrait, FromQueryResult, IdenStatic, Iterable, ModelTrait, QuerySelect};\nuse sea_query::Expr;\n\n/// A trait for a part of [Model](super::model::ModelTrait)\npub trait PartialModelTrait: FromQueryResult {\n    /// Select specific columns this [PartialModel] needs\n    ///\n    /// No need to implement this method, please implement `select_cols_nested` instead.\n    fn select_cols<S: QuerySelect>(select: S) -> S {\n        Self::select_cols_nested(select, None, None)\n    }\n\n    /// Used when nesting these structs into each other.\n    ///\n    /// Example impl\n    ///\n    /// ```ignore\n    /// fn select_cols_nested<S: QuerySelect>(mut select: S, prefix: Option<&str>) -> S {\n    ///     if let Some(prefix) = prefix {\n    ///         for col in <<T::Entity as EntityTrait>::Column as Iterable>::iter() {\n    ///             let alias = format!(\"{prefix}{}\", col.as_str());\n    ///             select = select.column_as(col, alias);\n    ///         }\n    ///     } else {\n    ///         for col in <<T::Entity as EntityTrait>::Column as Iterable>::iter() {\n    ///             select = select.column(col);\n    ///         }\n    ///     }\n    ///     select\n    /// }\n    /// ```\n    fn select_cols_nested<S: QuerySelect>(\n        select: S,\n        prefix: Option<&str>,\n        alias: Option<&'static str>,\n    ) -> S;\n}\n\nimpl<T: PartialModelTrait> PartialModelTrait for Option<T> {\n    fn select_cols_nested<S: QuerySelect>(\n        select: S,\n        prefix: Option<&str>,\n        alias: Option<&'static str>,\n    ) -> S {\n        T::select_cols_nested(select, prefix, alias)\n    }\n}\n\nimpl<T: ModelTrait + FromQueryResult> PartialModelTrait for T {\n    fn select_cols_nested<S: QuerySelect>(\n        mut select: S,\n        prefix: Option<&str>,\n        alias: Option<&'static str>,\n    ) -> S {\n        match (prefix, alias) {\n            (Some(prefix), Some(alias)) => {\n                for col in <<T::Entity as EntityTrait>::Column as Iterable>::iter() {\n                    let select_as = format!(\"{prefix}{}\", col.as_str());\n                    select = select.column_as(Expr::col((alias, col)), select_as);\n                }\n            }\n            (Some(prefix), None) => {\n                for col in <<T::Entity as EntityTrait>::Column as Iterable>::iter() {\n                    let select_as = format!(\"{prefix}{}\", col.as_str());\n                    select = select.column_as(col, select_as);\n                }\n            }\n            (None, Some(alias)) => {\n                for col in <<T::Entity as EntityTrait>::Column as Iterable>::iter() {\n                    select = select.column_as(Expr::col((alias, col)), col.as_str());\n                }\n            }\n            (None, None) => {\n                for col in <<T::Entity as EntityTrait>::Column as Iterable>::iter() {\n                    select = select.column(col);\n                }\n            }\n        }\n        select\n    }\n}\n"
  },
  {
    "path": "src/entity/prelude.rs",
    "content": "pub use crate::{\n    ActiveEnum, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, ColumnType,\n    ColumnTypeTrait, ConnectionTrait, CursorTrait, DatabaseConnection, DbConn, EntityName,\n    EntityTrait, EnumIter, ForeignKeyAction, Iden, IdenStatic, Linked, LoaderTrait, ModelTrait,\n    PaginatorTrait, PrimaryKeyArity, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult,\n    Related, RelatedSelfVia, RelationDef, RelationTrait, Select, SelectExt, Value,\n    error::*,\n    sea_query::{DynIden, Expr, RcOrArc, SeaRc, StringLen},\n};\n\n#[cfg(feature = \"macros\")]\npub use crate::{\n    DeriveActiveEnum, DeriveActiveModel, DeriveActiveModelBehavior, DeriveActiveModelEx,\n    DeriveArrowSchema, DeriveColumn, DeriveDisplay, DeriveEntity, DeriveEntityModel, DeriveIden,\n    DeriveIntoActiveModel, DeriveModel, DeriveModelEx, DerivePartialModel, DerivePrimaryKey,\n    DeriveRelatedEntity, DeriveRelation, DeriveValueType, FromJsonQueryResult,\n};\n\npub use super::active_model_ex::{HasManyModel, HasOneModel};\npub use super::compound::{HasMany, HasOne};\n\n#[cfg(not(feature = \"sync\"))]\npub use async_trait;\n\n#[cfg(feature = \"with-json\")]\npub use serde_json::Value as Json;\n\n#[cfg(feature = \"with-chrono\")]\npub use chrono::NaiveDate as Date;\n\n#[cfg(feature = \"with-chrono\")]\npub use chrono::NaiveTime as Time;\n\n#[cfg(feature = \"with-chrono\")]\npub use chrono::NaiveDateTime as DateTime;\n\n/// Date time with fixed offset\n#[cfg(feature = \"with-chrono\")]\npub type DateTimeWithTimeZone = chrono::DateTime<chrono::FixedOffset>;\n\n/// Date time represented in UTC\n#[cfg(feature = \"with-chrono\")]\npub type DateTimeUtc = chrono::DateTime<chrono::Utc>;\n\n/// Date time represented in local time\n#[cfg(feature = \"with-chrono\")]\npub type DateTimeLocal = chrono::DateTime<chrono::Local>;\n\n#[cfg(feature = \"with-chrono\")]\npub use chrono::NaiveDate as ChronoDate;\n\n#[cfg(feature = \"with-chrono\")]\npub use chrono::NaiveTime as ChronoTime;\n\n#[cfg(feature = \"with-chrono\")]\npub use chrono::NaiveDateTime as ChronoDateTime;\n\n/// Date time with fixed offset\n#[cfg(feature = \"with-chrono\")]\npub type ChronoDateTimeWithTimeZone = chrono::DateTime<chrono::FixedOffset>;\n\n/// Date time represented in UTC\n#[cfg(feature = \"with-chrono\")]\npub type ChronoDateTimeUtc = chrono::DateTime<chrono::Utc>;\n\n/// The UTC type from chrono\n#[cfg(feature = \"with-chrono\")]\npub type ChronoUtc = chrono::Utc;\n\n/// Date time represented in local time\n#[cfg(feature = \"with-chrono\")]\npub type ChronoDateTimeLocal = chrono::DateTime<chrono::Local>;\n\n#[cfg(feature = \"with-chrono\")]\npub use crate::value::{ChronoUnixTimestamp, ChronoUnixTimestampMillis};\n\n#[cfg(feature = \"with-time\")]\npub use time::Date as TimeDate;\n\n#[cfg(feature = \"with-time\")]\npub use time::Time as TimeTime;\n\n#[cfg(feature = \"with-time\")]\npub use time::PrimitiveDateTime as TimeDateTime;\n\n#[cfg(feature = \"with-time\")]\npub use time::OffsetDateTime as TimeDateTimeWithTimeZone;\n\n#[cfg(feature = \"with-time\")]\npub use crate::value::{TimeUnixTimestamp, TimeUnixTimestampMillis};\n\n#[cfg(feature = \"with-rust_decimal\")]\npub use rust_decimal::Decimal;\n\n#[cfg(feature = \"with-bigdecimal\")]\npub use bigdecimal::BigDecimal;\n\n#[cfg(feature = \"with-uuid\")]\npub use uuid::Uuid;\n\n#[cfg(feature = \"with-uuid\")]\npub use crate::value::TextUuid;\n\n#[cfg(feature = \"postgres-vector\")]\npub use pgvector::Vector as PgVector;\n\n#[cfg(feature = \"with-ipnetwork\")]\npub use ipnetwork::IpNetwork;\n"
  },
  {
    "path": "src/entity/primary_key.rs",
    "content": "use super::{ColumnTrait, IdenStatic, Iterable};\nuse crate::{TryFromU64, TryGetableMany};\nuse sea_query::{FromValueTuple, IntoValueTuple};\nuse std::fmt::Debug;\n\n/// A Trait for to be used to define a Primary Key.\n///\n/// A primary key can be derived manually\n///\n/// ### Example\n/// ```text\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(Copy, Clone, Debug, EnumIter)]\n/// pub enum PrimaryKey {\n///     Id,\n/// }\n/// impl PrimaryKeyTrait for PrimaryKey {\n///     type ValueType = i32;\n///\n///     fn auto_increment() -> bool {\n///         true\n///     }\n/// }\n/// ```\n///\n/// Alternatively, use derive macros to automatically implement the trait for a Primary Key\n///\n/// ### Example\n/// ```text\n/// use sea_orm::entity::prelude::*;\n///\n/// #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\n/// pub enum PrimaryKey {\n///     Id,\n/// }\n/// ```\n/// See module level docs [crate::entity] for a full example\npub trait PrimaryKeyTrait: IdenStatic + Iterable {\n    #[allow(missing_docs)]\n    type ValueType: Sized\n        + Send\n        + Debug\n        + PartialEq\n        + IntoValueTuple\n        + FromValueTuple\n        + TryGetableMany\n        + TryFromU64\n        + PrimaryKeyArity;\n\n    /// Method to call to perform `AUTOINCREMENT` operation on a Primary Key\n    fn auto_increment() -> bool;\n}\n\n/// Trait to map a Primary Key to a column\npub trait PrimaryKeyToColumn {\n    #[allow(missing_docs)]\n    type Column: ColumnTrait;\n\n    /// Method to map a primary key to a column in an Entity\n    fn into_column(self) -> Self::Column;\n\n    /// Method to map a primary key from a column in an Entity\n    fn from_column(col: Self::Column) -> Option<Self>\n    where\n        Self: Sized;\n}\n\n/// How many columns this Primary Key comprises\npub trait PrimaryKeyArity {\n    /// Arity of the Primary Key\n    const ARITY: usize;\n}\n\nimpl<V> PrimaryKeyArity for V\nwhere\n    V: crate::TryGetable,\n{\n    const ARITY: usize = 1;\n}\n\nmacro_rules! impl_pk_arity {\n    ($len:expr, $($tuple_arg:ident),*) => {\n        impl<$($tuple_arg: crate::TryGetableMany,)*> PrimaryKeyArity for ($($tuple_arg,)*) {\n            const ARITY: usize = $len;\n        }\n    }\n}\n\nimpl_pk_arity!(1, T1);\nimpl_pk_arity!(2, T1, T2);\nimpl_pk_arity!(3, T1, T2, T3);\nimpl_pk_arity!(4, T1, T2, T3, T4);\nimpl_pk_arity!(5, T1, T2, T3, T4, T5);\nimpl_pk_arity!(6, T1, T2, T3, T4, T5, T6);\nimpl_pk_arity!(7, T1, T2, T3, T4, T5, T6, T7);\nimpl_pk_arity!(8, T1, T2, T3, T4, T5, T6, T7, T8);\nimpl_pk_arity!(9, T1, T2, T3, T4, T5, T6, T7, T8, T9);\nimpl_pk_arity!(10, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);\nimpl_pk_arity!(11, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);\nimpl_pk_arity!(12, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);\n\n#[cfg(test)]\nmod tests {\n    use crate::{EntityTrait, Identity};\n\n    #[test]\n    #[cfg(feature = \"macros\")]\n    fn test_composite_primary_key() {\n        mod primary_key_of_1 {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"primary_key_of_1\")]\n            pub struct Model {\n                #[sea_orm(primary_key)]\n                pub id: i32,\n                pub owner: String,\n                pub name: String,\n                pub description: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        mod primary_key_of_2 {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"primary_key_of_2\")]\n            pub struct Model {\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_1: i32,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_2: String,\n                pub owner: String,\n                pub name: String,\n                pub description: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        mod primary_key_of_3 {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"primary_key_of_3\")]\n            pub struct Model {\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_1: i32,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_2: String,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_3: Uuid,\n                pub owner: String,\n                pub name: String,\n                pub description: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        mod primary_key_of_4 {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"primary_key_of_4\")]\n            pub struct Model {\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_1: TimeDateTimeWithTimeZone,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_2: Uuid,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_3: Json,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_4: Decimal,\n                pub owner: String,\n                pub name: String,\n                pub description: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        mod primary_key_of_11 {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n            #[sea_orm(\n                rs_type = \"String\",\n                db_type = \"String(StringLen::N(1))\",\n                enum_name = \"category\"\n            )]\n            pub enum DeriveCategory {\n                #[sea_orm(string_value = \"B\")]\n                Big,\n                #[sea_orm(string_value = \"S\")]\n                Small,\n            }\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"primary_key_of_11\")]\n            pub struct Model {\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_1: Vec<u8>,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_2: DeriveCategory,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_3: Date,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_4: DateTime,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_5: Time,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_6: TimeTime,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_7: DateTime,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_8: TimeDateTime,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_9: DateTimeLocal,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_10: DateTimeUtc,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_11: DateTimeWithTimeZone,\n                pub owner: String,\n                pub name: String,\n                pub description: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        mod primary_key_of_12 {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"primary_key_of_12\")]\n            pub struct Model {\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_1: String,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_2: i8,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_3: u8,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_4: i16,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_5: u16,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_6: i32,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_7: u32,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_8: i64,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_9: u64,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_10: f32,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_11: f64,\n                #[sea_orm(primary_key, auto_increment = false)]\n                pub id_12: bool,\n                pub owner: String,\n                pub name: String,\n                pub description: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        assert_eq!(\n            primary_key_of_3::Entity::primary_key_identity(),\n            Identity::Ternary(\"id_1\".into(), \"id_2\".into(), \"id_3\".into())\n        );\n    }\n}\n"
  },
  {
    "path": "src/entity/registry.rs",
    "content": "use crate::{EntitySchemaInfo, Schema, SchemaBuilder};\nuse tracing::debug;\n\n#[derive(derive_more::Debug)]\n/// The data structure submitted by your Entity to the Entity Registry.\npub struct EntityRegistry {\n    /// Please use `module_path!()`.\n    pub module_path: &'static str,\n    /// Function that returns schema info for the Entity.\n    #[debug(skip)]\n    pub schema_info: fn(&Schema) -> EntitySchemaInfo,\n}\n\ninventory::collect!(EntityRegistry);\n\n/// Macro to register an Entity\npub use inventory::submit as register_entity;\n\nimpl EntityRegistry {\n    /// Builds a schema from all the registered entities, filtering by prefix.\n    pub fn build_schema(schema: Schema, prefix: &str) -> SchemaBuilder {\n        let mut schema = SchemaBuilder::new(schema);\n        let mut string;\n        let mut prefix = prefix.trim_end_matches(\"*\");\n        if !prefix.contains(\"::\") {\n            string = format!(\"{prefix}::\");\n            prefix = &string;\n        }\n        if let Some((left, right)) = prefix.split_once(\"::\") {\n            if left.contains(\"-\") {\n                // convert crate name to module path\n                let left = left.replace('-', \"_\");\n                string = format!(\"{left}::{right}\");\n                prefix = &string;\n            }\n        }\n        debug!(\"Registering entities with prefix `{prefix}`\");\n        for entity in inventory::iter::<crate::EntityRegistry>() {\n            if entity.module_path.starts_with(prefix) {\n                schema.register_entity((entity.schema_info)(schema.helper()));\n                debug!(\"Registered {}\", entity.module_path);\n            } else {\n                debug!(\"Skipped {}\", entity.module_path);\n            }\n        }\n        schema\n    }\n}\n"
  },
  {
    "path": "src/entity/relation.rs",
    "content": "use crate::{\n    EntityTrait, Identity, IdentityOf, Iterable, QuerySelect, Select, join_tbl_on_condition,\n};\nuse core::marker::PhantomData;\nuse sea_query::{\n    Condition, ConditionType, DynIden, ForeignKeyCreateStatement, IntoIden, JoinType,\n    TableForeignKey, TableRef,\n};\nuse std::{fmt::Debug, sync::Arc};\n\n/// Defines the type of relationship\n#[derive(Clone, Debug, PartialEq, Eq, Hash)]\npub enum RelationType {\n    /// An Entity has one relationship\n    HasOne,\n    /// An Entity has many relationships\n    HasMany,\n}\n\n/// Action to perform on a foreign key whenever there are changes\n/// to an ActiveModel\npub type ForeignKeyAction = sea_query::ForeignKeyAction;\n\n/// Defines the relations of an Entity\npub trait RelationTrait: Iterable + Debug + 'static {\n    /// Creates a [`RelationDef`]\n    fn def(&self) -> RelationDef;\n\n    /// Name of the relation enum\n    fn name(&self) -> String {\n        format!(\"{self:?}\")\n    }\n}\n\n/// A trait to relate two Entities for them to be joined in queries\npub trait Related<R>\nwhere\n    R: EntityTrait,\n{\n    /// The RelationDef to the related Entity\n    fn to() -> RelationDef;\n\n    /// The RelationDef to the junction table, if any\n    fn via() -> Option<RelationDef> {\n        None\n    }\n\n    /// Find related Entities\n    fn find_related() -> Select<R> {\n        Select::<R>::new().join_join_rev(JoinType::InnerJoin, Self::to(), Self::via())\n    }\n}\n\n/// A trait to relate an Entity to itself through a junction table\npub trait RelatedSelfVia<R>\nwhere\n    R: EntityTrait,\n{\n    /// The RelationDef to the related Entity\n    fn to() -> RelationDef;\n\n    /// The RelationDef to the junction table\n    fn via() -> RelationDef;\n\n    /// Find related Entities\n    fn find_related() -> Select<R> {\n        Select::<R>::new().join_join_rev(JoinType::InnerJoin, Self::to(), Some(Self::via()))\n    }\n}\n\n/// Defines a relationship\n#[derive(derive_more::Debug, Clone)]\npub struct RelationDef {\n    /// The type of relationship defined in [RelationType]\n    pub rel_type: RelationType,\n    /// Reference from another Entity\n    pub from_tbl: TableRef,\n    /// Reference to another Entity\n    pub to_tbl: TableRef,\n    /// Reference to from a Column\n    pub from_col: Identity,\n    /// Reference to another column\n    pub to_col: Identity,\n    /// Defines the owner of the Relation\n    pub is_owner: bool,\n    /// Specifies if the foreign key should be skipped\n    pub skip_fk: bool,\n    /// Defines an operation to be performed on a Foreign Key when a\n    /// `DELETE` Operation is performed\n    pub on_delete: Option<ForeignKeyAction>,\n    /// Defines an operation to be performed on a Foreign Key when a\n    /// `UPDATE` Operation is performed\n    pub on_update: Option<ForeignKeyAction>,\n    /// Custom join ON condition\n    #[debug(\"{}\", on_condition.is_some())]\n    pub on_condition: Option<Arc<dyn Fn(DynIden, DynIden) -> Condition + Send + Sync>>,\n    /// The name of foreign key constraint\n    pub fk_name: Option<String>,\n    /// Condition type of join on expression\n    pub condition_type: ConditionType,\n}\n\n/// Idiomatically generate the join condition.\n///\n/// This allows using [RelationDef] directly where [`sea_query`] expects an [`IntoCondition`].\n///\n/// ## Examples\n///\n/// ```\n/// use sea_orm::tests_cfg::{cake, fruit};\n/// use sea_orm::{entity::*, sea_query::*};\n///\n/// let query = Query::select()\n///     .from(fruit::Entity)\n///     .inner_join(cake::Entity, fruit::Relation::Cake.def())\n///     .to_owned();\n///\n/// assert_eq!(\n///     query.to_string(MysqlQueryBuilder),\n///     r#\"SELECT  FROM `fruit` INNER JOIN `cake` ON `fruit`.`cake_id` = `cake`.`id`\"#\n/// );\n/// assert_eq!(\n///     query.to_string(PostgresQueryBuilder),\n///     r#\"SELECT  FROM \"fruit\" INNER JOIN \"cake\" ON \"fruit\".\"cake_id\" = \"cake\".\"id\"\"#\n/// );\n/// assert_eq!(\n///     query.to_string(SqliteQueryBuilder),\n///     r#\"SELECT  FROM \"fruit\" INNER JOIN \"cake\" ON \"fruit\".\"cake_id\" = \"cake\".\"id\"\"#\n/// );\n/// ```\nimpl From<RelationDef> for Condition {\n    fn from(mut rel: RelationDef) -> Condition {\n        // Use table alias (if any) to construct the join condition\n        let from_tbl = match rel.from_tbl.sea_orm_table_alias() {\n            Some(alias) => alias,\n            None => rel.from_tbl.sea_orm_table(),\n        };\n        let to_tbl = match rel.to_tbl.sea_orm_table_alias() {\n            Some(alias) => alias,\n            None => rel.to_tbl.sea_orm_table(),\n        };\n        let owner_keys = rel.from_col;\n        let foreign_keys = rel.to_col;\n\n        let mut condition = match rel.condition_type {\n            ConditionType::All => Condition::all(),\n            ConditionType::Any => Condition::any(),\n        };\n\n        condition = condition.add(join_tbl_on_condition(\n            from_tbl.clone(),\n            to_tbl.clone(),\n            owner_keys,\n            foreign_keys,\n        ));\n        if let Some(f) = rel.on_condition.take() {\n            condition = condition.add(f(from_tbl.clone(), to_tbl.clone()));\n        }\n\n        condition\n    }\n}\n\n/// Defines a helper to build a relation\n#[derive(derive_more::Debug)]\npub struct RelationBuilder<E, R>\nwhere\n    E: EntityTrait,\n    R: EntityTrait,\n{\n    entities: PhantomData<(E, R)>,\n    rel_type: RelationType,\n    from_tbl: TableRef,\n    to_tbl: TableRef,\n    from_col: Option<Identity>,\n    to_col: Option<Identity>,\n    is_owner: bool,\n    skip_fk: bool,\n    on_delete: Option<ForeignKeyAction>,\n    on_update: Option<ForeignKeyAction>,\n    #[debug(\"{}\", on_condition.is_some())]\n    on_condition: Option<Arc<dyn Fn(DynIden, DynIden) -> Condition + Send + Sync>>,\n    fk_name: Option<String>,\n    condition_type: ConditionType,\n}\n\nimpl RelationDef {\n    /// Reverse this relation (swap from and to)\n    pub fn rev(self) -> Self {\n        Self {\n            rel_type: self.rel_type,\n            from_tbl: self.to_tbl,\n            to_tbl: self.from_tbl,\n            from_col: self.to_col,\n            to_col: self.from_col,\n            is_owner: !self.is_owner,\n            skip_fk: self.skip_fk,\n            on_delete: self.on_delete,\n            on_update: self.on_update,\n            on_condition: self.on_condition,\n            fk_name: None,\n            condition_type: self.condition_type,\n        }\n    }\n\n    /// Express the relation from a table alias.\n    ///\n    /// This is a shorter and more discoverable equivalent to modifying `from_tbl` field by hand.\n    ///\n    /// # Examples\n    ///\n    /// Here's a short synthetic example.\n    /// In real life you'd use aliases when the table name comes up twice and you need to disambiguate,\n    /// e.g. https://github.com/SeaQL/sea-orm/discussions/2133\n    ///\n    /// ```\n    /// use sea_orm::{\n    ///     DbBackend,\n    ///     entity::*,\n    ///     query::*,\n    ///     tests_cfg::{cake, cake_filling},\n    /// };\n    /// use sea_query::Alias;\n    ///\n    /// let cf = \"cf\";\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .join_as(\n    ///             JoinType::LeftJoin,\n    ///             cake_filling::Relation::Cake.def().rev(),\n    ///             cf.clone()\n    ///         )\n    ///         .join(\n    ///             JoinType::LeftJoin,\n    ///             cake_filling::Relation::Filling.def().from_alias(cf)\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     [\n    ///         \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n    ///         \"LEFT JOIN `cake_filling` AS `cf` ON `cake`.`id` = `cf`.`cake_id`\",\n    ///         \"LEFT JOIN `filling` ON `cf`.`filling_id` = `filling`.`id`\",\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    /// ```\n    pub fn from_alias<A>(mut self, alias: A) -> Self\n    where\n        A: IntoIden,\n    {\n        self.from_tbl = self.from_tbl.alias(alias);\n        self\n    }\n\n    /// Set custom join ON condition.\n    ///\n    /// This method takes a closure with two parameters\n    /// denoting the left-hand side and right-hand side table in the join expression.\n    ///\n    /// This replaces the current condition if it is already set.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use sea_orm::{entity::*, query::*, DbBackend, tests_cfg::{cake, cake_filling}};\n    /// use sea_query::{Expr, ExprTrait, IntoCondition};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .join(\n    ///             JoinType::LeftJoin,\n    ///             cake_filling::Relation::Cake\n    ///                 .def()\n    ///                 .rev()\n    ///                 .on_condition(|_left, right| {\n    ///                     Expr::col((right, cake_filling::Column::CakeId))\n    ///                         .gt(10i32)\n    ///                         .into_condition()\n    ///                 })\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     [\n    ///         \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n    ///         \"LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id` AND `cake_filling`.`cake_id` > 10\",\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    /// ```\n    pub fn on_condition<F>(mut self, f: F) -> Self\n    where\n        F: Fn(DynIden, DynIden) -> Condition + 'static + Send + Sync,\n    {\n        self.on_condition = Some(Arc::new(f));\n        self\n    }\n\n    /// Set the condition type of join on expression\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use sea_orm::{entity::*, query::*, DbBackend, tests_cfg::{cake, cake_filling}};\n    /// use sea_query::{Expr, ExprTrait, IntoCondition, ConditionType};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .join(\n    ///             JoinType::LeftJoin,\n    ///             cake_filling::Relation::Cake\n    ///                 .def()\n    ///                 .rev()\n    ///                 .condition_type(ConditionType::Any)\n    ///                 .on_condition(|_left, right| {\n    ///                     Expr::col((right, cake_filling::Column::CakeId))\n    ///                         .gt(10i32)\n    ///                         .into_condition()\n    ///                 })\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     [\n    ///         \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n    ///         \"LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id` OR `cake_filling`.`cake_id` > 10\",\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    /// ```\n    pub fn condition_type(mut self, condition_type: ConditionType) -> Self {\n        self.condition_type = condition_type;\n        self\n    }\n}\n\nimpl<E, R> RelationBuilder<E, R>\nwhere\n    E: EntityTrait,\n    R: EntityTrait,\n{\n    pub(crate) fn new(rel_type: RelationType, from: E, to: R, is_owner: bool) -> Self {\n        Self {\n            entities: PhantomData,\n            rel_type,\n            from_tbl: from.table_ref(),\n            to_tbl: to.table_ref(),\n            from_col: None,\n            to_col: None,\n            is_owner,\n            skip_fk: false,\n            on_delete: None,\n            on_update: None,\n            on_condition: None,\n            fk_name: None,\n            condition_type: ConditionType::All,\n        }\n    }\n\n    pub(crate) fn from_rel(rel_type: RelationType, rel: RelationDef, is_owner: bool) -> Self {\n        Self {\n            entities: PhantomData,\n            rel_type,\n            from_tbl: rel.from_tbl,\n            to_tbl: rel.to_tbl,\n            from_col: Some(rel.from_col),\n            to_col: Some(rel.to_col),\n            is_owner,\n            skip_fk: false,\n            on_delete: None,\n            on_update: None,\n            on_condition: None,\n            fk_name: None,\n            condition_type: ConditionType::All,\n        }\n    }\n\n    /// Build a relationship from an Entity\n    pub fn from<T>(mut self, identifier: T) -> Self\n    where\n        T: IdentityOf<E>,\n    {\n        self.from_col = Some(identifier.identity_of());\n        self\n    }\n\n    /// Build a relationship to an Entity\n    pub fn to<T>(mut self, identifier: T) -> Self\n    where\n        T: IdentityOf<R>,\n    {\n        self.to_col = Some(identifier.identity_of());\n        self\n    }\n\n    /// Force the foreign key to not be created\n    pub fn skip_fk(mut self) -> Self {\n        self.skip_fk = true;\n        self\n    }\n\n    /// An operation to perform on a foreign key when a delete operation occurs\n    pub fn on_delete(mut self, action: ForeignKeyAction) -> Self {\n        self.on_delete = Some(action);\n        self\n    }\n\n    /// An operation to perform on a foreign key when an update operation occurs\n    pub fn on_update(mut self, action: ForeignKeyAction) -> Self {\n        self.on_update = Some(action);\n        self\n    }\n\n    /// Set custom join ON condition.\n    ///\n    /// This method takes a closure with parameters\n    /// denoting the left-hand side and right-hand side table in the join expression.\n    pub fn on_condition<F>(mut self, f: F) -> Self\n    where\n        F: Fn(DynIden, DynIden) -> Condition + 'static + Send + Sync,\n    {\n        self.on_condition = Some(Arc::new(f));\n        self\n    }\n\n    /// Set the name of foreign key constraint\n    pub fn fk_name(mut self, fk_name: &str) -> Self {\n        self.fk_name = Some(fk_name.to_owned());\n        self\n    }\n\n    /// Set the condition type of join on expression\n    pub fn condition_type(mut self, condition_type: ConditionType) -> Self {\n        self.condition_type = condition_type;\n        self\n    }\n}\n\nimpl<E, R> From<RelationBuilder<E, R>> for RelationDef\nwhere\n    E: EntityTrait,\n    R: EntityTrait,\n{\n    fn from(b: RelationBuilder<E, R>) -> Self {\n        RelationDef {\n            rel_type: b.rel_type,\n            from_tbl: b.from_tbl,\n            to_tbl: b.to_tbl,\n            from_col: b.from_col.expect(\"Reference column is not set\"),\n            to_col: b.to_col.expect(\"Owner column is not set\"),\n            is_owner: b.is_owner,\n            skip_fk: b.skip_fk,\n            on_delete: b.on_delete,\n            on_update: b.on_update,\n            on_condition: b.on_condition,\n            fk_name: b.fk_name,\n            condition_type: b.condition_type,\n        }\n    }\n}\n\nmacro_rules! set_foreign_key_stmt {\n    ( $relation: ident, $foreign_key: ident ) => {\n        let from_cols: Vec<String> = $relation\n            .from_col\n            .into_iter()\n            .map(|col| {\n                let col_name = col.to_string();\n                $foreign_key.from_col(col);\n                col_name\n            })\n            .collect();\n        for col in $relation.to_col.into_iter() {\n            $foreign_key.to_col(col);\n        }\n        if let Some(action) = $relation.on_delete {\n            $foreign_key.on_delete(action);\n        }\n        if let Some(action) = $relation.on_update {\n            $foreign_key.on_update(action);\n        }\n        let name = if let Some(name) = $relation.fk_name {\n            name\n        } else {\n            let from_tbl = &$relation.from_tbl.sea_orm_table().clone();\n            format!(\"fk-{}-{}\", from_tbl.to_string(), from_cols.join(\"-\"))\n        };\n        $foreign_key.name(&name);\n    };\n}\n\nimpl From<RelationDef> for ForeignKeyCreateStatement {\n    fn from(relation: RelationDef) -> Self {\n        let mut foreign_key_stmt = Self::new();\n        set_foreign_key_stmt!(relation, foreign_key_stmt);\n        foreign_key_stmt\n            .from_tbl(relation.from_tbl)\n            .to_tbl(relation.to_tbl)\n            .take()\n    }\n}\n\n/// Creates a column definition for example to update a table.\n/// ```\n/// use sea_query::{Alias, IntoIden, MysqlQueryBuilder, TableAlterStatement, IntoTableRef, ConditionType};\n/// use sea_orm::{EnumIter, Iden, Identity, PrimaryKeyTrait, RelationDef, RelationTrait, RelationType};\n///\n/// let relation = RelationDef {\n///     rel_type: RelationType::HasOne,\n///     from_tbl: \"foo\".into_table_ref(),\n///     to_tbl: \"bar\".into_table_ref(),\n///     from_col: Identity::Unary(\"bar_id\".into_iden()),\n///     to_col: Identity::Unary(\"bar_id\".into_iden()),\n///     is_owner: false,\n///     on_delete: None,\n///     on_update: None,\n///     on_condition: None,\n///     fk_name: Some(\"foo-bar\".to_string()),\n///     skip_fk: false,\n///     condition_type: ConditionType::All,\n/// };\n///\n/// let mut alter_table = TableAlterStatement::new()\n///     .table(\"foo\")\n///     .add_foreign_key(&mut relation.into()).take();\n/// assert_eq!(\n///     alter_table.to_string(MysqlQueryBuilder::default()),\n///     \"ALTER TABLE `foo` ADD CONSTRAINT `foo-bar` FOREIGN KEY (`bar_id`) REFERENCES `bar` (`bar_id`)\"\n/// );\n/// ```\nimpl From<RelationDef> for TableForeignKey {\n    fn from(relation: RelationDef) -> Self {\n        let mut foreign_key = Self::new();\n        set_foreign_key_stmt!(relation, foreign_key);\n        foreign_key\n            .from_tbl(relation.from_tbl.sea_orm_table().clone())\n            .to_tbl(relation.to_tbl.sea_orm_table().clone())\n            .take()\n    }\n}\n\nimpl std::hash::Hash for RelationDef {\n    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {\n        self.rel_type.hash(state);\n        self.from_tbl.sea_orm_table().hash(state);\n        self.to_tbl.sea_orm_table().hash(state);\n        self.from_col.hash(state);\n        self.to_col.hash(state);\n        self.is_owner.hash(state);\n    }\n}\n\nimpl PartialEq for RelationDef {\n    fn eq(&self, other: &Self) -> bool {\n        self.rel_type.eq(&other.rel_type)\n            && self.from_tbl.eq(&other.from_tbl)\n            && self.to_tbl.eq(&other.to_tbl)\n            && itertools::equal(self.from_col.iter(), other.from_col.iter())\n            && itertools::equal(self.to_col.iter(), other.to_col.iter())\n            && self.is_owner.eq(&other.is_owner)\n    }\n}\n\nimpl Eq for RelationDef {}\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        RelationBuilder, RelationDef,\n        tests_cfg::{cake, fruit},\n    };\n\n    #[cfg(not(feature = \"sync\"))]\n    #[test]\n    fn assert_relation_traits() {\n        fn assert_send_sync<T: Send + Sync>() {}\n\n        assert_send_sync::<RelationDef>();\n        assert_send_sync::<RelationBuilder<cake::Entity, fruit::Entity>>();\n    }\n}\n"
  },
  {
    "path": "src/entity/with_arrow.rs",
    "content": "use crate::DbErr;\nuse sea_orm_arrow::arrow::array::Array;\nuse sea_query::{ColumnType, Value};\n\npub use sea_orm_arrow::ArrowError;\n\nimpl From<ArrowError> for DbErr {\n    fn from(e: ArrowError) -> Self {\n        DbErr::Type(e.to_string())\n    }\n}\n\npub(crate) fn arrow_array_to_value(\n    array: &dyn Array,\n    col_type: &ColumnType,\n    row: usize,\n) -> Result<Value, DbErr> {\n    sea_orm_arrow::arrow_array_to_value(array, col_type, row).map_err(Into::into)\n}\n\n#[cfg(all(feature = \"with-chrono\", feature = \"with-time\"))]\npub(crate) fn arrow_array_to_value_alt(\n    array: &dyn Array,\n    col_type: &ColumnType,\n    row: usize,\n) -> Result<Option<Value>, DbErr> {\n    sea_orm_arrow::arrow_array_to_value_alt(array, col_type, row).map_err(Into::into)\n}\n\npub(crate) fn is_datetime_column(col_type: &ColumnType) -> bool {\n    sea_orm_arrow::is_datetime_column(col_type)\n}\n\npub(crate) fn option_values_to_arrow_array(\n    values: &[Option<Value>],\n    data_type: &sea_orm_arrow::arrow::datatypes::DataType,\n) -> Result<std::sync::Arc<dyn Array>, DbErr> {\n    sea_orm_arrow::option_values_to_arrow_array(values, data_type).map_err(Into::into)\n}\n"
  },
  {
    "path": "src/error.rs",
    "content": "#[cfg(feature = \"sqlx-dep\")]\npub use sqlx::error::Error as SqlxError;\n\n#[cfg(feature = \"sqlx-mysql\")]\npub use sqlx::mysql::MySqlDatabaseError as SqlxMySqlError;\n\n#[cfg(feature = \"sqlx-postgres\")]\npub use sqlx::postgres::PgDatabaseError as SqlxPostgresError;\n\n#[cfg(feature = \"sqlx-sqlite\")]\npub use sqlx::sqlite::SqliteError as SqlxSqliteError;\n\nuse std::sync::Arc;\nuse thiserror::Error;\n\n/// An error from unsuccessful database operations\n#[derive(Error, Debug, Clone)]\npub enum DbErr {\n    /// This error can happen when the connection pool is fully-utilized\n    #[error(\"Failed to acquire connection from pool: {0}\")]\n    ConnectionAcquire(#[source] ConnAcquireErr),\n    /// Runtime type conversion error\n    #[error(\"Error converting `{from}` into `{into}`: {source}\")]\n    TryIntoErr {\n        /// From type\n        from: &'static str,\n        /// Into type\n        into: &'static str,\n        /// TryError\n        source: Arc<dyn std::error::Error + Send + Sync>,\n    },\n    /// There was a problem with the database connection\n    #[error(\"Connection Error: {0}\")]\n    Conn(#[source] RuntimeErr),\n    /// An operation did not execute successfully\n    #[error(\"Execution Error: {0}\")]\n    Exec(#[source] RuntimeErr),\n    /// An error occurred while performing a query\n    #[error(\"Query Error: {0}\")]\n    Query(#[source] RuntimeErr),\n    /// Type error: the specified type cannot be converted from u64. This is not a runtime error.\n    #[error(\"Type '{0}' cannot be converted from u64\")]\n    ConvertFromU64(&'static str),\n    /// After an insert statement it was impossible to retrieve the last_insert_id\n    #[error(\"Failed to unpack last_insert_id\")]\n    UnpackInsertId,\n    /// When updating, a model should know its primary key to check\n    /// if the record has been correctly updated, otherwise this error will occur\n    #[error(\"Failed to get primary key from model\")]\n    UpdateGetPrimaryKey,\n    /// The record was not found in the database\n    #[error(\"RecordNotFound Error: {0}\")]\n    RecordNotFound(String),\n    /// Thrown by `TryFrom<ActiveModel>`, which assumes all attributes are set/unchanged\n    #[error(\"Attribute {0} is NotSet\")]\n    AttrNotSet(String),\n    /// A custom error\n    #[error(\"Custom Error: {0}\")]\n    Custom(String),\n    /// Error occurred while parsing value as target type\n    #[error(\"Type Error: {0}\")]\n    Type(String),\n    /// Error occurred while parsing json value as target type\n    #[error(\"Json Error: {0}\")]\n    Json(String),\n    /// A migration error\n    #[error(\"Migration Error: {0}\")]\n    Migration(String),\n    /// None of the records are inserted,\n    /// that probably means all of them conflict with existing records in the table\n    #[error(\"None of the records are inserted\")]\n    RecordNotInserted,\n    /// None of the records are updated, that means a WHERE condition has no matches.\n    /// May be the table is empty or the record does not exist\n    #[error(\"None of the records are updated\")]\n    RecordNotUpdated,\n    /// This operation is not supported by the database backend\n    #[error(\"Operation not supported by backend {db}: {ctx}\")]\n    BackendNotSupported {\n        /// Database backend\n        db: &'static str,\n        /// Context\n        ctx: &'static str,\n    },\n    /// (Primary) Key arity mismatch\n    #[error(\"Key arity mismatch: expected {expected}, received {received}\")]\n    KeyArityMismatch {\n        /// Expected value\n        expected: u8,\n        /// Received value\n        received: u8,\n    },\n    /// Primay key not set for update / delete\n    #[error(\"Primay key not set for {ctx}\")]\n    PrimaryKeyNotSet {\n        /// Context\n        ctx: &'static str,\n    },\n    /// Error while running RBAC checks\n    #[error(\"RBAC error: {0}\")]\n    RbacError(String),\n    /// Access denied after running RBAC checks\n    #[error(\"Access denied: cannot perform `{permission}` on `{resource}`\")]\n    AccessDenied {\n        /// The required permission\n        permission: String,\n        /// The requested resource\n        resource: String,\n    },\n    /// Mutex was poisoned by another thread\n    #[error(\"Mutex poisoned\")]\n    MutexPoisonError,\n}\n\n/// An error from trying to get a row from a Model\n#[derive(Debug)]\npub enum TryGetError {\n    /// A database error was encountered as defined in [crate::DbErr]\n    DbErr(DbErr),\n    /// A null value was encountered\n    Null(String),\n}\n\n/// Connection Acquire error\n#[derive(Error, Debug, PartialEq, Eq, Copy, Clone)]\npub enum ConnAcquireErr {\n    /// Connection pool timed out\n    #[error(\"Connection pool timed out\")]\n    Timeout,\n    /// Connection closed\n    #[error(\"Connection closed\")]\n    ConnectionClosed,\n}\n\n/// Runtime error\n#[derive(Error, Debug, Clone)]\npub enum RuntimeErr {\n    /// SQLx Error\n    #[cfg(feature = \"sqlx-dep\")]\n    #[error(\"{0}\")]\n    SqlxError(Arc<sqlx::error::Error>),\n    /// Rusqlite Error\n    #[cfg(feature = \"rusqlite\")]\n    #[error(\"{0}\")]\n    Rusqlite(Arc<crate::driver::rusqlite::RusqliteError>),\n    /// Error generated from within SeaORM\n    #[error(\"{0}\")]\n    Internal(String),\n}\n\nimpl PartialEq for DbErr {\n    fn eq(&self, other: &Self) -> bool {\n        self.to_string() == other.to_string()\n    }\n}\n\nimpl Eq for DbErr {}\n\n/// Error during `impl FromStr for Entity::Column`\n#[derive(Error, Debug)]\n#[error(\"Failed to match \\\"{0}\\\" as Column\")]\npub struct ColumnFromStrErr(pub String);\n\n#[allow(dead_code)]\npub(crate) fn conn_err<T>(s: T) -> DbErr\nwhere\n    T: ToString,\n{\n    DbErr::Conn(RuntimeErr::Internal(s.to_string()))\n}\n\n#[allow(dead_code)]\npub(crate) fn exec_err<T>(s: T) -> DbErr\nwhere\n    T: ToString,\n{\n    DbErr::Exec(RuntimeErr::Internal(s.to_string()))\n}\n\n#[allow(dead_code)]\npub(crate) fn query_err<T>(s: T) -> DbErr\nwhere\n    T: ToString,\n{\n    DbErr::Query(RuntimeErr::Internal(s.to_string()))\n}\n\n#[allow(dead_code)]\npub(crate) fn type_err<T>(s: T) -> DbErr\nwhere\n    T: ToString,\n{\n    DbErr::Type(s.to_string())\n}\n\n#[allow(dead_code)]\npub(crate) fn json_err<T>(s: T) -> DbErr\nwhere\n    T: ToString,\n{\n    DbErr::Json(s.to_string())\n}\n\n/// An error from unsuccessful SQL query\n#[derive(Error, Debug, Clone, PartialEq, Eq)]\n#[non_exhaustive]\npub enum SqlErr {\n    /// Error for duplicate record in unique field or primary key field\n    #[error(\"Unique Constraint Violated: {0}\")]\n    UniqueConstraintViolation(String),\n    /// Error for Foreign key constraint\n    #[error(\"Foreign Key Constraint Violated: {0}\")]\n    ForeignKeyConstraintViolation(String),\n}\n\n#[allow(dead_code)]\nimpl DbErr {\n    /// Convert generic DbErr by sqlx to SqlErr, return none if the error is not any type of SqlErr\n    pub fn sql_err(&self) -> Option<SqlErr> {\n        #[cfg(any(\n            feature = \"sqlx-mysql\",\n            feature = \"sqlx-postgres\",\n            feature = \"sqlx-sqlite\"\n        ))]\n        {\n            use std::ops::Deref;\n            if let DbErr::Exec(RuntimeErr::SqlxError(e)) | DbErr::Query(RuntimeErr::SqlxError(e)) =\n                self\n            {\n                if let sqlx::Error::Database(e) = e.deref() {\n                    let error_code = e.code().unwrap_or_default();\n                    let _error_code_expanded = error_code.deref();\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    if e.try_downcast_ref::<sqlx::mysql::MySqlDatabaseError>()\n                        .is_some()\n                    {\n                        let error_number = e\n                            .try_downcast_ref::<sqlx::mysql::MySqlDatabaseError>()?\n                            .number();\n                        match error_number {\n                            // 1022 Can't write; duplicate key in table '%s'\n                            // 1062 Duplicate entry '%s' for key %d\n                            // 1169 Can't write, because of unique constraint, to table '%s'\n                            // 1586 Duplicate entry '%s' for key '%s'\n                            1022 | 1062 | 1169 | 1586 => {\n                                return Some(SqlErr::UniqueConstraintViolation(e.message().into()));\n                            }\n                            // 1216 Cannot add or update a child row: a foreign key constraint fails\n                            // 1217 Cannot delete or update a parent row: a foreign key constraint fails\n                            // 1451 Cannot delete or update a parent row: a foreign key constraint fails (%s)\n                            // 1452 Cannot add or update a child row: a foreign key constraint fails (%s)\n                            // 1557 Upholding foreign key constraints for table '%s', entry '%s', key %d would lead to a duplicate entry\n                            // 1761 Foreign key constraint for table '%s', record '%s' would lead to a duplicate entry in table '%s', key '%s'\n                            // 1762 Foreign key constraint for table '%s', record '%s' would lead to a duplicate entry in a child table\n                            1216 | 1217 | 1451 | 1452 | 1557 | 1761 | 1762 => {\n                                return Some(SqlErr::ForeignKeyConstraintViolation(\n                                    e.message().into(),\n                                ));\n                            }\n                            _ => return None,\n                        }\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    if e.try_downcast_ref::<sqlx::postgres::PgDatabaseError>()\n                        .is_some()\n                    {\n                        match _error_code_expanded {\n                            \"23505\" => {\n                                return Some(SqlErr::UniqueConstraintViolation(e.message().into()));\n                            }\n                            \"23503\" => {\n                                return Some(SqlErr::ForeignKeyConstraintViolation(\n                                    e.message().into(),\n                                ));\n                            }\n                            _ => return None,\n                        }\n                    }\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    if e.try_downcast_ref::<sqlx::sqlite::SqliteError>().is_some() {\n                        match _error_code_expanded {\n                            // error code 1555 refers to the primary key's unique constraint violation\n                            // error code 2067 refers to the UNIQUE unique constraint violation\n                            \"1555\" | \"2067\" => {\n                                return Some(SqlErr::UniqueConstraintViolation(e.message().into()));\n                            }\n                            \"787\" => {\n                                return Some(SqlErr::ForeignKeyConstraintViolation(\n                                    e.message().into(),\n                                ));\n                            }\n                            _ => return None,\n                        }\n                    }\n                }\n            }\n        }\n        #[cfg(feature = \"rusqlite\")]\n        if let DbErr::Exec(RuntimeErr::Rusqlite(err)) | DbErr::Query(RuntimeErr::Rusqlite(err)) =\n            self\n        {\n            use crate::driver::rusqlite::RusqliteError;\n            use std::ops::Deref;\n\n            if let RusqliteError::SqliteFailure(err, msg) = err.deref() {\n                match err.extended_code {\n                    1555 | 2067 => {\n                        return Some(SqlErr::UniqueConstraintViolation(\n                            msg.to_owned().unwrap_or_else(|| err.to_string()),\n                        ));\n                    }\n                    787 => {\n                        return Some(SqlErr::ForeignKeyConstraintViolation(\n                            msg.to_owned().unwrap_or_else(|| err.to_string()),\n                        ));\n                    }\n                    _ => (),\n                }\n            }\n        }\n        None\n    }\n}\n"
  },
  {
    "path": "src/executor/consolidate.rs",
    "content": "#![allow(clippy::type_complexity)]\nuse crate::{\n    EntityTrait, Iterable, ModelTrait, PrimaryKeyArity, PrimaryKeyToColumn, PrimaryKeyTrait,\n};\nuse sea_query::Value;\nuse std::collections::{HashMap, HashSet};\nuse std::hash::Hash;\n\npub(super) fn consolidate_query_result<L, R>(\n    rows: Vec<(L::Model, Option<R::Model>)>,\n) -> Vec<(L::Model, Vec<R::Model>)>\nwhere\n    L: EntityTrait,\n    R: EntityTrait,\n{\n    // given that ARITY is a compile-time const, I hope the other branches can be eliminated as dead code\n    match <<L::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n        1 => consolidate_query_result_of::<L, R, _>(rows, unit_pk::<L>()),\n        2 => consolidate_query_result_of::<L, R, _>(rows, pair_pk::<L>()),\n        _ => consolidate_query_result_of::<L, R, _>(rows, tuple_pk::<L>()),\n    }\n}\n\npub(super) fn consolidate_query_result_tee<L, M, R>(\n    rows: Vec<(L::Model, Option<M::Model>, Option<R::Model>)>,\n) -> Vec<(L::Model, Vec<M::Model>, Vec<R::Model>)>\nwhere\n    L: EntityTrait,\n    M: EntityTrait,\n    R: EntityTrait,\n{\n    match <<L::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n        1 => consolidate_query_result_of_tee::<L, M, R, _>(rows, unit_pk::<L>()),\n        2 => consolidate_query_result_of_tee::<L, M, R, _>(rows, pair_pk::<L>()),\n        _ => consolidate_query_result_of_tee::<L, M, R, _>(rows, tuple_pk::<L>()),\n    }\n}\n\npub(super) fn consolidate_query_result_chain<L, M, R>(\n    rows: Vec<(L::Model, Option<M::Model>, Option<R::Model>)>,\n) -> Vec<(L::Model, Vec<(M::Model, Vec<R::Model>)>)>\nwhere\n    L: EntityTrait,\n    M: EntityTrait,\n    R: EntityTrait,\n{\n    match <<L::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n        1 => consolidate_query_result_of_chain::<L, M, R, _>(rows, unit_pk::<L>()),\n        2 => consolidate_query_result_of_chain::<L, M, R, _>(rows, pair_pk::<L>()),\n        _ => consolidate_query_result_of_chain::<L, M, R, _>(rows, tuple_pk::<L>()),\n    }\n}\n\nfn retain_unique_models<L>(rows: Vec<L::Model>) -> Vec<L::Model>\nwhere\n    L: EntityTrait,\n{\n    match <<L::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY {\n        1 => retain_unique_models_of::<L, _>(rows, unit_pk::<L>()),\n        2 => retain_unique_models_of::<L, _>(rows, pair_pk::<L>()),\n        _ => retain_unique_models_of::<L, _>(rows, tuple_pk::<L>()),\n    }\n}\n\n// This generic here is that we need to support composite primary key,\n// and that we don't want to penalize the unit pk which is the most common.\ntrait ModelKey<E: EntityTrait> {\n    type Type: Hash + PartialEq + Eq;\n    fn get(&self, model: &E::Model) -> Self::Type;\n}\n\n// This could have been an array of [E::Column; <E::PrimaryKey as PrimaryKeyTrait>::ARITY], but it still doesn't compile\nstruct UnitPk<E: EntityTrait>(E::Column);\nstruct PairPk<E: EntityTrait>(E::Column, E::Column);\nstruct TuplePk<E: EntityTrait>(Vec<E::Column>);\n\n#[allow(clippy::unwrap_used)]\nfn unit_pk<E: EntityTrait>() -> UnitPk<E> {\n    let col = <E::PrimaryKey as Iterable>::iter()\n        .next()\n        .unwrap()\n        .into_column();\n    UnitPk(col)\n}\n\n#[allow(clippy::unwrap_used)]\nfn pair_pk<E: EntityTrait>() -> PairPk<E> {\n    let mut iter = <E::PrimaryKey as Iterable>::iter();\n    let col1 = iter.next().unwrap().into_column();\n    let col2 = iter.next().unwrap().into_column();\n    PairPk(col1, col2)\n}\n\nfn tuple_pk<E: EntityTrait>() -> TuplePk<E> {\n    let cols: Vec<_> = <E::PrimaryKey as Iterable>::iter()\n        .map(|pk| pk.into_column())\n        .collect();\n    TuplePk(cols)\n}\n\nimpl<E: EntityTrait> ModelKey<E> for UnitPk<E> {\n    type Type = Value;\n    fn get(&self, model: &E::Model) -> Self::Type {\n        model.get(self.0)\n    }\n}\n\nimpl<E: EntityTrait> ModelKey<E> for PairPk<E> {\n    type Type = (Value, Value);\n    fn get(&self, model: &E::Model) -> Self::Type {\n        (model.get(self.0), model.get(self.1))\n    }\n}\n\nimpl<E: EntityTrait> ModelKey<E> for TuplePk<E> {\n    type Type = Vec<Value>;\n    fn get(&self, model: &E::Model) -> Self::Type {\n        let mut key = Vec::new();\n        for col in self.0.iter() {\n            key.push(model.get(*col));\n        }\n        key\n    }\n}\n\nfn consolidate_query_result_of<L, R, KEY: ModelKey<L>>(\n    mut rows: Vec<(L::Model, Option<R::Model>)>,\n    model_key: KEY,\n) -> Vec<(L::Model, Vec<R::Model>)>\nwhere\n    L: EntityTrait,\n    R: EntityTrait,\n{\n    // group items by unique key on left model\n    let mut hashmap: HashMap<KEY::Type, Vec<R::Model>> =\n        rows.iter_mut().fold(HashMap::new(), |mut acc, row| {\n            let key = model_key.get(&row.0); // keep left model in place\n            if let Some(value) = row.1.take() {\n                // take ownership of right model\n                if let Some(vec) = acc.get_mut(&key) {\n                    vec.push(value)\n                } else {\n                    acc.insert(key, vec![value]);\n                }\n            } else {\n                acc.entry(key).or_default(); // insert empty vec\n            }\n\n            acc\n        });\n\n    // re-iterate so that we keep the same order\n    rows.into_iter()\n        .filter_map(|(l_model, _)| {\n            // right model is empty here already\n            let l_pk = model_key.get(&l_model);\n            // the first time we encounter a left model, the value is taken\n            // subsequently the key will be empty\n            let r_models = hashmap.remove(&l_pk);\n            r_models.map(|r_models| (l_model, r_models))\n        })\n        .collect()\n}\n\n// this consolidate query result of a T topology\n// where L -> M and L -> R\nfn consolidate_query_result_of_tee<L, M, R, KEY: ModelKey<L>>(\n    mut rows: Vec<(L::Model, Option<M::Model>, Option<R::Model>)>,\n    model_key: KEY,\n) -> Vec<(L::Model, Vec<M::Model>, Vec<R::Model>)>\nwhere\n    L: EntityTrait,\n    M: EntityTrait,\n    R: EntityTrait,\n{\n    struct Slot<M, R> {\n        m: Vec<M>,\n        r: Vec<R>,\n    }\n\n    impl<M, R> Default for Slot<M, R> {\n        fn default() -> Self {\n            Self {\n                m: vec![],\n                r: vec![],\n            }\n        }\n    }\n\n    // group items by unique key on left model\n    let mut hashmap: HashMap<KEY::Type, Slot<M::Model, R::Model>> =\n        rows.iter_mut().fold(HashMap::new(), |mut acc, row| {\n            let key = model_key.get(&row.0);\n            match (row.1.take(), row.2.take()) {\n                (Some(m), Some(r)) => {\n                    if let Some(slot) = acc.get_mut(&key) {\n                        slot.m.push(m);\n                        slot.r.push(r);\n                    } else {\n                        acc.insert(\n                            key,\n                            Slot {\n                                m: vec![m],\n                                r: vec![r],\n                            },\n                        );\n                    }\n                }\n                (Some(m), None) => {\n                    if let Some(slot) = acc.get_mut(&key) {\n                        slot.m.push(m);\n                    } else {\n                        acc.insert(\n                            key,\n                            Slot {\n                                m: vec![m],\n                                r: vec![],\n                            },\n                        );\n                    }\n                }\n                (None, Some(r)) => {\n                    if let Some(slot) = acc.get_mut(&key) {\n                        slot.r.push(r);\n                    } else {\n                        acc.insert(\n                            key,\n                            Slot {\n                                m: vec![],\n                                r: vec![r],\n                            },\n                        );\n                    }\n                }\n                (None, None) => {\n                    acc.entry(key).or_default(); // insert empty vec\n                }\n            }\n\n            acc\n        });\n\n    // re-iterate so that we keep the same order\n    rows.into_iter()\n        .filter_map(|(l_model, _, _)| {\n            let l_pk = model_key.get(&l_model);\n            let mr_models = hashmap.remove(&l_pk);\n            // if both L -> M and L -> R is one to many\n            // it's possible for them to have duplicates\n            mr_models.map(|Slot { m, r }| {\n                (\n                    l_model,\n                    retain_unique_models::<M>(m),\n                    retain_unique_models::<R>(r),\n                )\n            })\n        })\n        .collect()\n}\n\n// this consolidate query result of a chained topology\n// where L -> M and M -> R\nfn consolidate_query_result_of_chain<L, M, R, KEY: ModelKey<L>>(\n    mut rows: Vec<(L::Model, Option<M::Model>, Option<R::Model>)>,\n    model_key: KEY,\n) -> Vec<(L::Model, Vec<(M::Model, Vec<R::Model>)>)>\nwhere\n    L: EntityTrait,\n    M: EntityTrait,\n    R: EntityTrait,\n{\n    // group items by unique key on left model\n    let mut hashmap: HashMap<KEY::Type, Vec<(M::Model, Option<R::Model>)>> =\n        rows.iter_mut().fold(HashMap::new(), |mut acc, row| {\n            let key = model_key.get(&row.0);\n            match (row.1.take(), row.2.take()) {\n                (Some(m), Some(r)) => {\n                    if let Some(slot) = acc.get_mut(&key) {\n                        slot.push((m, Some(r)));\n                    } else {\n                        acc.insert(key, vec![(m, Some(r))]);\n                    }\n                }\n                (Some(m), None) => {\n                    if let Some(slot) = acc.get_mut(&key) {\n                        slot.push((m, None));\n                    } else {\n                        acc.insert(key, vec![(m, None)]);\n                    }\n                }\n                (None, Some(_)) => {\n                    panic!(\n                        \"Impossible to have R when M ({}) -> R ({})\",\n                        M::default().as_str(),\n                        R::default().as_str()\n                    )\n                }\n                (None, None) => {\n                    acc.entry(key).or_default(); // insert empty vec\n                }\n            }\n\n            acc\n        });\n\n    // re-iterate so that we keep the same order\n    rows.into_iter()\n        .filter_map(|(l_model, _, _)| {\n            let l_pk = model_key.get(&l_model);\n            let mr_models = hashmap.remove(&l_pk);\n            mr_models.map(|mr_models| (l_model, consolidate_query_result::<M, R>(mr_models)))\n        })\n        .collect()\n}\n\nfn retain_unique_models_of<L, KEY: ModelKey<L>>(\n    mut rows: Vec<L::Model>,\n    model_key: KEY,\n) -> Vec<L::Model>\nwhere\n    L: EntityTrait,\n{\n    let mut seen = HashSet::new();\n\n    rows.retain(|model| seen.insert(model_key.get(model)));\n\n    rows\n}\n\n/// This is the legacy consolidate algorithm. Kept for reference\n#[allow(dead_code)]\nfn consolidate_query_result_of_ordered_rows<L, R>(\n    rows: Vec<(L::Model, Option<R::Model>)>,\n) -> Vec<(L::Model, Vec<R::Model>)>\nwhere\n    L: EntityTrait,\n    R: EntityTrait,\n{\n    let mut acc: Vec<(L::Model, Vec<R::Model>)> = Vec::new();\n    for (l, r) in rows {\n        if let Some((last_l, last_r)) = acc.last_mut() {\n            let mut same_l = true;\n            for pk_col in <L::PrimaryKey as Iterable>::iter() {\n                let col = pk_col.into_column();\n                let val = l.get(col);\n                let last_val = last_l.get(col);\n                if !val.eq(&last_val) {\n                    same_l = false;\n                    break;\n                }\n            }\n            if same_l {\n                if let Some(r) = r {\n                    last_r.push(r);\n                    continue;\n                }\n            }\n        }\n        let rows = match r {\n            Some(r) => vec![r],\n            None => vec![],\n        };\n        acc.push((l, rows));\n    }\n    acc\n}\n\n#[cfg(test)]\nmod tests {\n    use pretty_assertions::assert_eq;\n\n    fn cake_model(id: i32) -> crate::tests_cfg::cake::Model {\n        let name = match id {\n            1 => \"apple cake\",\n            2 => \"orange cake\",\n            3 => \"fruit cake\",\n            4 => \"chocolate cake\",\n            _ => \"\",\n        }\n        .to_string();\n        crate::tests_cfg::cake::Model { id, name }\n    }\n\n    fn filling_model(id: i32) -> crate::tests_cfg::filling::Model {\n        let name = match id {\n            1 => \"apple sauce\",\n            2 => \"orange jam\",\n            3 => \"fruit salad\",\n            4 => \"chocolate chips\",\n            _ => \"\",\n        }\n        .to_string();\n        crate::tests_cfg::filling::Model {\n            id,\n            name,\n            vendor_id: Some(1),\n            ignored_attr: 0,\n        }\n    }\n\n    fn fruit_model(id: i32) -> crate::tests_cfg::fruit::Model {\n        fruit_model_for(id, None)\n    }\n\n    fn fruit_model_for(id: i32, cake_id: Option<i32>) -> crate::tests_cfg::fruit::Model {\n        let name = match id {\n            1 => \"apple\",\n            2 => \"orange\",\n            3 => \"grape\",\n            4 => \"strawberry\",\n            _ => \"\",\n        }\n        .to_string();\n        crate::tests_cfg::fruit::Model { id, name, cake_id }\n    }\n\n    fn vendor_model(id: i32) -> crate::tests_cfg::vendor::Model {\n        let name = match id {\n            1 => \"Apollo\",\n            2 => \"Benny\",\n            3 => \"Christine\",\n            4 => \"David\",\n            _ => \"\",\n        }\n        .to_string();\n        crate::tests_cfg::vendor::Model { id, name }\n    }\n\n    fn cake_with_fruit(\n        cake_id: i32,\n        fruit_id: i32,\n    ) -> (\n        crate::tests_cfg::cake::Model,\n        crate::tests_cfg::fruit::Model,\n    ) {\n        (\n            cake_model(cake_id),\n            fruit_model_for(fruit_id, Some(cake_id)),\n        )\n    }\n\n    fn cake_and_filling(\n        cake_id: i32,\n        filling_id: i32,\n    ) -> (\n        crate::tests_cfg::cake::Model,\n        crate::tests_cfg::filling::Model,\n    ) {\n        (cake_model(cake_id), filling_model(filling_id))\n    }\n\n    fn cake_and_vendor(\n        cake_id: i32,\n        vendor_id: i32,\n    ) -> (\n        crate::tests_cfg::cake::Model,\n        crate::tests_cfg::vendor::Model,\n    ) {\n        (cake_model(cake_id), vendor_model(vendor_id))\n    }\n\n    #[smol_potat::test]\n    async fn also_related() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase, Statement, Transaction};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_with_fruit(1, 1)]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_also_related(Fruit).all(&db).await?,\n            [(cake_model(1), Some(fruit_model_for(1, Some(1))))]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                []\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn also_related_2() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_with_fruit(1, 1), cake_with_fruit(1, 2)]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_also_related(Fruit).all(&db).await?,\n            [\n                (cake_model(1), Some(fruit_model_for(1, Some(1)))),\n                (cake_model(1), Some(fruit_model_for(2, Some(1))))\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn also_related_3() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_with_fruit(1, 1),\n                cake_with_fruit(1, 2),\n                cake_with_fruit(2, 3),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_also_related(Fruit).all(&db).await?,\n            [\n                (cake_model(1), Some(fruit_model_for(1, Some(1)))),\n                (cake_model(1), Some(fruit_model_for(2, Some(1)))),\n                (cake_model(2), Some(fruit_model_for(3, Some(2))))\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn also_related_4() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_with_fruit(1, 1).into_mock_row(),\n                cake_with_fruit(1, 2).into_mock_row(),\n                cake_with_fruit(2, 3).into_mock_row(),\n                (cake_model(3), None::<fruit::Model>).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_also_related(Fruit).all(&db).await?,\n            [\n                (cake_model(1), Some(fruit_model_for(1, Some(1)))),\n                (cake_model(1), Some(fruit_model_for(2, Some(1)))),\n                (cake_model(2), Some(fruit_model_for(3, Some(2)))),\n                (cake_model(3), None)\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn also_related_many_to_many() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_filling(1, 1).into_mock_row(),\n                cake_and_filling(1, 2).into_mock_row(),\n                cake_and_filling(2, 2).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_also_related(Filling).all(&db).await?,\n            [\n                (cake_model(1), Some(filling_model(1))),\n                (cake_model(1), Some(filling_model(2))),\n                (cake_model(2), Some(filling_model(2))),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn also_related_many_to_many_2() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_filling(1, 1).into_mock_row(),\n                cake_and_filling(1, 2).into_mock_row(),\n                cake_and_filling(2, 2).into_mock_row(),\n                (cake_model(3), None::<filling::Model>).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_also_related(Filling).all(&db).await?,\n            [\n                (cake_model(1), Some(filling_model(1))),\n                (cake_model(1), Some(filling_model(2))),\n                (cake_model(2), Some(filling_model(2))),\n                (cake_model(3), None)\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn with_related() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase, Statement, Transaction};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_with_fruit(1, 1),\n                cake_with_fruit(2, 2),\n                cake_with_fruit(2, 3),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_with_related(Fruit).all(&db).await?,\n            [\n                (cake_model(1), vec![fruit_model_for(1, Some(1))]),\n                (\n                    cake_model(2),\n                    vec![fruit_model_for(2, Some(2)), fruit_model_for(3, Some(2))]\n                )\n            ]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                    r#\"ORDER BY \"cake\".\"id\" ASC\"#\n                ]\n                .join(\" \")\n                .as_str(),\n                []\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn with_related_2() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_with_fruit(1, 1).into_mock_row(),\n                cake_with_fruit(2, 2).into_mock_row(),\n                cake_with_fruit(2, 3).into_mock_row(),\n                cake_with_fruit(2, 4).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_with_related(Fruit).all(&db).await?,\n            [\n                (cake_model(1), vec![fruit_model_for(1, Some(1)),]),\n                (\n                    cake_model(2),\n                    vec![\n                        fruit_model_for(2, Some(2)),\n                        fruit_model_for(3, Some(2)),\n                        fruit_model_for(4, Some(2)),\n                    ]\n                ),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn with_related_empty() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_with_fruit(1, 1).into_mock_row(),\n                cake_with_fruit(2, 2).into_mock_row(),\n                cake_with_fruit(2, 3).into_mock_row(),\n                cake_with_fruit(2, 4).into_mock_row(),\n                (cake_model(3), None::<fruit::Model>).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_with_related(Fruit).all(&db).await?,\n            [\n                (cake_model(1), vec![fruit_model_for(1, Some(1)),]),\n                (\n                    cake_model(2),\n                    vec![\n                        fruit_model_for(2, Some(2)),\n                        fruit_model_for(3, Some(2)),\n                        fruit_model_for(4, Some(2)),\n                    ]\n                ),\n                (cake_model(3), vec![])\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn with_related_many_to_many() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_filling(1, 1).into_mock_row(),\n                cake_and_filling(1, 2).into_mock_row(),\n                cake_and_filling(2, 2).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_with_related(Filling).all(&db).await?,\n            [\n                (cake_model(1), vec![filling_model(1), filling_model(2)]),\n                (cake_model(2), vec![filling_model(2)]),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn with_related_many_to_many_2() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_filling(1, 1).into_mock_row(),\n                cake_and_filling(1, 2).into_mock_row(),\n                cake_and_filling(2, 2).into_mock_row(),\n                (cake_model(3), None::<filling::Model>).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find().find_with_related(Filling).all(&db).await?,\n            [\n                (cake_model(1), vec![filling_model(1), filling_model(2)]),\n                (cake_model(2), vec![filling_model(2)]),\n                (cake_model(3), vec![])\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn also_linked_base() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase, Statement, Transaction};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_and_vendor(1, 1)]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)\n                .await?,\n            [(cake_model(1), Some(vendor_model(1)))]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"r2\".\"id\" AS \"B_id\", \"r2\".\"name\" AS \"B_name\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"cake_filling\" AS \"r0\" ON \"cake\".\"id\" = \"r0\".\"cake_id\"\"#,\n                    r#\"LEFT JOIN \"filling\" AS \"r1\" ON \"r0\".\"filling_id\" = \"r1\".\"id\"\"#,\n                    r#\"LEFT JOIN \"vendor\" AS \"r2\" ON \"r1\".\"vendor_id\" = \"r2\".\"id\"\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                []\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn also_linked_same_cake() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1),\n                cake_and_vendor(1, 2),\n                cake_and_vendor(2, 3),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)\n                .await?,\n            [\n                (cake_model(1), Some(vendor_model(1))),\n                (cake_model(1), Some(vendor_model(2))),\n                (cake_model(2), Some(vendor_model(3)))\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn also_linked_same_vendor() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(2, 1).into_mock_row(),\n                cake_and_vendor(3, 2).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)\n                .await?,\n            [\n                (cake_model(1), Some(vendor_model(1))),\n                (cake_model(2), Some(vendor_model(1))),\n                (cake_model(3), Some(vendor_model(2))),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn also_linked_many_to_many() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(1, 2).into_mock_row(),\n                cake_and_vendor(1, 3).into_mock_row(),\n                cake_and_vendor(2, 1).into_mock_row(),\n                cake_and_vendor(2, 2).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)\n                .await?,\n            [\n                (cake_model(1), Some(vendor_model(1))),\n                (cake_model(1), Some(vendor_model(2))),\n                (cake_model(1), Some(vendor_model(3))),\n                (cake_model(2), Some(vendor_model(1))),\n                (cake_model(2), Some(vendor_model(2))),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn also_linked_empty() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(2, 2).into_mock_row(),\n                cake_and_vendor(3, 3).into_mock_row(),\n                (cake_model(4), None::<vendor::Model>).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)\n                .await?,\n            [\n                (cake_model(1), Some(vendor_model(1))),\n                (cake_model(2), Some(vendor_model(2))),\n                (cake_model(3), Some(vendor_model(3))),\n                (cake_model(4), None)\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn with_linked_base() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, MockDatabase, Statement, Transaction};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1),\n                cake_and_vendor(2, 2),\n                cake_and_vendor(2, 3),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_with_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)\n                .await?,\n            [\n                (cake_model(1), vec![vendor_model(1)]),\n                (cake_model(2), vec![vendor_model(2), vendor_model(3)])\n            ]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"r2\".\"id\" AS \"B_id\", \"r2\".\"name\" AS \"B_name\" FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"cake_filling\" AS \"r0\" ON \"cake\".\"id\" = \"r0\".\"cake_id\"\"#,\n                    r#\"LEFT JOIN \"filling\" AS \"r1\" ON \"r0\".\"filling_id\" = \"r1\".\"id\"\"#,\n                    r#\"LEFT JOIN \"vendor\" AS \"r2\" ON \"r1\".\"vendor_id\" = \"r2\".\"id\"\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                []\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn with_linked_same_vendor() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(2, 2).into_mock_row(),\n                cake_and_vendor(3, 2).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_with_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)\n                .await?,\n            [\n                (cake_model(1), vec![vendor_model(1)]),\n                (cake_model(2), vec![vendor_model(2)]),\n                (cake_model(3), vec![vendor_model(2)])\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn with_linked_empty() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(2, 1).into_mock_row(),\n                cake_and_vendor(2, 2).into_mock_row(),\n                (cake_model(3), None::<vendor::Model>).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_with_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)\n                .await?,\n            [\n                (cake_model(1), vec![vendor_model(1)]),\n                (cake_model(2), vec![vendor_model(1), vendor_model(2)]),\n                (cake_model(3), vec![])\n            ]\n        );\n\n        Ok(())\n    }\n\n    // normally would not happen\n    #[smol_potat::test]\n    async fn with_linked_repeated() -> Result<(), crate::DbErr> {\n        use crate::tests_cfg::*;\n        use crate::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(1, 1).into_mock_row(),\n                cake_and_vendor(2, 1).into_mock_row(),\n                cake_and_vendor(2, 2).into_mock_row(),\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Cake::find()\n                .find_with_linked(entity_linked::CakeToFillingVendor)\n                .all(&db)\n                .await?,\n            [\n                (cake_model(1), vec![vendor_model(1), vendor_model(1)]),\n                (cake_model(2), vec![vendor_model(1), vendor_model(2)]),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[test]\n    fn test_retain_unique_models() {\n        use crate::tests_cfg::Cake;\n        assert_eq!(\n            super::retain_unique_models::<Cake>(vec![\n                cake_model(1),\n                cake_model(1),\n                cake_model(2),\n                cake_model(2),\n                cake_model(3),\n            ]),\n            [cake_model(1), cake_model(2), cake_model(3)]\n        );\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_consolidate_tee() {\n        use crate::tests_cfg::{Cake, Filling, Fruit};\n\n        assert_eq!(\n            super::consolidate_query_result_tee::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n            ]),\n            vec![(cake_model(1), vec![fruit_model(1)], vec![filling_model(1)])]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_tee::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), None),\n            ]),\n            vec![(cake_model(1), vec![fruit_model(1)], vec![])]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_tee::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), None, Some(filling_model(1))),\n            ]),\n            vec![(cake_model(1), vec![], vec![filling_model(1)])]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_tee::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![fruit_model(1)],\n                vec![filling_model(1), filling_model(2)]\n            )]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_tee::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(3))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(3))),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![fruit_model(1), fruit_model(2)],\n                vec![filling_model(1), filling_model(2), filling_model(3)]\n            )]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_tee::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(3))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(3))),\n                (cake_model(2), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(2), Some(fruit_model(2)), Some(filling_model(2))),\n                (cake_model(3), Some(fruit_model(3)), None),\n                (cake_model(4), None, None),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![fruit_model(1), fruit_model(2)],\n                vec![filling_model(1), filling_model(2), filling_model(3)]\n            ), (\n                cake_model(2),\n                vec![fruit_model(1), fruit_model(2)],\n                vec![filling_model(2)]\n            ), (\n                cake_model(3),\n                vec![fruit_model(3)],\n                vec![]\n            ), (\n                cake_model(4),\n                vec![],\n                vec![]\n            )]\n        );\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_consolidate_chain() {\n        use crate::tests_cfg::{Cake, Filling, Fruit};\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n            ]),\n            vec![(cake_model(1), vec![(fruit_model(1), vec![filling_model(1)])])]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), None),\n            ]),\n            vec![(cake_model(1), vec![(fruit_model(1), vec![])])]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), None, None),\n            ]),\n            vec![(cake_model(1), vec![])]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![(fruit_model(1), vec![filling_model(1), filling_model(2)])]\n            )]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(3))),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![(fruit_model(1), vec![filling_model(1), filling_model(2), filling_model(3)])]\n            )]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(3))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(3))),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![\n                    (fruit_model(1), vec![filling_model(1), filling_model(2), filling_model(3)]),\n                    (fruit_model(2), vec![filling_model(2), filling_model(3)]),\n                ]\n            )]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(3))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(3))),\n                (cake_model(2), Some(fruit_model(3)), Some(filling_model(4))),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![\n                    (fruit_model(1), vec![filling_model(1), filling_model(2), filling_model(3)]),\n                    (fruit_model(2), vec![filling_model(2), filling_model(3)]),\n                ]\n            ), (\n                cake_model(2),\n                vec![(fruit_model(3), vec![filling_model(4)])]\n            )]\n        );\n\n        assert_eq!(\n            super::consolidate_query_result_chain::<Cake, Fruit, Filling>(vec![\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(1))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(1)), Some(filling_model(3))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(2))),\n                (cake_model(1), Some(fruit_model(2)), Some(filling_model(3))),\n                (cake_model(2), Some(fruit_model(3)), Some(filling_model(3))),\n                (cake_model(2), Some(fruit_model(3)), Some(filling_model(4))),\n                (cake_model(3), Some(fruit_model(4)), None),\n                (cake_model(4), None, None),\n            ]),\n            vec![(\n                cake_model(1),\n                vec![\n                    (fruit_model(1), vec![filling_model(1), filling_model(2), filling_model(3)]),\n                    (fruit_model(2), vec![filling_model(2), filling_model(3)]),\n                ]\n            ), (\n                cake_model(2),\n                vec![(fruit_model(3), vec![filling_model(3), filling_model(4)])]\n            ), (\n                cake_model(3),\n                vec![(fruit_model(4), vec![])]\n            ), (\n                cake_model(4),\n                vec![]\n            )]\n        );\n    }\n}\n"
  },
  {
    "path": "src/executor/cursor.rs",
    "content": "use crate::{\n    ConnectionTrait, DbErr, EntityTrait, FromQueryResult, Identity, IdentityOf, IntoIdentity,\n    PartialModelTrait, PrimaryKeyToColumn, QuerySelect, Select, SelectModel, SelectThree,\n    SelectThreeModel, SelectTwo, SelectTwoModel, SelectorTrait, Topology,\n};\nuse sea_query::{\n    Condition, DynIden, Expr, ExprTrait, IntoValueTuple, Order, SeaRc, SelectStatement, SimpleExpr,\n    Value, ValueTuple,\n};\nuse std::marker::PhantomData;\nuse strum::IntoEnumIterator as Iterable;\n\n#[cfg(feature = \"with-json\")]\nuse crate::JsonValue;\n\n/// Cursor pagination\n#[derive(Debug, Clone)]\npub struct Cursor<S>\nwhere\n    S: SelectorTrait,\n{\n    query: SelectStatement,\n    table: DynIden,\n    order_columns: Identity,\n    secondary_order_by: Vec<(DynIden, Identity)>,\n    first: Option<u64>,\n    last: Option<u64>,\n    before: Option<ValueTuple>,\n    after: Option<ValueTuple>,\n    sort_asc: bool,\n    is_result_reversed: bool,\n    phantom: PhantomData<S>,\n}\n\nimpl<S> Cursor<S>\nwhere\n    S: SelectorTrait,\n{\n    pub(crate) fn new<C>(query: SelectStatement, table: DynIden, order_columns: C) -> Self\n    where\n        C: IntoIdentity,\n    {\n        Self {\n            query,\n            table,\n            order_columns: order_columns.into_identity(),\n            secondary_order_by: Default::default(),\n            last: None,\n            first: None,\n            after: None,\n            before: None,\n            sort_asc: true,\n            is_result_reversed: false,\n            phantom: PhantomData,\n        }\n    }\n\n    /// Filter paginated result with corresponding column less than the input value\n    pub fn before<V>(&mut self, values: V) -> &mut Self\n    where\n        V: IntoValueTuple,\n    {\n        self.before = Some(values.into_value_tuple());\n        self\n    }\n\n    /// Filter paginated result with corresponding column greater than the input value\n    pub fn after<V>(&mut self, values: V) -> &mut Self\n    where\n        V: IntoValueTuple,\n    {\n        self.after = Some(values.into_value_tuple());\n        self\n    }\n\n    fn apply_filters(&mut self) -> Result<&mut Self, DbErr> {\n        if let Some(values) = self.after.clone() {\n            if self.order_columns.arity() != values.arity() {\n                return Err(DbErr::KeyArityMismatch {\n                    expected: self.order_columns.arity() as u8,\n                    received: values.arity() as u8,\n                });\n            }\n            let condition = self.apply_filter(values, |c, v| {\n                let exp = Expr::col((self.table.clone(), c.clone()));\n                if self.sort_asc { exp.gt(v) } else { exp.lt(v) }\n            });\n            self.query.cond_where(condition);\n        }\n\n        if let Some(values) = self.before.clone() {\n            if self.order_columns.arity() != values.arity() {\n                return Err(DbErr::KeyArityMismatch {\n                    expected: self.order_columns.arity() as u8,\n                    received: values.arity() as u8,\n                });\n            }\n            let condition = self.apply_filter(values, |c, v| {\n                let exp = Expr::col((self.table.clone(), c.clone()));\n                if self.sort_asc { exp.lt(v) } else { exp.gt(v) }\n            });\n            self.query.cond_where(condition);\n        }\n\n        Ok(self)\n    }\n\n    fn apply_filter<F>(&self, values: ValueTuple, f: F) -> Condition\n    where\n        F: Fn(&DynIden, Value) -> SimpleExpr,\n    {\n        match (&self.order_columns, values) {\n            (Identity::Unary(c1), ValueTuple::One(v1)) => Condition::all().add(f(c1, v1)),\n            (Identity::Binary(c1, c2), ValueTuple::Two(v1, v2)) => Condition::any()\n                .add(\n                    Condition::all()\n                        .add(Expr::col((self.table.clone(), c1.clone())).eq(v1.clone()))\n                        .add(f(c2, v2)),\n                )\n                .add(f(c1, v1)),\n            (Identity::Ternary(c1, c2, c3), ValueTuple::Three(v1, v2, v3)) => Condition::any()\n                .add(\n                    Condition::all()\n                        .add(Expr::col((self.table.clone(), c1.clone())).eq(v1.clone()))\n                        .add(Expr::col((self.table.clone(), c2.clone())).eq(v2.clone()))\n                        .add(f(c3, v3)),\n                )\n                .add(\n                    Condition::all()\n                        .add(Expr::col((self.table.clone(), c1.clone())).eq(v1.clone()))\n                        .add(f(c2, v2)),\n                )\n                .add(f(c1, v1)),\n            (Identity::Many(col_vec), ValueTuple::Many(val_vec))\n                if col_vec.len() == val_vec.len() =>\n            {\n                // The length of `col_vec` and `val_vec` should be equal and is denoted by \"n\".\n                //\n                // The elements of `col_vec` and `val_vec` are denoted by:\n                //   - `col_vec`: \"col_1\", \"col_2\", ..., \"col_n-1\", \"col_n\"\n                //   - `val_vec`: \"val_1\", \"val_2\", ..., \"val_n-1\", \"val_n\"\n                //\n                // The general form of the where condition should have \"n\" number of inner-AND-condition chained by an outer-OR-condition.\n                // The \"n\"-th inner-AND-condition should have exactly \"n\" number of column value expressions,\n                // to construct the expression we take the first \"n\" number of column and value from the respected vector.\n                //   - if it's not the last element, then we construct a \"col_1 = val_1\" equal expression\n                //   - otherwise, for the last element, we should construct a \"col_n > val_n\" greater than or \"col_n < val_n\" less than expression.\n                // i.e.\n                // WHERE\n                //   (col_1 = val_1 AND col_2 = val_2 AND ... AND col_n > val_n)\n                //   OR (col_1 = val_1 AND col_2 = val_2 AND ... AND col_n-1 > val_n-1)\n                //   OR (col_1 = val_1 AND col_2 = val_2 AND ... AND col_n-2 > val_n-2)\n                //   OR ...\n                //   OR (col_1 = val_1 AND col_2 > val_2)\n                //   OR (col_1 > val_1)\n\n                // Counting from 1 to \"n\" (inclusive) but in reverse, i.e. n, n-1, ..., 2, 1\n                (1..=col_vec.len())\n                    .rev()\n                    .fold(Condition::any(), |cond_any, n| {\n                        // Construct the inner-AND-condition\n                        let inner_cond_all =\n                            // Take the first \"n\" elements from the column and value vector respectively\n                            col_vec.iter().zip(val_vec.iter()).enumerate().take(n).fold(\n                                Condition::all(),\n                                |inner_cond_all, (i, (col, val))| {\n                                    let val = val.clone();\n                                    // Construct a equal expression,\n                                    // except for the last one being greater than or less than expression\n                                    let expr = if i != (n - 1) {\n                                        Expr::col((self.table.clone(), col.clone()))\n                                            .eq(val)\n                                    } else {\n                                        f(col, val)\n                                    };\n                                    // Chain it with AND operator\n                                    inner_cond_all.add(expr)\n                                },\n                            );\n                        // Chain inner-AND-condition with OR operator\n                        cond_any.add(inner_cond_all)\n                    })\n            }\n            _ => unreachable!(\"checked by caller\"),\n        }\n    }\n\n    /// Use ascending sort order\n    pub fn asc(&mut self) -> &mut Self {\n        self.sort_asc = true;\n        self\n    }\n\n    /// Use descending sort order\n    pub fn desc(&mut self) -> &mut Self {\n        self.sort_asc = false;\n        self\n    }\n\n    /// Limit result set to only first N rows in ascending order of the order by column\n    pub fn first(&mut self, num_rows: u64) -> &mut Self {\n        self.last = None;\n        self.first = Some(num_rows);\n        self\n    }\n\n    /// Limit result set to only last N rows in ascending order of the order by column\n    pub fn last(&mut self, num_rows: u64) -> &mut Self {\n        self.first = None;\n        self.last = Some(num_rows);\n        self\n    }\n\n    fn resolve_sort_order(&mut self) -> Order {\n        let should_reverse_order = self.last.is_some();\n        self.is_result_reversed = should_reverse_order;\n\n        if (self.sort_asc && !should_reverse_order) || (!self.sort_asc && should_reverse_order) {\n            Order::Asc\n        } else {\n            Order::Desc\n        }\n    }\n\n    fn apply_limit(&mut self) -> &mut Self {\n        if let Some(num_rows) = self.first {\n            self.query.limit(num_rows);\n        } else if let Some(num_rows) = self.last {\n            self.query.limit(num_rows);\n        }\n\n        self\n    }\n\n    fn apply_order_by(&mut self) -> &mut Self {\n        self.query.clear_order_by();\n        let ord = self.resolve_sort_order();\n\n        let query = &mut self.query;\n        let order = |query: &mut SelectStatement, col: &DynIden| {\n            query.order_by((self.table.clone(), col.clone()), ord.clone());\n        };\n        match &self.order_columns {\n            Identity::Unary(c1) => {\n                order(query, c1);\n            }\n            Identity::Binary(c1, c2) => {\n                order(query, c1);\n                order(query, c2);\n            }\n            Identity::Ternary(c1, c2, c3) => {\n                order(query, c1);\n                order(query, c2);\n                order(query, c3);\n            }\n            Identity::Many(vec) => {\n                for col in vec.iter() {\n                    order(query, col);\n                }\n            }\n        }\n\n        for (tbl, col) in self.secondary_order_by.iter().cloned() {\n            if let Identity::Unary(c1) = col {\n                query.order_by((tbl, c1), ord.clone());\n            }\n        }\n\n        self\n    }\n\n    /// Fetch the paginated result\n    pub async fn all<C>(&mut self, db: &C) -> Result<Vec<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.apply_limit();\n        self.apply_order_by();\n        self.apply_filters()?;\n\n        let rows = db.query_all(&self.query).await?;\n        let mut buffer = Vec::with_capacity(rows.len());\n        for row in rows.into_iter() {\n            buffer.push(S::from_raw_query_result(row)?);\n        }\n        if self.is_result_reversed {\n            buffer.reverse()\n        }\n        Ok(buffer)\n    }\n\n    /// Construct a [Cursor] that fetch any custom struct\n    pub fn into_model<M>(self) -> Cursor<SelectModel<M>>\n    where\n        M: FromQueryResult,\n    {\n        Cursor {\n            query: self.query,\n            table: self.table,\n            order_columns: self.order_columns,\n            secondary_order_by: self.secondary_order_by,\n            last: self.last,\n            first: self.first,\n            after: self.after,\n            before: self.before,\n            sort_asc: self.sort_asc,\n            is_result_reversed: self.is_result_reversed,\n            phantom: PhantomData,\n        }\n    }\n\n    /// Return a [Selector] from `Self` that wraps a [SelectModel] with a [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M>(self) -> Cursor<SelectModel<M>>\n    where\n        M: PartialModelTrait,\n    {\n        M::select_cols(QuerySelect::select_only(self)).into_model::<M>()\n    }\n\n    /// Construct a [Cursor] that fetch JSON value\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(self) -> Cursor<SelectModel<JsonValue>> {\n        Cursor {\n            query: self.query,\n            table: self.table,\n            order_columns: self.order_columns,\n            secondary_order_by: self.secondary_order_by,\n            last: self.last,\n            first: self.first,\n            after: self.after,\n            before: self.before,\n            sort_asc: self.sort_asc,\n            is_result_reversed: self.is_result_reversed,\n            phantom: PhantomData,\n        }\n    }\n\n    /// Set the cursor ordering for another table when dealing with SelectTwo\n    pub fn set_secondary_order_by(&mut self, tbl_col: Vec<(DynIden, Identity)>) -> &mut Self {\n        self.secondary_order_by = tbl_col;\n        self\n    }\n}\n\nimpl<S> QuerySelect for Cursor<S>\nwhere\n    S: SelectorTrait,\n{\n    type QueryStatement = SelectStatement;\n\n    fn query(&mut self) -> &mut SelectStatement {\n        &mut self.query\n    }\n}\n\n/// A trait for any type that can be turn into a cursor\npub trait CursorTrait {\n    /// Select operation\n    type Selector: SelectorTrait + Send + Sync;\n}\n\nimpl<E, M> CursorTrait for Select<E>\nwhere\n    E: EntityTrait<Model = M>,\n    M: FromQueryResult + Sized + Send + Sync,\n{\n    type Selector = SelectModel<M>;\n}\n\nimpl<E, M> Select<E>\nwhere\n    E: EntityTrait<Model = M>,\n    M: FromQueryResult + Sized + Send + Sync,\n{\n    /// Convert into a cursor\n    pub fn cursor_by<C>(self, order_columns: C) -> Cursor<SelectModel<M>>\n    where\n        C: IntoIdentity,\n    {\n        Cursor::new(self.query, SeaRc::new(E::default()), order_columns)\n    }\n}\n\nimpl<E, F, M, N> CursorTrait for SelectTwo<E, F>\nwhere\n    E: EntityTrait<Model = M>,\n    F: EntityTrait<Model = N>,\n    M: FromQueryResult + Sized + Send + Sync,\n    N: FromQueryResult + Sized + Send + Sync,\n{\n    type Selector = SelectTwoModel<M, N>;\n}\n\nimpl<E, F, G, M, N, O, TOP> CursorTrait for SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait<Model = M>,\n    F: EntityTrait<Model = N>,\n    G: EntityTrait<Model = O>,\n    M: FromQueryResult + Sized + Send + Sync,\n    N: FromQueryResult + Sized + Send + Sync,\n    O: FromQueryResult + Sized + Send + Sync,\n    TOP: Topology,\n{\n    type Selector = SelectThreeModel<M, N, O>;\n}\n\nimpl<E, F, M, N> SelectTwo<E, F>\nwhere\n    E: EntityTrait<Model = M>,\n    F: EntityTrait<Model = N>,\n    M: FromQueryResult + Sized + Send + Sync,\n    N: FromQueryResult + Sized + Send + Sync,\n{\n    /// Convert into a cursor using column of first entity\n    pub fn cursor_by<C>(self, order_columns: C) -> Cursor<SelectTwoModel<M, N>>\n    where\n        C: IdentityOf<E>,\n    {\n        let primary_keys: Vec<(DynIden, Identity)> = <F::PrimaryKey as Iterable>::iter()\n            .map(|pk| {\n                (\n                    SeaRc::new(F::default()),\n                    Identity::Unary(SeaRc::new(pk.into_column())),\n                )\n            })\n            .collect();\n        let mut cursor = Cursor::new(\n            self.query,\n            SeaRc::new(E::default()),\n            order_columns.identity_of(),\n        );\n        cursor.set_secondary_order_by(primary_keys);\n        cursor\n    }\n\n    /// Convert into a cursor using column of second entity\n    pub fn cursor_by_other<C>(self, order_columns: C) -> Cursor<SelectTwoModel<M, N>>\n    where\n        C: IdentityOf<F>,\n    {\n        let primary_keys: Vec<(DynIden, Identity)> = <E::PrimaryKey as Iterable>::iter()\n            .map(|pk| {\n                (\n                    SeaRc::new(E::default()),\n                    Identity::Unary(SeaRc::new(pk.into_column())),\n                )\n            })\n            .collect();\n        let mut cursor = Cursor::new(\n            self.query,\n            SeaRc::new(F::default()),\n            order_columns.identity_of(),\n        );\n        cursor.set_secondary_order_by(primary_keys);\n        cursor\n    }\n}\n\nimpl<E, F, G, M, N, O, TOP> SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait<Model = M>,\n    F: EntityTrait<Model = N>,\n    G: EntityTrait<Model = O>,\n    M: FromQueryResult + Sized + Send + Sync,\n    N: FromQueryResult + Sized + Send + Sync,\n    O: FromQueryResult + Sized + Send + Sync,\n    TOP: Topology,\n{\n    /// Convert into a cursor using column of first entity\n    pub fn cursor_by<C>(self, order_columns: C) -> Cursor<SelectThreeModel<M, N, O>>\n    where\n        C: IdentityOf<E>,\n    {\n        let mut cursor = Cursor::new(\n            self.query,\n            SeaRc::new(E::default()),\n            order_columns.identity_of(),\n        );\n        {\n            let primary_keys: Vec<(DynIden, Identity)> = <F::PrimaryKey as Iterable>::iter()\n                .map(|pk| {\n                    (\n                        SeaRc::new(F::default()),\n                        Identity::Unary(SeaRc::new(pk.into_column())),\n                    )\n                })\n                .collect();\n            cursor.set_secondary_order_by(primary_keys);\n        }\n        {\n            let primary_keys: Vec<(DynIden, Identity)> = <G::PrimaryKey as Iterable>::iter()\n                .map(|pk| {\n                    (\n                        SeaRc::new(G::default()),\n                        Identity::Unary(SeaRc::new(pk.into_column())),\n                    )\n                })\n                .collect();\n            cursor.set_secondary_order_by(primary_keys);\n        }\n        cursor\n    }\n}\n\n#[cfg(test)]\n#[cfg(feature = \"mock\")]\nmod tests {\n    use crate::entity::prelude::*;\n    use crate::tests_cfg::*;\n    use crate::{DbBackend, MockDatabase, Statement, Transaction};\n    use pretty_assertions::assert_eq;\n\n    #[smol_potat::test]\n    async fn first_2_before_10() -> Result<(), DbErr> {\n        use fruit::*;\n\n        let models = [\n            Model {\n                id: 1,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            },\n            Model {\n                id: 2,\n                name: \"Raspberry\".into(),\n                cake_id: Some(1),\n            },\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            Entity::find()\n                .cursor_by(Column::Id)\n                .before(10)\n                .first(2)\n                .all(&db)\n                .await?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\"\"#,\n                    r#\"FROM \"fruit\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" < $1\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" ASC\"#,\n                    r#\"LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn last_2_after_10_desc() -> Result<(), DbErr> {\n        use fruit::*;\n\n        let mut models = [\n            Model {\n                id: 1,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            },\n            Model {\n                id: 2,\n                name: \"Raspberry\".into(),\n                cake_id: Some(1),\n            },\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        models.reverse();\n\n        assert_eq!(\n            Entity::find()\n                .cursor_by(Column::Id)\n                .after(10)\n                .last(2)\n                .desc()\n                .all(&db)\n                .await?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\"\"#,\n                    r#\"FROM \"fruit\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" < $1\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" ASC\"#,\n                    r#\"LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn first_2_before_10_also_related_select() -> Result<(), DbErr> {\n        let models = [\n            (\n                cake::Model {\n                    id: 1,\n                    name: \"Blueberry Cheese Cake\".into(),\n                },\n                Some(fruit::Model {\n                    id: 9,\n                    name: \"Blueberry\".into(),\n                    cake_id: Some(1),\n                }),\n            ),\n            (\n                cake::Model {\n                    id: 2,\n                    name: \"Raspberry Cheese Cake\".into(),\n                },\n                Some(fruit::Model {\n                    id: 10,\n                    name: \"Raspberry\".into(),\n                    cake_id: Some(1),\n                }),\n            ),\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_related(Fruit)\n                .cursor_by(cake::Column::Id)\n                .before(10)\n                .first(2)\n                .all(&db)\n                .await?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                    r#\"WHERE \"cake\".\"id\" < $1\"#,\n                    r#\"ORDER BY \"cake\".\"id\" ASC, \"fruit\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn last_2_after_10_also_related_select_desc() -> Result<(), DbErr> {\n        let mut models = [\n            (\n                cake::Model {\n                    id: 2,\n                    name: \"Raspberry Cheese Cake\".into(),\n                },\n                Some(fruit::Model {\n                    id: 10,\n                    name: \"Raspberry\".into(),\n                    cake_id: Some(1),\n                }),\n            ),\n            (\n                cake::Model {\n                    id: 1,\n                    name: \"Blueberry Cheese Cake\".into(),\n                },\n                Some(fruit::Model {\n                    id: 9,\n                    name: \"Blueberry\".into(),\n                    cake_id: Some(1),\n                }),\n            ),\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        models.reverse();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_related(Fruit)\n                .cursor_by(cake::Column::Id)\n                .after(10)\n                .last(2)\n                .desc()\n                .all(&db)\n                .await?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                    r#\"WHERE \"cake\".\"id\" < $1\"#,\n                    r#\"ORDER BY \"cake\".\"id\" ASC, \"fruit\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn first_2_before_10_also_related_select_cursor_other() -> Result<(), DbErr> {\n        let models = [(\n            cake::Model {\n                id: 1,\n                name: \"Blueberry Cheese Cake\".into(),\n            },\n            Some(fruit::Model {\n                id: 9,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            }),\n        )];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_related(Fruit)\n                .cursor_by_other(fruit::Column::Id)\n                .before(10)\n                .first(2)\n                .all(&db)\n                .await?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" < $1\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" ASC, \"cake\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn last_2_after_10_also_related_select_cursor_other_desc() -> Result<(), DbErr> {\n        let models = [(\n            cake::Model {\n                id: 1,\n                name: \"Blueberry Cheese Cake\".into(),\n            },\n            Some(fruit::Model {\n                id: 9,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            }),\n        )];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_related(Fruit)\n                .cursor_by_other(fruit::Column::Id)\n                .after(10)\n                .last(2)\n                .desc()\n                .all(&db)\n                .await?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"fruit\".\"id\" AS \"B_id\", \"fruit\".\"name\" AS \"B_name\", \"fruit\".\"cake_id\" AS \"B_cake_id\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" < $1\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" ASC, \"cake\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn first_2_before_10_also_linked_select() -> Result<(), DbErr> {\n        let models = [\n            (\n                cake::Model {\n                    id: 1,\n                    name: \"Blueberry Cheese Cake\".into(),\n                },\n                Some(vendor::Model {\n                    id: 9,\n                    name: \"Blueberry\".into(),\n                }),\n            ),\n            (\n                cake::Model {\n                    id: 2,\n                    name: \"Raspberry Cheese Cake\".into(),\n                },\n                Some(vendor::Model {\n                    id: 10,\n                    name: \"Raspberry\".into(),\n                }),\n            ),\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .cursor_by(cake::Column::Id)\n                .before(10)\n                .first(2)\n                .all(&db)\n                .await?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"r2\".\"id\" AS \"B_id\", \"r2\".\"name\" AS \"B_name\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"cake_filling\" AS \"r0\" ON \"cake\".\"id\" = \"r0\".\"cake_id\"\"#,\n                    r#\"LEFT JOIN \"filling\" AS \"r1\" ON \"r0\".\"filling_id\" = \"r1\".\"id\"\"#,\n                    r#\"LEFT JOIN \"vendor\" AS \"r2\" ON \"r1\".\"vendor_id\" = \"r2\".\"id\"\"#,\n                    r#\"WHERE \"cake\".\"id\" < $1 ORDER BY \"cake\".\"id\" ASC, \"vendor\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn last_2_after_10_also_linked_select_desc() -> Result<(), DbErr> {\n        let mut models = [\n            (\n                cake::Model {\n                    id: 2,\n                    name: \"Raspberry Cheese Cake\".into(),\n                },\n                Some(vendor::Model {\n                    id: 10,\n                    name: \"Raspberry\".into(),\n                }),\n            ),\n            (\n                cake::Model {\n                    id: 1,\n                    name: \"Blueberry Cheese Cake\".into(),\n                },\n                Some(vendor::Model {\n                    id: 9,\n                    name: \"Blueberry\".into(),\n                }),\n            ),\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        models.reverse();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .cursor_by(cake::Column::Id)\n                .after(10)\n                .last(2)\n                .desc()\n                .all(&db)\n                .await?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"r2\".\"id\" AS \"B_id\", \"r2\".\"name\" AS \"B_name\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"cake_filling\" AS \"r0\" ON \"cake\".\"id\" = \"r0\".\"cake_id\"\"#,\n                    r#\"LEFT JOIN \"filling\" AS \"r1\" ON \"r0\".\"filling_id\" = \"r1\".\"id\"\"#,\n                    r#\"LEFT JOIN \"vendor\" AS \"r2\" ON \"r1\".\"vendor_id\" = \"r2\".\"id\"\"#,\n                    r#\"WHERE \"cake\".\"id\" < $1 ORDER BY \"cake\".\"id\" ASC, \"vendor\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn first_2_before_10_also_linked_select_cursor_other() -> Result<(), DbErr> {\n        let models = [(\n            cake::Model {\n                id: 1,\n                name: \"Blueberry Cheese Cake\".into(),\n            },\n            Some(vendor::Model {\n                id: 9,\n                name: \"Blueberry\".into(),\n            }),\n        )];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .cursor_by_other(vendor::Column::Id)\n                .before(10)\n                .first(2)\n                .all(&db)\n                .await?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"r2\".\"id\" AS \"B_id\", \"r2\".\"name\" AS \"B_name\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"cake_filling\" AS \"r0\" ON \"cake\".\"id\" = \"r0\".\"cake_id\"\"#,\n                    r#\"LEFT JOIN \"filling\" AS \"r1\" ON \"r0\".\"filling_id\" = \"r1\".\"id\"\"#,\n                    r#\"LEFT JOIN \"vendor\" AS \"r2\" ON \"r1\".\"vendor_id\" = \"r2\".\"id\"\"#,\n                    r#\"WHERE \"vendor\".\"id\" < $1 ORDER BY \"vendor\".\"id\" ASC, \"cake\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn last_2_after_10_also_linked_select_cursor_other_desc() -> Result<(), DbErr> {\n        let mut models = [(\n            cake::Model {\n                id: 1,\n                name: \"Blueberry Cheese Cake\".into(),\n            },\n            Some(vendor::Model {\n                id: 9,\n                name: \"Blueberry\".into(),\n            }),\n        )];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        models.reverse();\n\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .cursor_by_other(vendor::Column::Id)\n                .after(10)\n                .last(2)\n                .desc()\n                .all(&db)\n                .await?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"cake\".\"id\" AS \"A_id\", \"cake\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"r2\".\"id\" AS \"B_id\", \"r2\".\"name\" AS \"B_name\"\"#,\n                    r#\"FROM \"cake\"\"#,\n                    r#\"LEFT JOIN \"cake_filling\" AS \"r0\" ON \"cake\".\"id\" = \"r0\".\"cake_id\"\"#,\n                    r#\"LEFT JOIN \"filling\" AS \"r1\" ON \"r0\".\"filling_id\" = \"r1\".\"id\"\"#,\n                    r#\"LEFT JOIN \"vendor\" AS \"r2\" ON \"r1\".\"vendor_id\" = \"r2\".\"id\"\"#,\n                    r#\"WHERE \"vendor\".\"id\" < $1 ORDER BY \"vendor\".\"id\" ASC, \"cake\".\"id\" ASC LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn last_2_after_10() -> Result<(), DbErr> {\n        use fruit::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                Model {\n                    id: 22,\n                    name: \"Raspberry\".into(),\n                    cake_id: Some(1),\n                },\n                Model {\n                    id: 21,\n                    name: \"Blueberry\".into(),\n                    cake_id: Some(1),\n                },\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Entity::find()\n                .cursor_by(Column::Id)\n                .after(10)\n                .last(2)\n                .all(&db)\n                .await?,\n            [\n                Model {\n                    id: 21,\n                    name: \"Blueberry\".into(),\n                    cake_id: Some(1),\n                },\n                Model {\n                    id: 22,\n                    name: \"Raspberry\".into(),\n                    cake_id: Some(1),\n                },\n            ]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\"\"#,\n                    r#\"FROM \"fruit\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" > $1\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" DESC\"#,\n                    r#\"LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn first_2_before_10_desc() -> Result<(), DbErr> {\n        use fruit::*;\n\n        let models = [\n            Model {\n                id: 22,\n                name: \"Raspberry\".into(),\n                cake_id: Some(1),\n            },\n            Model {\n                id: 21,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            },\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            Entity::find()\n                .cursor_by(Column::Id)\n                .before(10)\n                .first(2)\n                .desc()\n                .all(&db)\n                .await?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\"\"#,\n                    r#\"FROM \"fruit\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" > $1\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" DESC\"#,\n                    r#\"LIMIT $2\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [10_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn last_2_after_25_before_30() -> Result<(), DbErr> {\n        use fruit::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                Model {\n                    id: 27,\n                    name: \"Raspberry\".into(),\n                    cake_id: Some(1),\n                },\n                Model {\n                    id: 26,\n                    name: \"Blueberry\".into(),\n                    cake_id: Some(1),\n                },\n            ]])\n            .into_connection();\n\n        assert_eq!(\n            Entity::find()\n                .cursor_by(Column::Id)\n                .after(25)\n                .before(30)\n                .last(2)\n                .all(&db)\n                .await?,\n            [\n                Model {\n                    id: 26,\n                    name: \"Blueberry\".into(),\n                    cake_id: Some(1),\n                },\n                Model {\n                    id: 27,\n                    name: \"Raspberry\".into(),\n                    cake_id: Some(1),\n                },\n            ]\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\"\"#,\n                    r#\"FROM \"fruit\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" > $1\"#,\n                    r#\"AND \"fruit\".\"id\" < $2\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" DESC\"#,\n                    r#\"LIMIT $3\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [25_i32.into(), 30_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn first_2_after_30_before_25_desc() -> Result<(), DbErr> {\n        use fruit::*;\n\n        let models = [\n            Model {\n                id: 27,\n                name: \"Raspberry\".into(),\n                cake_id: Some(1),\n            },\n            Model {\n                id: 26,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            },\n        ];\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([models.clone()])\n            .into_connection();\n\n        assert_eq!(\n            Entity::find()\n                .cursor_by(Column::Id)\n                .after(30)\n                .before(25)\n                .first(2)\n                .desc()\n                .all(&db)\n                .await?,\n            models\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\"\"#,\n                    r#\"FROM \"fruit\"\"#,\n                    r#\"WHERE \"fruit\".\"id\" < $1\"#,\n                    r#\"AND \"fruit\".\"id\" > $2\"#,\n                    r#\"ORDER BY \"fruit\".\"id\" DESC\"#,\n                    r#\"LIMIT $3\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [30_i32.into(), 25_i32.into(), 2_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    mod test_entity {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"example\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(primary_key)]\n            pub category: String,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    mod xyz_entity {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"m\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub x: i32,\n            #[sea_orm(primary_key)]\n            pub y: String,\n            #[sea_orm(primary_key)]\n            pub z: i64,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[smol_potat::test]\n    async fn composite_keys_1() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::Category, Column::Id))\n                .first(3)\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"example\".\"id\", \"example\".\"category\"\"#,\n                    r#\"FROM \"example\"\"#,\n                    r#\"ORDER BY \"example\".\"category\" ASC, \"example\".\"id\" ASC\"#,\n                    r#\"LIMIT $1\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [3_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn composite_keys_1_desc() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::Category, Column::Id))\n                .last(3)\n                .desc()\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"example\".\"id\", \"example\".\"category\"\"#,\n                    r#\"FROM \"example\"\"#,\n                    r#\"ORDER BY \"example\".\"category\" ASC, \"example\".\"id\" ASC\"#,\n                    r#\"LIMIT $1\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [3_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn composite_keys_2() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::Category, Column::Id))\n                .after((\"A\".to_owned(), 2))\n                .first(3)\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"example\".\"id\", \"example\".\"category\"\"#,\n                    r#\"FROM \"example\"\"#,\n                    r#\"WHERE (\"example\".\"category\" = $1 AND \"example\".\"id\" > $2)\"#,\n                    r#\"OR \"example\".\"category\" > $3\"#,\n                    r#\"ORDER BY \"example\".\"category\" ASC, \"example\".\"id\" ASC\"#,\n                    r#\"LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    \"A\".to_string().into(),\n                    2i32.into(),\n                    \"A\".to_string().into(),\n                    3_u64.into(),\n                ]\n            )])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn composite_keys_error() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        let result = Entity::find()\n            .cursor_by((Column::Category, Column::Id))\n            .after(\"A\".to_owned())\n            .first(3)\n            .all(&db)\n            .await;\n\n        assert!(matches!(\n            result,\n            Err(DbErr::KeyArityMismatch {\n                expected: 2,\n                received: 1,\n            })\n        ));\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn composite_keys_2_desc() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::Category, Column::Id))\n                .before((\"A\".to_owned(), 2))\n                .last(3)\n                .desc()\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"example\".\"id\", \"example\".\"category\"\"#,\n                    r#\"FROM \"example\"\"#,\n                    r#\"WHERE (\"example\".\"category\" = $1 AND \"example\".\"id\" > $2)\"#,\n                    r#\"OR \"example\".\"category\" > $3\"#,\n                    r#\"ORDER BY \"example\".\"category\" ASC, \"example\".\"id\" ASC\"#,\n                    r#\"LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    \"A\".to_string().into(),\n                    2i32.into(),\n                    \"A\".to_string().into(),\n                    3_u64.into(),\n                ]\n            )])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn composite_keys_3() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::Category, Column::Id))\n                .before((\"A\".to_owned(), 2))\n                .last(3)\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"example\".\"id\", \"example\".\"category\"\"#,\n                    r#\"FROM \"example\"\"#,\n                    r#\"WHERE (\"example\".\"category\" = $1 AND \"example\".\"id\" < $2)\"#,\n                    r#\"OR \"example\".\"category\" < $3\"#,\n                    r#\"ORDER BY \"example\".\"category\" DESC, \"example\".\"id\" DESC\"#,\n                    r#\"LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    \"A\".to_string().into(),\n                    2i32.into(),\n                    \"A\".to_string().into(),\n                    3_u64.into(),\n                ]\n            )])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn composite_keys_3_desc() -> Result<(), DbErr> {\n        use test_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                id: 1,\n                category: \"CAT\".into(),\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::Category, Column::Id))\n                .after((\"A\".to_owned(), 2))\n                .first(3)\n                .desc()\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"example\".\"id\", \"example\".\"category\"\"#,\n                    r#\"FROM \"example\"\"#,\n                    r#\"WHERE (\"example\".\"category\" = $1 AND \"example\".\"id\" < $2)\"#,\n                    r#\"OR \"example\".\"category\" < $3\"#,\n                    r#\"ORDER BY \"example\".\"category\" DESC, \"example\".\"id\" DESC\"#,\n                    r#\"LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    \"A\".to_string().into(),\n                    2i32.into(),\n                    \"A\".to_string().into(),\n                    3_u64.into(),\n                ]\n            )])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn composite_keys_4() -> Result<(), DbErr> {\n        use xyz_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                x: 'x' as i32,\n                y: \"y\".into(),\n                z: 'z' as i64,\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::X, Column::Y, Column::Z))\n                .first(4)\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"m\".\"x\", \"m\".\"y\", \"m\".\"z\"\"#,\n                    r#\"FROM \"m\"\"#,\n                    r#\"ORDER BY \"m\".\"x\" ASC, \"m\".\"y\" ASC, \"m\".\"z\" ASC\"#,\n                    r#\"LIMIT $1\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [4_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn composite_keys_4_desc() -> Result<(), DbErr> {\n        use xyz_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                x: 'x' as i32,\n                y: \"y\".into(),\n                z: 'z' as i64,\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::X, Column::Y, Column::Z))\n                .last(4)\n                .desc()\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"m\".\"x\", \"m\".\"y\", \"m\".\"z\"\"#,\n                    r#\"FROM \"m\"\"#,\n                    r#\"ORDER BY \"m\".\"x\" ASC, \"m\".\"y\" ASC, \"m\".\"z\" ASC\"#,\n                    r#\"LIMIT $1\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [4_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn composite_keys_5() -> Result<(), DbErr> {\n        use xyz_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                x: 'x' as i32,\n                y: \"y\".into(),\n                z: 'z' as i64,\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::X, Column::Y, Column::Z))\n                .after(('x' as i32, \"y\".to_owned(), 'z' as i64))\n                .first(4)\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"m\".\"x\", \"m\".\"y\", \"m\".\"z\"\"#,\n                    r#\"FROM \"m\"\"#,\n                    r#\"WHERE (\"m\".\"x\" = $1 AND \"m\".\"y\" = $2 AND \"m\".\"z\" > $3)\"#,\n                    r#\"OR (\"m\".\"x\" = $4 AND \"m\".\"y\" > $5)\"#,\n                    r#\"OR \"m\".\"x\" > $6\"#,\n                    r#\"ORDER BY \"m\".\"x\" ASC, \"m\".\"y\" ASC, \"m\".\"z\" ASC\"#,\n                    r#\"LIMIT $7\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    ('x' as i32).into(),\n                    \"y\".into(),\n                    ('z' as i64).into(),\n                    ('x' as i32).into(),\n                    \"y\".into(),\n                    ('x' as i32).into(),\n                    4_u64.into(),\n                ]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn composite_keys_5_desc() -> Result<(), DbErr> {\n        use xyz_entity::*;\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[Model {\n                x: 'x' as i32,\n                y: \"y\".into(),\n                z: 'z' as i64,\n            }]])\n            .into_connection();\n\n        assert!(\n            !Entity::find()\n                .cursor_by((Column::X, Column::Y, Column::Z))\n                .before(('x' as i32, \"y\".to_owned(), 'z' as i64))\n                .last(4)\n                .desc()\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"m\".\"x\", \"m\".\"y\", \"m\".\"z\"\"#,\n                    r#\"FROM \"m\"\"#,\n                    r#\"WHERE (\"m\".\"x\" = $1 AND \"m\".\"y\" = $2 AND \"m\".\"z\" > $3)\"#,\n                    r#\"OR (\"m\".\"x\" = $4 AND \"m\".\"y\" > $5)\"#,\n                    r#\"OR \"m\".\"x\" > $6\"#,\n                    r#\"ORDER BY \"m\".\"x\" ASC, \"m\".\"y\" ASC, \"m\".\"z\" ASC\"#,\n                    r#\"LIMIT $7\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    ('x' as i32).into(),\n                    \"y\".into(),\n                    ('z' as i64).into(),\n                    ('x' as i32).into(),\n                    \"y\".into(),\n                    ('x' as i32).into(),\n                    4_u64.into(),\n                ]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    mod composite_entity {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"t\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub col_1: String,\n            #[sea_orm(primary_key)]\n            pub col_2: String,\n            #[sea_orm(primary_key)]\n            pub col_3: String,\n            #[sea_orm(primary_key)]\n            pub col_4: String,\n            #[sea_orm(primary_key)]\n            pub col_5: String,\n            #[sea_orm(primary_key)]\n            pub col_6: String,\n            #[sea_orm(primary_key)]\n            pub col_7: String,\n            #[sea_orm(primary_key)]\n            pub col_8: String,\n            #[sea_orm(primary_key)]\n            pub col_9: String,\n            #[sea_orm(primary_key)]\n            pub col_10: String,\n            #[sea_orm(primary_key)]\n            pub col_11: String,\n            #[sea_orm(primary_key)]\n            pub col_12: String,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[smol_potat::test]\n    async fn cursor_by_many() -> Result<(), DbErr> {\n        use composite_entity::*;\n\n        let base_sql = [\n            r#\"SELECT \"t\".\"col_1\", \"t\".\"col_2\", \"t\".\"col_3\", \"t\".\"col_4\", \"t\".\"col_5\", \"t\".\"col_6\", \"t\".\"col_7\", \"t\".\"col_8\", \"t\".\"col_9\", \"t\".\"col_10\", \"t\".\"col_11\", \"t\".\"col_12\"\"#,\n            r#\"FROM \"t\" WHERE\"#,\n        ].join(\" \");\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4))\n                .after((\"val_1\", \"val_2\", \"val_3\", \"val_4\")).apply_limit().apply_order_by().apply_filters()?.query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" > 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" > 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" > 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" > 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" ASC, \"t\".\"col_2\" ASC, \"t\".\"col_3\" ASC, \"t\".\"col_4\" ASC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5))\n                .after((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\")).apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" > 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" > 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" > 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" > 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" > 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" ASC, \"t\".\"col_2\" ASC, \"t\".\"col_3\" ASC, \"t\".\"col_4\" ASC, \"t\".\"col_5\" ASC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6))\n                .after((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\")).apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" > 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" > 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" > 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" > 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" > 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" > 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" ASC, \"t\".\"col_2\" ASC, \"t\".\"col_3\" ASC, \"t\".\"col_4\" ASC, \"t\".\"col_5\" ASC, \"t\".\"col_6\" ASC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6, Column::Col7))\n                .before((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\", \"val_7\")).apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" < 'val_7')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" < 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" < 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" < 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" < 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" < 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" < 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" ASC, \"t\".\"col_2\" ASC, \"t\".\"col_3\" ASC, \"t\".\"col_4\" ASC, \"t\".\"col_5\" ASC, \"t\".\"col_6\" ASC, \"t\".\"col_7\" ASC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6, Column::Col7, Column::Col8))\n                .before((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\", \"val_7\", \"val_8\")).apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" = 'val_7' AND \"t\".\"col_8\" < 'val_8')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" < 'val_7')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" < 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" < 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" < 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" < 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" < 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" < 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" ASC, \"t\".\"col_2\" ASC, \"t\".\"col_3\" ASC, \"t\".\"col_4\" ASC, \"t\".\"col_5\" ASC, \"t\".\"col_6\" ASC, \"t\".\"col_7\" ASC, \"t\".\"col_8\" ASC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6, Column::Col7, Column::Col8, Column::Col9))\n                .before((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\", \"val_7\", \"val_8\", \"val_9\")).apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" = 'val_7' AND \"t\".\"col_8\" = 'val_8' AND \"t\".\"col_9\" < 'val_9')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" = 'val_7' AND \"t\".\"col_8\" < 'val_8')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" < 'val_7')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" < 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" < 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" < 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" < 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" < 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" < 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" ASC, \"t\".\"col_2\" ASC, \"t\".\"col_3\" ASC, \"t\".\"col_4\" ASC, \"t\".\"col_5\" ASC, \"t\".\"col_6\" ASC, \"t\".\"col_7\" ASC, \"t\".\"col_8\" ASC, \"t\".\"col_9\" ASC\"#,\n            ].join(\" \"))\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn cursor_by_many_desc() -> Result<(), DbErr> {\n        use composite_entity::*;\n\n        let base_sql = [\n            r#\"SELECT \"t\".\"col_1\", \"t\".\"col_2\", \"t\".\"col_3\", \"t\".\"col_4\", \"t\".\"col_5\", \"t\".\"col_6\", \"t\".\"col_7\", \"t\".\"col_8\", \"t\".\"col_9\", \"t\".\"col_10\", \"t\".\"col_11\", \"t\".\"col_12\"\"#,\n            r#\"FROM \"t\" WHERE\"#,\n        ].join(\" \");\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4))\n                .before((\"val_1\", \"val_2\", \"val_3\", \"val_4\")).desc().apply_limit().apply_order_by().apply_filters()?.query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" > 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" > 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" > 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" > 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" DESC, \"t\".\"col_2\" DESC, \"t\".\"col_3\" DESC, \"t\".\"col_4\" DESC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5))\n                .before((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\")).desc().apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" > 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" > 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" > 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" > 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" > 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" DESC, \"t\".\"col_2\" DESC, \"t\".\"col_3\" DESC, \"t\".\"col_4\" DESC, \"t\".\"col_5\" DESC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6))\n                .before((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\")).desc().apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" > 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" > 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" > 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" > 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" > 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" > 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" DESC, \"t\".\"col_2\" DESC, \"t\".\"col_3\" DESC, \"t\".\"col_4\" DESC, \"t\".\"col_5\" DESC, \"t\".\"col_6\" DESC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6, Column::Col7))\n                .after((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\", \"val_7\")).desc().apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" < 'val_7')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" < 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" < 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" < 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" < 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" < 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" < 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" DESC, \"t\".\"col_2\" DESC, \"t\".\"col_3\" DESC, \"t\".\"col_4\" DESC, \"t\".\"col_5\" DESC, \"t\".\"col_6\" DESC, \"t\".\"col_7\" DESC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6, Column::Col7, Column::Col8))\n                .after((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\", \"val_7\", \"val_8\")).desc().apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" = 'val_7' AND \"t\".\"col_8\" < 'val_8')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" < 'val_7')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" < 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" < 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" < 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" < 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" < 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" < 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" DESC, \"t\".\"col_2\" DESC, \"t\".\"col_3\" DESC, \"t\".\"col_4\" DESC, \"t\".\"col_5\" DESC, \"t\".\"col_6\" DESC, \"t\".\"col_7\" DESC, \"t\".\"col_8\" DESC\"#,\n            ].join(\" \"))\n        );\n\n        assert_eq!(\n            DbBackend::Postgres.build(&\n                Entity::find()\n                .cursor_by((Column::Col1, Column::Col2, Column::Col3, Column::Col4, Column::Col5, Column::Col6, Column::Col7, Column::Col8, Column::Col9))\n                .after((\"val_1\", \"val_2\", \"val_3\", \"val_4\", \"val_5\", \"val_6\", \"val_7\", \"val_8\", \"val_9\")).desc().apply_limit().apply_order_by().apply_filters()?\n                .query\n            ).to_string(),\n            format!(\"{base_sql} {}\", [\n                r#\"(\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" = 'val_7' AND \"t\".\"col_8\" = 'val_8' AND \"t\".\"col_9\" < 'val_9')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" = 'val_7' AND \"t\".\"col_8\" < 'val_8')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" = 'val_6' AND \"t\".\"col_7\" < 'val_7')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" = 'val_5' AND \"t\".\"col_6\" < 'val_6')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" = 'val_4' AND \"t\".\"col_5\" < 'val_5')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" = 'val_3' AND \"t\".\"col_4\" < 'val_4')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" = 'val_2' AND \"t\".\"col_3\" < 'val_3')\"#,\n                r#\"OR (\"t\".\"col_1\" = 'val_1' AND \"t\".\"col_2\" < 'val_2')\"#,\n                r#\"OR \"t\".\"col_1\" < 'val_1'\"#,\n                r#\"ORDER BY \"t\".\"col_1\" DESC, \"t\".\"col_2\" DESC, \"t\".\"col_3\" DESC, \"t\".\"col_4\" DESC, \"t\".\"col_5\" DESC, \"t\".\"col_6\" DESC, \"t\".\"col_7\" DESC, \"t\".\"col_8\" DESC, \"t\".\"col_9\" DESC\"#,\n            ].join(\" \"))\n        );\n\n        Ok(())\n    }\n\n    mod test_base_entity {\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"base\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(primary_key)]\n            pub name: String,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {\n            #[sea_orm(has_many = \"super::test_related_entity::Entity\")]\n            TestRelatedEntity,\n        }\n\n        impl Related<super::test_related_entity::Entity> for Entity {\n            fn to() -> RelationDef {\n                Relation::TestRelatedEntity.def()\n            }\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    mod test_related_entity {\n        use super::test_base_entity;\n        use crate as sea_orm;\n        use crate::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"related\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(primary_key)]\n            pub name: String,\n            pub test_id: i32,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {\n            #[sea_orm(\n                belongs_to = \"test_base_entity::Entity\",\n                from = \"Column::TestId\",\n                to = \"super::test_base_entity::Column::Id\"\n            )]\n            TestBaseEntity,\n        }\n\n        impl Related<super::test_base_entity::Entity> for Entity {\n            fn to() -> RelationDef {\n                Relation::TestBaseEntity.def()\n            }\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[smol_potat::test]\n    async fn related_composite_keys_1() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                test_base_entity::Model {\n                    id: 1,\n                    name: \"CAT\".into(),\n                },\n                test_related_entity::Model {\n                    id: 1,\n                    name: \"CATE\".into(),\n                    test_id: 1,\n                },\n            )]])\n            .into_connection();\n\n        assert!(\n            !test_base_entity::Entity::find()\n                .find_also_related(test_related_entity::Entity)\n                .cursor_by((test_base_entity::Column::Id, test_base_entity::Column::Name))\n                .first(1)\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"base\".\"id\" AS \"A_id\", \"base\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"related\".\"id\" AS \"B_id\", \"related\".\"name\" AS \"B_name\", \"related\".\"test_id\" AS \"B_test_id\"\"#,\n                    r#\"FROM \"base\"\"#,\n                    r#\"LEFT JOIN \"related\" ON \"base\".\"id\" = \"related\".\"test_id\"\"#,\n                    r#\"ORDER BY \"base\".\"id\" ASC, \"base\".\"name\" ASC, \"related\".\"id\" ASC, \"related\".\"name\" ASC LIMIT $1\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [1_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn related_composite_keys_1_desc() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                test_base_entity::Model {\n                    id: 1,\n                    name: \"CAT\".into(),\n                },\n                test_related_entity::Model {\n                    id: 1,\n                    name: \"CATE\".into(),\n                    test_id: 1,\n                },\n            )]])\n            .into_connection();\n\n        assert!(\n            !test_base_entity::Entity::find()\n                .find_also_related(test_related_entity::Entity)\n                .cursor_by((test_base_entity::Column::Id, test_base_entity::Column::Name))\n                .last(1)\n                .desc()\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"base\".\"id\" AS \"A_id\", \"base\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"related\".\"id\" AS \"B_id\", \"related\".\"name\" AS \"B_name\", \"related\".\"test_id\" AS \"B_test_id\"\"#,\n                    r#\"FROM \"base\"\"#,\n                    r#\"LEFT JOIN \"related\" ON \"base\".\"id\" = \"related\".\"test_id\"\"#,\n                    r#\"ORDER BY \"base\".\"id\" ASC, \"base\".\"name\" ASC, \"related\".\"id\" ASC, \"related\".\"name\" ASC LIMIT $1\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [1_u64.into()]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn related_composite_keys_2() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                test_base_entity::Model {\n                    id: 1,\n                    name: \"CAT\".into(),\n                },\n                test_related_entity::Model {\n                    id: 1,\n                    name: \"CATE\".into(),\n                    test_id: 1,\n                },\n            )]])\n            .into_connection();\n\n        assert!(\n            !test_base_entity::Entity::find()\n                .find_also_related(test_related_entity::Entity)\n                .cursor_by((test_base_entity::Column::Id, test_base_entity::Column::Name))\n                .after((1, \"C\".to_string()))\n                .first(2)\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"base\".\"id\" AS \"A_id\", \"base\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"related\".\"id\" AS \"B_id\", \"related\".\"name\" AS \"B_name\", \"related\".\"test_id\" AS \"B_test_id\"\"#,\n                    r#\"FROM \"base\"\"#,\n                    r#\"LEFT JOIN \"related\" ON \"base\".\"id\" = \"related\".\"test_id\"\"#,\n                    r#\"WHERE (\"base\".\"id\" = $1 AND \"base\".\"name\" > $2) OR \"base\".\"id\" > $3\"#,\n                    r#\"ORDER BY \"base\".\"id\" ASC, \"base\".\"name\" ASC, \"related\".\"id\" ASC, \"related\".\"name\" ASC LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    1_i32.into(),\n                    \"C\".into(),\n                    1_i32.into(),\n                    2_u64.into(),\n                ]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn related_composite_keys_2_desc() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                test_base_entity::Model {\n                    id: 1,\n                    name: \"CAT\".into(),\n                },\n                test_related_entity::Model {\n                    id: 1,\n                    name: \"CATE\".into(),\n                    test_id: 1,\n                },\n            )]])\n            .into_connection();\n\n        assert!(\n            !test_base_entity::Entity::find()\n                .find_also_related(test_related_entity::Entity)\n                .cursor_by((test_base_entity::Column::Id, test_base_entity::Column::Name))\n                .before((1, \"C\".to_string()))\n                .last(2)\n                .desc()\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"base\".\"id\" AS \"A_id\", \"base\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"related\".\"id\" AS \"B_id\", \"related\".\"name\" AS \"B_name\", \"related\".\"test_id\" AS \"B_test_id\"\"#,\n                    r#\"FROM \"base\"\"#,\n                    r#\"LEFT JOIN \"related\" ON \"base\".\"id\" = \"related\".\"test_id\"\"#,\n                    r#\"WHERE (\"base\".\"id\" = $1 AND \"base\".\"name\" > $2) OR \"base\".\"id\" > $3\"#,\n                    r#\"ORDER BY \"base\".\"id\" ASC, \"base\".\"name\" ASC, \"related\".\"id\" ASC, \"related\".\"name\" ASC LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    1_i32.into(),\n                    \"C\".into(),\n                    1_i32.into(),\n                    2_u64.into(),\n                ]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn related_composite_keys_3() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                test_base_entity::Model {\n                    id: 1,\n                    name: \"CAT\".into(),\n                },\n                test_related_entity::Model {\n                    id: 1,\n                    name: \"CATE\".into(),\n                    test_id: 1,\n                },\n            )]])\n            .into_connection();\n\n        assert!(\n            !test_base_entity::Entity::find()\n                .find_also_related(test_related_entity::Entity)\n                .cursor_by_other((\n                    test_related_entity::Column::Id,\n                    test_related_entity::Column::Name\n                ))\n                .after((1, \"CAT\".to_string()))\n                .first(2)\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"base\".\"id\" AS \"A_id\", \"base\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"related\".\"id\" AS \"B_id\", \"related\".\"name\" AS \"B_name\", \"related\".\"test_id\" AS \"B_test_id\"\"#,\n                    r#\"FROM \"base\"\"#,\n                    r#\"LEFT JOIN \"related\" ON \"base\".\"id\" = \"related\".\"test_id\"\"#,\n                    r#\"WHERE (\"related\".\"id\" = $1 AND \"related\".\"name\" > $2) OR \"related\".\"id\" > $3\"#,\n                    r#\"ORDER BY \"related\".\"id\" ASC, \"related\".\"name\" ASC, \"base\".\"id\" ASC, \"base\".\"name\" ASC LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    1_i32.into(),\n                    \"CAT\".into(),\n                    1_i32.into(),\n                    2_u64.into(),\n                ]\n            ),])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn related_composite_keys_3_desc() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[(\n                test_base_entity::Model {\n                    id: 1,\n                    name: \"CAT\".into(),\n                },\n                test_related_entity::Model {\n                    id: 1,\n                    name: \"CATE\".into(),\n                    test_id: 1,\n                },\n            )]])\n            .into_connection();\n\n        assert!(\n            !test_base_entity::Entity::find()\n                .find_also_related(test_related_entity::Entity)\n                .cursor_by_other((\n                    test_related_entity::Column::Id,\n                    test_related_entity::Column::Name\n                ))\n                .before((1, \"CAT\".to_string()))\n                .last(2)\n                .desc()\n                .all(&db)\n                .await?\n                .is_empty()\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                [\n                    r#\"SELECT \"base\".\"id\" AS \"A_id\", \"base\".\"name\" AS \"A_name\",\"#,\n                    r#\"\"related\".\"id\" AS \"B_id\", \"related\".\"name\" AS \"B_name\", \"related\".\"test_id\" AS \"B_test_id\"\"#,\n                    r#\"FROM \"base\"\"#,\n                    r#\"LEFT JOIN \"related\" ON \"base\".\"id\" = \"related\".\"test_id\"\"#,\n                    r#\"WHERE (\"related\".\"id\" = $1 AND \"related\".\"name\" > $2) OR \"related\".\"id\" > $3\"#,\n                    r#\"ORDER BY \"related\".\"id\" ASC, \"related\".\"name\" ASC, \"base\".\"id\" ASC, \"base\".\"name\" ASC LIMIT $4\"#,\n                ]\n                .join(\" \")\n                .as_str(),\n                [\n                    1_i32.into(),\n                    \"CAT\".into(),\n                    1_i32.into(),\n                    2_u64.into(),\n                ]\n            ),])]\n        );\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "src/executor/delete.rs",
    "content": "use super::{ReturningSelector, SelectModel};\nuse crate::{\n    ColumnTrait, ConnectionTrait, DeleteMany, DeleteOne, EntityTrait, Iterable, ValidatedDeleteOne,\n    error::*,\n};\nuse sea_query::{DeleteStatement, Query};\n\n/// Handles DELETE operations in a ActiveModel using [DeleteStatement]\n#[derive(Clone, Debug)]\npub struct Deleter {\n    query: DeleteStatement,\n}\n\n/// The result of a DELETE operation\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct DeleteResult {\n    /// The number of rows affected by the DELETE operation\n    pub rows_affected: u64,\n}\n\nimpl<E> ValidatedDeleteOne<E>\nwhere\n    E: EntityTrait,\n{\n    /// Execute a DELETE operation on one ActiveModel\n    pub async fn exec<C>(self, db: &C) -> Result<DeleteResult, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        exec_delete_only(self.query, db).await\n    }\n\n    /// Execute an delete operation and return the deleted model\n    pub async fn exec_with_returning<C>(self, db: &C) -> Result<Option<E::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        exec_delete_with_returning_one::<E, _>(self.query, db).await\n    }\n}\n\nimpl<E> DeleteOne<E>\nwhere\n    E: EntityTrait,\n{\n    /// Execute a DELETE operation on one ActiveModel\n    pub async fn exec<C>(self, db: &C) -> Result<DeleteResult, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.0?.exec(db).await\n    }\n\n    /// Execute an delete operation and return the deleted model\n    pub async fn exec_with_returning<C>(self, db: &C) -> Result<Option<E::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.0?.exec_with_returning(db).await\n    }\n}\n\nimpl<'a, E> DeleteMany<E>\nwhere\n    E: EntityTrait,\n{\n    /// Execute a DELETE operation on many ActiveModels\n    pub async fn exec<C>(self, db: &'a C) -> Result<DeleteResult, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        exec_delete_only(self.query, db).await\n    }\n\n    /// Execute an delete operation and return the deleted model\n    pub async fn exec_with_returning<C>(self, db: &C) -> Result<Vec<E::Model>, DbErr>\n    where\n        E: EntityTrait,\n        C: ConnectionTrait,\n    {\n        exec_delete_with_returning_many::<E, _>(self.query, db).await\n    }\n}\n\nimpl Deleter {\n    /// Instantiate a new [Deleter] by passing it a [DeleteStatement]\n    pub fn new(query: DeleteStatement) -> Self {\n        Self { query }\n    }\n\n    /// Execute a DELETE operation\n    pub async fn exec<C>(self, db: &C) -> Result<DeleteResult, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        exec_delete(self.query, db).await\n    }\n\n    /// Execute an delete operation and return the deleted model\n    pub async fn exec_with_returning<E, C>(self, db: &C) -> Result<Vec<E::Model>, DbErr>\n    where\n        E: EntityTrait,\n        C: ConnectionTrait,\n    {\n        exec_delete_with_returning_many::<E, _>(self.query, db).await\n    }\n}\n\nimpl DeleteResult {\n    #[doc(hidden)]\n    pub fn empty() -> Self {\n        Self { rows_affected: 0 }\n    }\n\n    #[doc(hidden)]\n    pub fn merge(&mut self, other: DeleteResult) {\n        self.rows_affected += other.rows_affected;\n    }\n}\n\nasync fn exec_delete_only<C>(query: DeleteStatement, db: &C) -> Result<DeleteResult, DbErr>\nwhere\n    C: ConnectionTrait,\n{\n    Deleter::new(query).exec(db).await\n}\n\nasync fn exec_delete<C>(query: DeleteStatement, db: &C) -> Result<DeleteResult, DbErr>\nwhere\n    C: ConnectionTrait,\n{\n    let result = db.execute(&query).await?;\n    Ok(DeleteResult {\n        rows_affected: result.rows_affected(),\n    })\n}\n\nasync fn exec_delete_with_returning_one<E, C>(\n    mut query: DeleteStatement,\n    db: &C,\n) -> Result<Option<E::Model>, DbErr>\nwhere\n    E: EntityTrait,\n    C: ConnectionTrait,\n{\n    let db_backend = db.get_database_backend();\n    match db.support_returning() {\n        true => {\n            let returning = Query::returning().exprs(\n                E::Column::iter().map(|c| c.select_enum_as(c.into_returning_expr(db_backend))),\n            );\n            query.returning(returning);\n            ReturningSelector::<SelectModel<<E>::Model>, _>::from_query(query)\n                .one(db)\n                .await\n        }\n        false => Err(DbErr::BackendNotSupported {\n            db: db_backend.as_str(),\n            ctx: \"DELETE RETURNING\",\n        }),\n    }\n}\n\nasync fn exec_delete_with_returning_many<E, C>(\n    mut query: DeleteStatement,\n    db: &C,\n) -> Result<Vec<E::Model>, DbErr>\nwhere\n    E: EntityTrait,\n    C: ConnectionTrait,\n{\n    let db_backend = db.get_database_backend();\n    match db.support_returning() {\n        true => {\n            let returning = Query::returning().exprs(\n                E::Column::iter().map(|c| c.select_enum_as(c.into_returning_expr(db_backend))),\n            );\n            query.returning(returning);\n            ReturningSelector::<SelectModel<<E>::Model>, _>::from_query(query)\n                .all(db)\n                .await\n        }\n        false => Err(DbErr::BackendNotSupported {\n            db: db_backend.as_str(),\n            ctx: \"DELETE RETURNING\",\n        }),\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::cake;\n\n    #[smol_potat::test]\n    async fn delete_error() {\n        use crate::{DbBackend, DbErr, Delete, EntityTrait, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::MySql).into_connection();\n\n        assert!(matches!(\n            Delete::one(cake::ActiveModel {\n                ..Default::default()\n            })\n            .exec(&db)\n            .await,\n            Err(DbErr::PrimaryKeyNotSet { .. })\n        ));\n\n        assert!(matches!(\n            cake::Entity::delete(cake::ActiveModel::default())\n                .exec(&db)\n                .await,\n            Err(DbErr::PrimaryKeyNotSet { .. })\n        ));\n    }\n}\n"
  },
  {
    "path": "src/executor/execute.rs",
    "content": "/// Defines the result of executing an operation\n#[derive(Debug)]\npub struct ExecResult {\n    /// The type of result from the execution depending on the feature flag enabled\n    /// to choose a database backend\n    pub(crate) result: ExecResultHolder,\n}\n\n/// Holds a result depending on the database backend chosen by the feature flag\n#[allow(clippy::enum_variant_names)]\n#[derive(Debug)]\npub(crate) enum ExecResultHolder {\n    /// Holds the result of executing an operation on a MySQL database\n    #[cfg(feature = \"sqlx-mysql\")]\n    SqlxMySql(sqlx::mysql::MySqlQueryResult),\n    /// Holds the result of executing an operation on a PostgreSQL database\n    #[cfg(feature = \"sqlx-postgres\")]\n    SqlxPostgres(sqlx::postgres::PgQueryResult),\n    /// Holds the result of executing an operation on a SQLite database\n    #[cfg(feature = \"sqlx-sqlite\")]\n    SqlxSqlite(sqlx::sqlite::SqliteQueryResult),\n    /// Holds the result of executing an operation on a SQLite database\n    #[cfg(feature = \"rusqlite\")]\n    Rusqlite(crate::driver::rusqlite::RusqliteExecResult),\n    /// Holds the result of executing an operation on the Mock database\n    #[cfg(feature = \"mock\")]\n    Mock(crate::MockExecResult),\n    /// Holds the result of executing an operation on the Proxy database\n    #[cfg(feature = \"proxy\")]\n    Proxy(crate::ProxyExecResult),\n}\n\n// ExecResult //\n\nimpl ExecResult {\n    /// Get the last id after `AUTOINCREMENT` is done on the primary key\n    ///\n    /// # Panics\n    ///\n    /// Postgres does not support retrieving last insert id this way except through `RETURNING` clause\n    pub fn last_insert_id(&self) -> u64 {\n        match &self.result {\n            #[cfg(feature = \"sqlx-mysql\")]\n            ExecResultHolder::SqlxMySql(result) => result.last_insert_id(),\n            #[cfg(feature = \"sqlx-postgres\")]\n            ExecResultHolder::SqlxPostgres(_) => {\n                panic!(\"Should not retrieve last_insert_id this way\")\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            ExecResultHolder::SqlxSqlite(result) => {\n                let last_insert_rowid = result.last_insert_rowid();\n                if last_insert_rowid < 0 {\n                    unreachable!(\"negative last_insert_rowid\")\n                } else {\n                    last_insert_rowid as u64\n                }\n            }\n            #[cfg(feature = \"rusqlite\")]\n            ExecResultHolder::Rusqlite(result) => {\n                let last_insert_rowid = result.last_insert_rowid;\n                if last_insert_rowid < 0 {\n                    unreachable!(\"negative last_insert_rowid\")\n                } else {\n                    last_insert_rowid as u64\n                }\n            }\n            #[cfg(feature = \"mock\")]\n            ExecResultHolder::Mock(result) => result.last_insert_id,\n            #[cfg(feature = \"proxy\")]\n            ExecResultHolder::Proxy(result) => result.last_insert_id,\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n\n    /// Get the number of rows affected by the operation\n    pub fn rows_affected(&self) -> u64 {\n        match &self.result {\n            #[cfg(feature = \"sqlx-mysql\")]\n            ExecResultHolder::SqlxMySql(result) => result.rows_affected(),\n            #[cfg(feature = \"sqlx-postgres\")]\n            ExecResultHolder::SqlxPostgres(result) => result.rows_affected(),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            ExecResultHolder::SqlxSqlite(result) => result.rows_affected(),\n            #[cfg(feature = \"rusqlite\")]\n            ExecResultHolder::Rusqlite(result) => result.rows_affected,\n            #[cfg(feature = \"mock\")]\n            ExecResultHolder::Mock(result) => result.rows_affected,\n            #[cfg(feature = \"proxy\")]\n            ExecResultHolder::Proxy(result) => result.rows_affected,\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n"
  },
  {
    "path": "src/executor/insert.rs",
    "content": "use super::ReturningSelector;\nuse crate::{\n    ActiveModelTrait, ColumnTrait, ConnectionTrait, DbBackend, EntityTrait, Insert, InsertMany,\n    IntoActiveModel, Iterable, PrimaryKeyToColumn, PrimaryKeyTrait, SelectModel, TryFromU64,\n    TryInsert, error::*,\n};\nuse sea_query::{FromValueTuple, Iden, InsertStatement, Query, ReturningClause, ValueTuple};\nuse std::marker::PhantomData;\n\ntype PrimaryKey<A> = <<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey;\n\n/// Defines a structure to perform INSERT operations in an ActiveModel\n#[derive(Debug)]\npub struct Inserter<A>\nwhere\n    A: ActiveModelTrait,\n{\n    primary_key: Option<ValueTuple>,\n    query: InsertStatement,\n    model: PhantomData<A>,\n}\n\n/// The result of an INSERT operation on an ActiveModel\n#[derive(Debug)]\n#[non_exhaustive]\npub struct InsertResult<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// The primary key value of the last inserted row\n    pub last_insert_id: <PrimaryKey<A> as PrimaryKeyTrait>::ValueType,\n}\n\n/// The result of an INSERT many operation for a set of ActiveModels\n#[derive(Debug)]\n#[non_exhaustive]\npub struct InsertManyResult<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// The primary key value of the last inserted row\n    pub last_insert_id: Option<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>,\n}\n\n/// The result of executing a [`crate::TryInsert`].\n///\n/// This enum represents no‑op inserts (e.g. conflict `DO NOTHING`) without treating\n/// them as errors.\n#[derive(Debug)]\npub enum TryInsertResult<T> {\n    /// There was nothing to insert, so no SQL was executed.\n    ///\n    /// This typically happens when creating a [`crate::TryInsert`] from an empty iterator or None.\n    Empty,\n    /// The statement was executed, but SeaORM could not get the inserted row / insert id.\n    ///\n    /// This is commonly caused by `ON CONFLICT ... DO NOTHING` (Postgres / SQLite) or the MySQL\n    /// polyfill (`ON DUPLICATE KEY UPDATE pk = pk`).\n    ///\n    /// Note that this variant maps from `DbErr::RecordNotInserted`, so it can also represent other\n    /// situations where the backend/driver reports no inserted row (e.g. an empty `RETURNING`\n    /// result set or a \"no-op\" update in MySQL where `last_insert_id` is reported as `0`). In rare\n    /// cases, this can be a false negative where a row was inserted but the backend did not report\n    /// it.\n    Conflicted,\n    /// Successfully inserted\n    Inserted(T),\n}\n\nimpl<A> TryInsertResult<InsertResult<A>>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Extract the last inserted id.\n    ///\n    /// - [`TryInsertResult::Empty`] => `Ok(None)`\n    /// - [`TryInsertResult::Inserted`] => `Ok(Some(last_insert_id))`\n    /// - [`TryInsertResult::Conflicted`] => `Err(DbErr::RecordNotInserted)`\n    pub fn last_insert_id(\n        self,\n    ) -> Result<Option<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>, DbErr> {\n        match self {\n            Self::Empty => Ok(None),\n            Self::Inserted(v) => Ok(Some(v.last_insert_id)),\n            Self::Conflicted => Err(DbErr::RecordNotInserted),\n        }\n    }\n}\n\nimpl<A> TryInsert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Execute an insert operation\n    pub async fn exec<C>(self, db: &C) -> Result<TryInsertResult<InsertResult<A>>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(TryInsertResult::Empty);\n        }\n        let res = self.insert_struct.exec(db).await;\n        match res {\n            Ok(res) => Ok(TryInsertResult::Inserted(res)),\n            Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),\n            Err(err) => Err(err),\n        }\n    }\n\n    /// Execute an insert operation without returning (don't use `RETURNING` syntax)\n    /// Number of rows affected is returned\n    pub async fn exec_without_returning<C>(self, db: &C) -> Result<TryInsertResult<u64>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(TryInsertResult::Empty);\n        }\n        let res = self.insert_struct.exec_without_returning(db).await;\n        match res {\n            Ok(res) => Ok(TryInsertResult::Inserted(res)),\n            Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),\n            Err(err) => Err(err),\n        }\n    }\n\n    /// Execute an insert operation and return the inserted model (use `RETURNING` syntax if supported)\n    pub async fn exec_with_returning<C>(\n        self,\n        db: &C,\n    ) -> Result<TryInsertResult<<A::Entity as EntityTrait>::Model>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(TryInsertResult::Empty);\n        }\n        let res = self.insert_struct.exec_with_returning(db).await;\n        match res {\n            Ok(res) => Ok(TryInsertResult::Inserted(res)),\n            Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),\n            Err(err) => Err(err),\n        }\n    }\n\n    /// Execute an insert operation and return primary keys of inserted models\n    pub async fn exec_with_returning_keys<C>(\n        self,\n        db: &C,\n    ) -> Result<TryInsertResult<Vec<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(TryInsertResult::Empty);\n        }\n\n        let res = self.insert_struct.exec_with_returning_keys(db).await;\n        match res {\n            Ok(res) => Ok(TryInsertResult::Inserted(res)),\n            Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),\n            Err(err) => Err(err),\n        }\n    }\n\n    /// Execute an insert operation and return all inserted models\n    pub async fn exec_with_returning_many<C>(\n        self,\n        db: &C,\n    ) -> Result<TryInsertResult<Vec<<A::Entity as EntityTrait>::Model>>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(TryInsertResult::Empty);\n        }\n\n        let res = self.insert_struct.exec_with_returning_many(db).await;\n        match res {\n            Ok(res) => Ok(TryInsertResult::Inserted(res)),\n            Err(DbErr::RecordNotInserted) => Ok(TryInsertResult::Conflicted),\n            Err(err) => Err(err),\n        }\n    }\n}\n\nimpl<A> Insert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Execute an insert operation\n    pub async fn exec<'a, C>(self, db: &'a C) -> Result<InsertResult<A>, DbErr>\n    where\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        // so that self is dropped before entering await\n        let mut query = self.query;\n        if db.support_returning() {\n            query.returning(returning_pk::<A>(db.get_database_backend()));\n        }\n        Inserter::<A>::new(self.primary_key, query).exec(db).await\n    }\n\n    /// Execute an insert operation without returning (don't use `RETURNING` syntax)\n    /// Number of rows affected is returned\n    pub async fn exec_without_returning<'a, C>(self, db: &'a C) -> Result<u64, DbErr>\n    where\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        Inserter::<A>::new(self.primary_key, self.query)\n            .exec_without_returning(db)\n            .await\n    }\n\n    /// Execute an insert operation and return the inserted model (use `RETURNING` syntax if supported)\n    ///\n    /// + To get back all inserted models, use [`exec_with_returning_many`].\n    /// + To get back all inserted primary keys, use [`exec_with_returning_keys`].\n    pub async fn exec_with_returning<'a, C>(\n        self,\n        db: &'a C,\n    ) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        Inserter::<A>::new(self.primary_key, self.query)\n            .exec_with_returning(db)\n            .await\n    }\n\n    /// Execute an insert operation and return primary keys of inserted models\n    pub async fn exec_with_returning_keys<'a, C>(\n        self,\n        db: &'a C,\n    ) -> Result<Vec<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        Inserter::<A>::new(self.primary_key, self.query)\n            .exec_with_returning_keys(db)\n            .await\n    }\n\n    /// Execute an insert operation and return all inserted models\n    pub async fn exec_with_returning_many<'a, C>(\n        self,\n        db: &'a C,\n    ) -> Result<Vec<<A::Entity as EntityTrait>::Model>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        Inserter::<A>::new(self.primary_key, self.query)\n            .exec_with_returning_many(db)\n            .await\n    }\n}\n\nimpl<A> InsertMany<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Execute an insert operation\n    pub async fn exec<C>(self, db: &C) -> Result<InsertManyResult<A>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(InsertManyResult {\n                last_insert_id: None,\n            });\n        }\n        let res = self.into_one().exec(db).await;\n        match res {\n            Ok(r) => Ok(InsertManyResult {\n                last_insert_id: Some(r.last_insert_id),\n            }),\n            Err(err) => Err(err),\n        }\n    }\n\n    /// Execute an insert operation without returning (don't use `RETURNING` syntax)\n    /// Number of rows affected is returned\n    pub async fn exec_without_returning<C>(self, db: &C) -> Result<u64, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(0);\n        }\n        self.into_one().exec_without_returning(db).await\n    }\n\n    /// Execute an insert operation and return all inserted models\n    pub async fn exec_with_returning<C>(\n        self,\n        db: &C,\n    ) -> Result<Vec<<A::Entity as EntityTrait>::Model>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(Vec::new());\n        }\n\n        self.into_one().exec_with_returning_many(db).await\n    }\n\n    /// Alias to [`InsertMany::exec_with_returning`].\n    #[deprecated(\n        since = \"2.0.0\",\n        note = \"Please use [`InsertMany::exec_with_returning`]\"\n    )]\n    pub async fn exec_with_returning_many<C>(\n        self,\n        db: &C,\n    ) -> Result<Vec<<A::Entity as EntityTrait>::Model>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(Vec::new());\n        }\n\n        self.into_one().exec_with_returning_many(db).await\n    }\n\n    /// Execute an insert operation and return primary keys of inserted models\n    pub async fn exec_with_returning_keys<C>(\n        self,\n        db: &C,\n    ) -> Result<Vec<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        if self.empty {\n            return Ok(Vec::new());\n        }\n\n        self.into_one().exec_with_returning_keys(db).await\n    }\n}\n\nimpl<A> Inserter<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Instantiate a new insert operation\n    pub fn new(primary_key: Option<ValueTuple>, query: InsertStatement) -> Self {\n        Self {\n            primary_key,\n            query,\n            model: PhantomData,\n        }\n    }\n\n    /// Execute an insert operation, returning the last inserted id\n    pub async fn exec<'a, C>(self, db: &'a C) -> Result<InsertResult<A>, DbErr>\n    where\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        exec_insert(self.primary_key, self.query, db).await\n    }\n\n    /// Execute an insert operation\n    pub async fn exec_without_returning<'a, C>(self, db: &'a C) -> Result<u64, DbErr>\n    where\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        exec_insert_without_returning(self.query, db).await\n    }\n\n    /// Execute an insert operation and return the inserted model (use `RETURNING` syntax if supported)\n    pub async fn exec_with_returning<'a, C>(\n        self,\n        db: &'a C,\n    ) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        exec_insert_with_returning::<A, _>(self.primary_key, self.query, db).await\n    }\n\n    /// Execute an insert operation and return primary keys of inserted models\n    pub async fn exec_with_returning_keys<'a, C>(\n        self,\n        db: &'a C,\n    ) -> Result<Vec<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        exec_insert_with_returning_keys::<A, _>(self.query, db).await\n    }\n\n    /// Execute an insert operation and return all inserted models\n    pub async fn exec_with_returning_many<'a, C>(\n        self,\n        db: &'a C,\n    ) -> Result<Vec<<A::Entity as EntityTrait>::Model>, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n        A: 'a,\n    {\n        exec_insert_with_returning_many::<A, _>(self.query, db).await\n    }\n}\n\nasync fn exec_insert<A, C>(\n    primary_key: Option<ValueTuple>,\n    statement: InsertStatement,\n    db: &C,\n) -> Result<InsertResult<A>, DbErr>\nwhere\n    C: ConnectionTrait,\n    A: ActiveModelTrait,\n{\n    type ValueTypeOf<A> = <PrimaryKey<A> as PrimaryKeyTrait>::ValueType;\n\n    let db_backend = db.get_database_backend();\n\n    let last_insert_id = match (primary_key, db.support_returning()) {\n        (_, true) => {\n            let mut rows = db.query_all(&statement).await?;\n            let row = match rows.pop() {\n                Some(row) => row,\n                None => return Err(DbErr::RecordNotInserted),\n            };\n            let cols = PrimaryKey::<A>::iter()\n                .map(|col| col.to_string())\n                .collect::<Vec<_>>();\n            row.try_get_many(\"\", cols.as_ref())\n                .map_err(|_| DbErr::UnpackInsertId)?\n        }\n        (Some(value_tuple), false) => {\n            let res = db.execute(&statement).await?;\n            if res.rows_affected() == 0 {\n                return Err(DbErr::RecordNotInserted);\n            }\n            FromValueTuple::from_value_tuple(value_tuple)\n        }\n        (None, false) => {\n            let res = db.execute(&statement).await?;\n            if res.rows_affected() == 0 {\n                return Err(DbErr::RecordNotInserted);\n            }\n            let last_insert_id = res.last_insert_id();\n            // For MySQL, the affected-rows number:\n            //   - The affected-rows value per row is `1` if the row is inserted as a new row,\n            //   - `2` if an existing row is updated,\n            //   - and `0` if an existing row is set to its current values.\n            // Reference: https://dev.mysql.com/doc/refman/8.4/en/insert-on-duplicate.html\n            if db_backend == DbBackend::MySql && last_insert_id == 0 {\n                return Err(DbErr::RecordNotInserted);\n            }\n            ValueTypeOf::<A>::try_from_u64(last_insert_id).map_err(|_| DbErr::UnpackInsertId)?\n        }\n    };\n\n    Ok(InsertResult { last_insert_id })\n}\n\nasync fn exec_insert_without_returning<C>(\n    insert_statement: InsertStatement,\n    db: &C,\n) -> Result<u64, DbErr>\nwhere\n    C: ConnectionTrait,\n{\n    let exec_result = db.execute(&insert_statement).await?;\n    Ok(exec_result.rows_affected())\n}\n\nasync fn exec_insert_with_returning<A, C>(\n    primary_key: Option<ValueTuple>,\n    mut insert_statement: InsertStatement,\n    db: &C,\n) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\nwhere\n    <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n    C: ConnectionTrait,\n    A: ActiveModelTrait,\n{\n    let db_backend = db.get_database_backend();\n    let found = match db.support_returning() {\n        true => {\n            let returning = Query::returning().exprs(\n                <A::Entity as EntityTrait>::Column::iter()\n                    .map(|c| c.select_as(c.into_returning_expr(db_backend))),\n            );\n            insert_statement.returning(returning);\n            ReturningSelector::<SelectModel<<A::Entity as EntityTrait>::Model>, _>::from_query(\n                insert_statement,\n            )\n            .one(db)\n            .await?\n        }\n        false => {\n            let insert_res = exec_insert::<A, _>(primary_key, insert_statement, db).await?;\n            <A::Entity as EntityTrait>::find_by_id(insert_res.last_insert_id)\n                .one(db)\n                .await?\n        }\n    };\n    match found {\n        Some(model) => Ok(model),\n        None => Err(DbErr::RecordNotFound(\n            \"Failed to find inserted item\".to_owned(),\n        )),\n    }\n}\n\nasync fn exec_insert_with_returning_keys<A, C>(\n    mut insert_statement: InsertStatement,\n    db: &C,\n) -> Result<Vec<<PrimaryKey<A> as PrimaryKeyTrait>::ValueType>, DbErr>\nwhere\n    <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n    C: ConnectionTrait,\n    A: ActiveModelTrait,\n{\n    let db_backend = db.get_database_backend();\n    match db.support_returning() {\n        true => {\n            insert_statement.returning(returning_pk::<A>(db_backend));\n            let rows = db.query_all(&insert_statement).await?;\n            let cols = PrimaryKey::<A>::iter()\n                .map(|col| col.to_string())\n                .collect::<Vec<_>>();\n            let mut keys = Vec::new();\n            for row in rows {\n                keys.push(\n                    row.try_get_many(\"\", cols.as_ref())\n                        .map_err(|_| DbErr::UnpackInsertId)?,\n                );\n            }\n            Ok(keys)\n        }\n        false => Err(DbErr::BackendNotSupported {\n            db: db_backend.as_str(),\n            ctx: \"INSERT RETURNING\",\n        }),\n    }\n}\n\nasync fn exec_insert_with_returning_many<A, C>(\n    mut insert_statement: InsertStatement,\n    db: &C,\n) -> Result<Vec<<A::Entity as EntityTrait>::Model>, DbErr>\nwhere\n    <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n    C: ConnectionTrait,\n    A: ActiveModelTrait,\n{\n    let db_backend = db.get_database_backend();\n    match db.support_returning() {\n        true => {\n            let returning = Query::returning().exprs(\n                <A::Entity as EntityTrait>::Column::iter()\n                    .map(|c| c.select_as(c.into_returning_expr(db_backend))),\n            );\n            insert_statement.returning(returning);\n            ReturningSelector::<SelectModel<<A::Entity as EntityTrait>::Model>, _>::from_query(\n                insert_statement,\n            )\n            .all(db)\n            .await\n        }\n        false => Err(DbErr::BackendNotSupported {\n            db: db_backend.as_str(),\n            ctx: \"INSERT RETURNING\",\n        }),\n    }\n}\n\nfn returning_pk<A>(db_backend: DbBackend) -> ReturningClause\nwhere\n    A: ActiveModelTrait,\n{\n    Query::returning().exprs(<A::Entity as EntityTrait>::PrimaryKey::iter().map(|c| {\n        c.into_column()\n            .select_as(c.into_column().into_returning_expr(db_backend))\n    }))\n}\n"
  },
  {
    "path": "src/executor/mod.rs",
    "content": "mod consolidate;\nmod cursor;\nmod delete;\nmod execute;\nmod insert;\nmod paginator;\nmod query;\nmod returning;\nmod select;\nmod select_ext;\nmod update;\n\nuse consolidate::*;\npub use cursor::*;\npub use delete::*;\npub use execute::*;\npub use insert::*;\npub use paginator::*;\npub use query::*;\nuse returning::*;\npub use select::*;\npub use select_ext::*;\npub use update::*;\n"
  },
  {
    "path": "src/executor/paginator.rs",
    "content": "use crate::{\n    ConnectionTrait, EntityTrait, FromQueryResult, Select, SelectModel, SelectTwo, SelectTwoModel,\n    Selector, SelectorRaw, SelectorTrait, error::*,\n};\nuse async_stream::stream;\nuse futures_util::Stream;\nuse sea_query::{Expr, SelectStatement};\nuse std::{marker::PhantomData, pin::Pin};\n\n#[cfg(not(feature = \"sync\"))]\ntype PinBoxStream<'db, Item> = Pin<Box<dyn Stream<Item = Item> + 'db>>;\n#[cfg(feature = \"sync\")]\ntype PinBoxStream<'db, Item> = Box<dyn Iterator<Item = Item> + 'db>;\n\n/// Defined a structure to handle pagination of a result from a query operation on a Model\n#[derive(Clone, Debug)]\npub struct Paginator<'db, C, S>\nwhere\n    C: ConnectionTrait,\n    S: SelectorTrait + 'db,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) page: u64,\n    pub(crate) page_size: u64,\n    pub(crate) db: &'db C,\n    pub(crate) selector: PhantomData<S>,\n}\n\n/// Define a structure containing the numbers of items and pages of a Paginator\n#[derive(Clone, Debug)]\npub struct ItemsAndPagesNumber {\n    /// The total number of items of a paginator\n    pub number_of_items: u64,\n    /// The total number of pages of a paginator\n    pub number_of_pages: u64,\n}\n\n// LINT: warn if paginator is used without an order by clause\n\nimpl<'db, C, S> Paginator<'db, C, S>\nwhere\n    C: ConnectionTrait,\n    S: SelectorTrait + 'db,\n{\n    /// Fetch a specific page; page index starts from zero\n    pub async fn fetch_page(&self, page: u64) -> Result<Vec<S::Item>, DbErr> {\n        let query = self\n            .query\n            .clone()\n            .limit(self.page_size)\n            .offset(self.page_size * page)\n            .to_owned();\n        let rows = self.db.query_all(&query).await?;\n        let mut buffer = Vec::with_capacity(rows.len());\n        for row in rows.into_iter() {\n            buffer.push(S::from_raw_query_result(row)?);\n        }\n        Ok(buffer)\n    }\n\n    /// Fetch the current page\n    pub async fn fetch(&self) -> Result<Vec<S::Item>, DbErr> {\n        self.fetch_page(self.page).await\n    }\n\n    /// Get the total number of items\n    pub async fn num_items(&self) -> Result<u64, DbErr> {\n        let query = SelectStatement::new()\n            .expr(Expr::cust(\"COUNT(*) AS num_items\"))\n            .from_subquery(\n                self.query\n                    .clone()\n                    .reset_limit()\n                    .reset_offset()\n                    .clear_order_by()\n                    .to_owned(),\n                \"sub_query\",\n            )\n            .to_owned();\n        let result = match self.db.query_one(&query).await? {\n            Some(res) => res,\n            None => return Ok(0),\n        };\n        #[allow(clippy::match_single_binding)]\n        let num_items = match self.db.get_database_backend() {\n            _ => result.try_get::<i64>(\"\", \"num_items\")? as u64,\n        };\n        Ok(num_items)\n    }\n\n    /// Get the total number of pages\n    pub async fn num_pages(&self) -> Result<u64, DbErr> {\n        let num_items = self.num_items().await?;\n        let num_pages = self.compute_pages_number(num_items);\n        Ok(num_pages)\n    }\n\n    /// Get the total number of items and pages\n    pub async fn num_items_and_pages(&self) -> Result<ItemsAndPagesNumber, DbErr> {\n        let number_of_items = self.num_items().await?;\n        let number_of_pages = self.compute_pages_number(number_of_items);\n\n        Ok(ItemsAndPagesNumber {\n            number_of_items,\n            number_of_pages,\n        })\n    }\n\n    /// Compute the number of pages for the current page\n    fn compute_pages_number(&self, num_items: u64) -> u64 {\n        (num_items / self.page_size) + (num_items % self.page_size > 0) as u64\n    }\n\n    /// Increment the page counter\n    pub fn next(&mut self) {\n        self.page += 1;\n    }\n\n    /// Get current page number\n    pub fn cur_page(&self) -> u64 {\n        self.page\n    }\n\n    /// Fetch one page and increment the page counter\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let owned_db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         vec![cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Cake\".to_owned(),\n    /// #         }],\n    /// #         vec![],\n    /// #     ])\n    /// #     .into_connection();\n    /// # let db = &owned_db;\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    /// let mut cake_pages = cake::Entity::find()\n    ///     .order_by_asc(cake::Column::Id)\n    ///     .paginate(db, 50);\n    ///\n    /// while let Some(cakes) = cake_pages.fetch_and_next().await? {\n    ///     // Do something on cakes: Vec<cake::Model>\n    /// }\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub async fn fetch_and_next(&mut self) -> Result<Option<Vec<S::Item>>, DbErr> {\n        let vec = self.fetch().await?;\n        self.next();\n        let opt = if !vec.is_empty() { Some(vec) } else { None };\n        Ok(opt)\n    }\n\n    /// Convert self into an async stream\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(all(feature = \"mock\", not(feature = \"sync\")))]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let owned_db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         vec![cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Cake\".to_owned(),\n    /// #         }],\n    /// #         vec![],\n    /// #     ])\n    /// #     .into_connection();\n    /// # let db = &owned_db;\n    /// #\n    /// use futures_util::TryStreamExt;\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    /// let mut cake_stream = cake::Entity::find()\n    ///     .order_by_asc(cake::Column::Id)\n    ///     .paginate(db, 50)\n    ///     .into_stream();\n    ///\n    /// while let Some(cakes) = cake_stream.try_next().await? {\n    ///     // Do something on cakes: Vec<cake::Model>\n    /// }\n    /// #\n    /// # Ok(())\n    /// # }\n    /// # #[cfg(all(feature = \"mock\", feature = \"sync\"))]\n    /// # fn main() {}\n    /// ```\n    /// (for SeaORM Sync)\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// # #[cfg(all(feature = \"mock\", feature = \"sync\"))]\n    /// # fn example() -> Result<(), DbErr> {\n    /// #\n    /// # let owned_db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         vec![cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Cake\".to_owned(),\n    /// #         }],\n    /// #         vec![],\n    /// #     ])\n    /// #     .into_connection();\n    /// # let db = &owned_db;\n    /// #\n    /// use futures_util::TryStreamExt;\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    /// let mut cake_stream = cake::Entity::find()\n    ///     .order_by_asc(cake::Column::Id)\n    ///     .paginate(db, 50)\n    ///     .into_stream();\n    ///\n    /// while let Some(cakes) = cake_stream.next() {\n    ///     // Do something on cakes: Vec<cake::Model>\n    /// }\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn into_stream(self) -> PinBoxStream<'db, Result<Vec<S::Item>, DbErr>> {\n        #[cfg(not(feature = \"sync\"))]\n        {\n            let mut streamer = self;\n            Box::pin(stream! {\n                while let Some(vec) = streamer.fetch_and_next().await? {\n                    yield Ok(vec);\n                }\n            })\n        }\n        #[cfg(feature = \"sync\")]\n        {\n            Box::new(PaginatorStream { paginator: self })\n        }\n    }\n}\n\n#[cfg(feature = \"sync\")]\n#[derive(Debug)]\n/// Stream items by page\npub struct PaginatorStream<'db, C, S>\nwhere\n    C: ConnectionTrait,\n    S: SelectorTrait + 'db,\n{\n    paginator: Paginator<'db, C, S>,\n}\n\n#[async_trait::async_trait]\n/// A Trait for any type that can paginate results\npub trait PaginatorTrait<'db, C>\nwhere\n    C: ConnectionTrait,\n{\n    /// Select operation\n    type Selector: SelectorTrait + Send + Sync + 'db;\n\n    /// Paginate the result of a select operation.\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector>;\n\n    /// Perform a count on the paginated results\n    async fn count(self, db: &'db C) -> Result<u64, DbErr>\n    where\n        Self: Send + Sized,\n    {\n        self.paginate(db, 1).num_items().await\n    }\n}\n\nimpl<'db, C, S> PaginatorTrait<'db, C> for Selector<S>\nwhere\n    C: ConnectionTrait,\n    S: SelectorTrait + Send + Sync + 'db,\n{\n    type Selector = S;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, S> {\n        assert!(page_size != 0, \"page_size should not be zero\");\n        Paginator {\n            query: self.query,\n            page: 0,\n            page_size,\n            db,\n            selector: PhantomData,\n        }\n    }\n}\n\nimpl<'db, C, S> PaginatorTrait<'db, C> for SelectorRaw<S>\nwhere\n    C: ConnectionTrait,\n    S: SelectorTrait + Send + Sync + 'db,\n{\n    type Selector = S;\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, S> {\n        assert!(page_size != 0, \"page_size should not be zero\");\n        let sql = self.stmt.sql.trim()[6..].trim().to_owned();\n        let mut query = SelectStatement::new();\n        query.expr(if let Some(values) = self.stmt.values {\n            Expr::cust_with_values(sql, values.0)\n        } else {\n            Expr::cust(sql)\n        });\n\n        Paginator {\n            query,\n            page: 0,\n            page_size,\n            db,\n            selector: PhantomData,\n        }\n    }\n}\n\nimpl<'db, C, M, E> PaginatorTrait<'db, C> for Select<E>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait<Model = M>,\n    M: FromQueryResult + Sized + Send + Sync + 'db,\n{\n    type Selector = SelectModel<M>;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {\n        self.into_model().paginate(db, page_size)\n    }\n}\n\nimpl<'db, C, M, N, E, F> PaginatorTrait<'db, C> for SelectTwo<E, F>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait<Model = M>,\n    F: EntityTrait<Model = N>,\n    M: FromQueryResult + Sized + Send + Sync + 'db,\n    N: FromQueryResult + Sized + Send + Sync + 'db,\n{\n    type Selector = SelectTwoModel<M, N>;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {\n        self.into_model().paginate(db, page_size)\n    }\n}\n\n#[cfg(feature = \"sync\")]\nimpl<'db, C, S> Iterator for PaginatorStream<'db, C, S>\nwhere\n    C: ConnectionTrait,\n    S: SelectorTrait + 'db,\n{\n    type Item = Result<Vec<S::Item>, DbErr>;\n\n    fn next(&mut self) -> Option<Self::Item> {\n        match self.paginator.fetch_and_next() {\n            Ok(Some(vec)) => Some(Ok(vec)),\n            Ok(None) => None,\n            Err(e) => Some(Err(e)),\n        }\n    }\n}\n\n#[cfg(test)]\n#[cfg(feature = \"mock\")]\nmod tests {\n    use super::*;\n    use crate::entity::prelude::*;\n    #[cfg(feature = \"sync\")]\n    use crate::util::StreamShim;\n    use crate::{DatabaseConnection, DbBackend, MockDatabase, Transaction};\n    use crate::{QueryOrder, QuerySelect};\n    use crate::{Statement, tests_cfg::*};\n    use futures_util::{TryStreamExt, stream::TryNext};\n    use pretty_assertions::assert_eq;\n    use sea_query::{Expr, SelectStatement, Value};\n    use std::sync::LazyLock;\n\n    static RAW_STMT: LazyLock<Statement> = LazyLock::new(|| {\n        Statement::from_sql_and_values(\n            DbBackend::Postgres,\n            r#\"SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\"\"#,\n            [],\n        )\n    });\n\n    fn setup() -> (DatabaseConnection, Vec<Vec<fruit::Model>>) {\n        let page1 = vec![\n            fruit::Model {\n                id: 1,\n                name: \"Blueberry\".into(),\n                cake_id: Some(1),\n            },\n            fruit::Model {\n                id: 2,\n                name: \"Raspberry\".into(),\n                cake_id: Some(1),\n            },\n        ];\n\n        let page2 = vec![fruit::Model {\n            id: 3,\n            name: \"Strawberry\".into(),\n            cake_id: Some(2),\n        }];\n\n        let page3 = Vec::<fruit::Model>::new();\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([page1.clone(), page2.clone(), page3.clone()])\n            .into_connection();\n\n        (db, vec![page1, page2, page3])\n    }\n\n    fn setup_num_items() -> (DatabaseConnection, i64) {\n        let num_items = 3;\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[maplit::btreemap! {\n                \"num_items\" => Into::<Value>::into(num_items),\n            }]])\n            .into_connection();\n\n        (db, num_items)\n    }\n\n    #[smol_potat::test]\n    async fn fetch_page() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let paginator = fruit::Entity::find().paginate(&db, 2);\n\n        assert_eq!(paginator.fetch_page(0).await?, pages[0].clone());\n        assert_eq!(paginator.fetch_page(1).await?, pages[1].clone());\n        assert_eq!(paginator.fetch_page(2).await?, pages[2].clone());\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn fetch_page_raw() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let paginator = fruit::Entity::find()\n            .from_raw_sql(RAW_STMT.clone())\n            .paginate(&db, 2);\n\n        assert_eq!(paginator.fetch_page(0).await?, pages[0].clone());\n        assert_eq!(paginator.fetch_page(1).await?, pages[1].clone());\n        assert_eq!(paginator.fetch_page(2).await?, pages[2].clone());\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn fetch() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let mut paginator = fruit::Entity::find().paginate(&db, 2);\n\n        assert_eq!(paginator.fetch().await?, pages[0].clone());\n        paginator.next();\n\n        assert_eq!(paginator.fetch().await?, pages[1].clone());\n        paginator.next();\n\n        assert_eq!(paginator.fetch().await?, pages[2].clone());\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn fetch_raw() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let mut paginator = fruit::Entity::find()\n            .from_raw_sql(RAW_STMT.clone())\n            .paginate(&db, 2);\n\n        assert_eq!(paginator.fetch().await?, pages[0].clone());\n        paginator.next();\n\n        assert_eq!(paginator.fetch().await?, pages[1].clone());\n        paginator.next();\n\n        assert_eq!(paginator.fetch().await?, pages[2].clone());\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn num_pages() -> Result<(), DbErr> {\n        let (db, num_items) = setup_num_items();\n\n        let num_items = num_items as u64;\n        let page_size = 2_u64;\n        let num_pages = (num_items / page_size) + (num_items % page_size > 0) as u64;\n        let paginator = fruit::Entity::find().paginate(&db, page_size);\n\n        assert_eq!(paginator.num_pages().await?, num_pages);\n\n        let sub_query = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let select = SelectStatement::new()\n            .expr(Expr::cust(\"COUNT(*) AS num_items\"))\n            .from_subquery(sub_query, \"sub_query\")\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [query_builder.build(&select)];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn num_pages_raw() -> Result<(), DbErr> {\n        let (db, num_items) = setup_num_items();\n\n        let num_items = num_items as u64;\n        let page_size = 2_u64;\n        let num_pages = (num_items / page_size) + (num_items % page_size > 0) as u64;\n        let paginator = fruit::Entity::find()\n            .from_raw_sql(RAW_STMT.clone())\n            .paginate(&db, page_size);\n\n        assert_eq!(paginator.num_pages().await?, num_pages);\n\n        let sub_query = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let select = SelectStatement::new()\n            .expr(Expr::cust(\"COUNT(*) AS num_items\"))\n            .from_subquery(sub_query, \"sub_query\")\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [query_builder.build(&select)];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn next_and_cur_page() -> Result<(), DbErr> {\n        let (db, _) = setup();\n\n        let mut paginator = fruit::Entity::find().paginate(&db, 2);\n\n        assert_eq!(paginator.cur_page(), 0);\n        paginator.next();\n\n        assert_eq!(paginator.cur_page(), 1);\n        paginator.next();\n\n        assert_eq!(paginator.cur_page(), 2);\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn next_and_cur_page_raw() -> Result<(), DbErr> {\n        let (db, _) = setup();\n\n        let mut paginator = fruit::Entity::find()\n            .from_raw_sql(RAW_STMT.clone())\n            .paginate(&db, 2);\n\n        assert_eq!(paginator.cur_page(), 0);\n        paginator.next();\n\n        assert_eq!(paginator.cur_page(), 1);\n        paginator.next();\n\n        assert_eq!(paginator.cur_page(), 2);\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn fetch_and_next() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let mut paginator = fruit::Entity::find().paginate(&db, 2);\n\n        assert_eq!(paginator.cur_page(), 0);\n        assert_eq!(paginator.fetch_and_next().await?, Some(pages[0].clone()));\n\n        assert_eq!(paginator.cur_page(), 1);\n        assert_eq!(paginator.fetch_and_next().await?, Some(pages[1].clone()));\n\n        assert_eq!(paginator.cur_page(), 2);\n        assert_eq!(paginator.fetch_and_next().await?, None);\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn fetch_and_next_raw() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let mut paginator = fruit::Entity::find()\n            .from_raw_sql(RAW_STMT.clone())\n            .paginate(&db, 2);\n\n        assert_eq!(paginator.cur_page(), 0);\n        assert_eq!(paginator.fetch_and_next().await?, Some(pages[0].clone()));\n\n        assert_eq!(paginator.cur_page(), 1);\n        assert_eq!(paginator.fetch_and_next().await?, Some(pages[1].clone()));\n\n        assert_eq!(paginator.cur_page(), 2);\n        assert_eq!(paginator.fetch_and_next().await?, None);\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn into_stream() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let mut fruit_stream = fruit::Entity::find().paginate(&db, 2).into_stream();\n\n        assert_eq!(fruit_stream.try_next().await?, Some(pages[0].clone()));\n        assert_eq!(fruit_stream.try_next().await?, Some(pages[1].clone()));\n        assert_eq!(fruit_stream.try_next().await?, None);\n\n        drop(fruit_stream);\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn into_stream_raw() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let mut fruit_stream = fruit::Entity::find()\n            .from_raw_sql(RAW_STMT.clone())\n            .paginate(&db, 2)\n            .into_stream();\n\n        assert_eq!(fruit_stream.try_next().await?, Some(pages[0].clone()));\n        assert_eq!(fruit_stream.try_next().await?, Some(pages[1].clone()));\n        assert_eq!(fruit_stream.try_next().await?, None);\n\n        drop(fruit_stream);\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn into_stream_raw_leading_spaces() -> Result<(), DbErr> {\n        let (db, pages) = setup();\n\n        let raw_stmt = Statement::from_sql_and_values(\n            DbBackend::Postgres,\n            r#\"  SELECT \"fruit\".\"id\", \"fruit\".\"name\", \"fruit\".\"cake_id\" FROM \"fruit\"  \"#,\n            [],\n        );\n\n        let mut fruit_stream = fruit::Entity::find()\n            .from_raw_sql(raw_stmt.clone())\n            .paginate(&db, 2)\n            .into_stream();\n\n        assert_eq!(fruit_stream.try_next().await?, Some(pages[0].clone()));\n        assert_eq!(fruit_stream.try_next().await?, Some(pages[1].clone()));\n        assert_eq!(fruit_stream.try_next().await?, None);\n\n        drop(fruit_stream);\n\n        let mut select = SelectStatement::new()\n            .exprs([\n                Expr::col((fruit::Entity, fruit::Column::Id)),\n                Expr::col((fruit::Entity, fruit::Column::Name)),\n                Expr::col((fruit::Entity, fruit::Column::CakeId)),\n            ])\n            .from(fruit::Entity)\n            .to_owned();\n\n        let query_builder = db.get_database_backend();\n        let stmts = [\n            query_builder.build(select.clone().offset(0).limit(2)),\n            query_builder.build(select.clone().offset(2).limit(2)),\n            query_builder.build(select.offset(4).limit(2)),\n        ];\n\n        assert_eq!(db.into_transaction_log(), Transaction::wrap(stmts));\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    #[should_panic]\n    async fn error() {\n        let (db, _pages) = setup();\n\n        fruit::Entity::find().paginate(&db, 0);\n    }\n}\n"
  },
  {
    "path": "src/executor/query.rs",
    "content": "pub use crate::error::TryGetError;\nuse crate::{\n    SelectGetableValue, SelectorRaw, Statement,\n    error::{DbErr, type_err},\n};\nuse std::{fmt::Debug, marker::PhantomData, sync::Arc};\n\n#[cfg(any(feature = \"mock\", feature = \"proxy\"))]\nuse crate::debug_print;\n\n#[cfg(feature = \"sqlx-dep\")]\nuse crate::driver::*;\n#[cfg(feature = \"sqlx-dep\")]\nuse sqlx::Row;\n\n/// Defines the result of a query operation on a Model\n#[derive(Debug)]\npub struct QueryResult {\n    pub(crate) row: QueryResultRow,\n}\n\n#[allow(clippy::enum_variant_names)]\npub(crate) enum QueryResultRow {\n    #[cfg(feature = \"sqlx-mysql\")]\n    SqlxMySql(sqlx::mysql::MySqlRow),\n    #[cfg(feature = \"sqlx-postgres\")]\n    SqlxPostgres(sqlx::postgres::PgRow),\n    #[cfg(feature = \"sqlx-sqlite\")]\n    SqlxSqlite(sqlx::sqlite::SqliteRow),\n    #[cfg(feature = \"rusqlite\")]\n    Rusqlite(crate::driver::rusqlite::RusqliteRow),\n    #[cfg(feature = \"mock\")]\n    Mock(crate::MockRow),\n    #[cfg(feature = \"proxy\")]\n    Proxy(crate::ProxyRow),\n}\n\n/// An interface to get a value from the query result\npub trait TryGetable: Sized {\n    /// Get a value from the query result with an ColIdx\n    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError>;\n\n    /// Get a value from the query result with prefixed column name\n    fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TryGetError> {\n        if pre.is_empty() {\n            Self::try_get_by(res, col)\n        } else {\n            Self::try_get_by(res, format!(\"{pre}{col}\").as_str())\n        }\n    }\n\n    /// Get a value from the query result based on the order in the select expressions\n    fn try_get_by_index(res: &QueryResult, index: usize) -> Result<Self, TryGetError> {\n        Self::try_get_by(res, index)\n    }\n}\n\nimpl From<TryGetError> for DbErr {\n    fn from(e: TryGetError) -> DbErr {\n        match e {\n            TryGetError::DbErr(e) => e,\n            TryGetError::Null(s) => {\n                type_err(format!(\"A null value was encountered while decoding {s}\"))\n            }\n        }\n    }\n}\n\nimpl From<DbErr> for TryGetError {\n    fn from(e: DbErr) -> TryGetError {\n        Self::DbErr(e)\n    }\n}\n\n// QueryResult //\n\nimpl QueryResult {\n    /// Get a value from the query result with an ColIdx\n    pub fn try_get_by<T, I>(&self, index: I) -> Result<T, DbErr>\n    where\n        T: TryGetable,\n        I: ColIdx,\n    {\n        Ok(T::try_get_by(self, index)?)\n    }\n\n    /// Get a value from the query result with an ColIdx\n    pub fn try_get_by_nullable<T, I>(&self, index: I) -> Result<T, TryGetError>\n    where\n        T: TryGetable,\n        I: ColIdx,\n    {\n        T::try_get_by(self, index)\n    }\n\n    /// Get a value from the query result with prefixed column name\n    pub fn try_get<T>(&self, pre: &str, col: &str) -> Result<T, DbErr>\n    where\n        T: TryGetable,\n    {\n        Ok(T::try_get(self, pre, col)?)\n    }\n\n    /// Get a value from the query result with prefixed column name\n    pub fn try_get_nullable<T>(&self, pre: &str, col: &str) -> Result<T, TryGetError>\n    where\n        T: TryGetable,\n    {\n        T::try_get(self, pre, col)\n    }\n\n    /// Get a value from the query result based on the order in the select expressions\n    pub fn try_get_by_index<T>(&self, idx: usize) -> Result<T, DbErr>\n    where\n        T: TryGetable,\n    {\n        Ok(T::try_get_by_index(self, idx)?)\n    }\n\n    /// Get a value from the query result based on the order in the select expressions\n    pub fn try_get_by_index_nullable<T>(&self, idx: usize) -> Result<T, TryGetError>\n    where\n        T: TryGetable,\n    {\n        T::try_get_by_index(self, idx)\n    }\n\n    /// Get a tuple value from the query result with prefixed column name\n    pub fn try_get_many<T>(&self, pre: &str, cols: &[String]) -> Result<T, DbErr>\n    where\n        T: TryGetableMany,\n    {\n        Ok(T::try_get_many(self, pre, cols)?)\n    }\n\n    /// Get a tuple value from the query result based on the order in the select expressions\n    pub fn try_get_many_by_index<T>(&self) -> Result<T, DbErr>\n    where\n        T: TryGetableMany,\n    {\n        Ok(T::try_get_many_by_index(self)?)\n    }\n\n    /// Retrieves the names of the columns in the result set\n    pub fn column_names(&self) -> Vec<String> {\n        #[cfg(feature = \"sqlx-dep\")]\n        use sqlx::Column;\n\n        match &self.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(row) => {\n                row.columns().iter().map(|c| c.name().to_string()).collect()\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => {\n                row.columns().iter().map(|c| c.name().to_string()).collect()\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(row) => {\n                row.columns().iter().map(|c| c.name().to_string()).collect()\n            }\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(row) => row.columns().iter().map(|c| c.to_string()).collect(),\n            #[cfg(feature = \"mock\")]\n            QueryResultRow::Mock(row) => row\n                .clone()\n                .into_column_value_tuples()\n                .map(|(c, _)| c.to_string())\n                .collect(),\n            #[cfg(feature = \"proxy\")]\n            QueryResultRow::Proxy(row) => row\n                .clone()\n                .into_column_value_tuples()\n                .map(|(c, _)| c.to_string())\n                .collect(),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n\n    /// Access the underlying `MySqlRow` if we use the MySQL backend.\n    #[cfg(feature = \"sqlx-mysql\")]\n    pub fn try_as_mysql_row(&self) -> Option<&sqlx::mysql::MySqlRow> {\n        match &self.row {\n            QueryResultRow::SqlxMySql(mysql_row) => Some(mysql_row),\n            #[allow(unreachable_patterns)]\n            _ => None,\n        }\n    }\n\n    /// Access the underlying `PgRow` if we use the Postgres backend.\n    #[cfg(feature = \"sqlx-postgres\")]\n    pub fn try_as_pg_row(&self) -> Option<&sqlx::postgres::PgRow> {\n        match &self.row {\n            QueryResultRow::SqlxPostgres(pg_row) => Some(pg_row),\n            #[allow(unreachable_patterns)]\n            _ => None,\n        }\n    }\n\n    /// Access the underlying `SqliteRow` if we use the SQLite backend.\n    #[cfg(feature = \"sqlx-sqlite\")]\n    pub fn try_as_sqlite_row(&self) -> Option<&sqlx::sqlite::SqliteRow> {\n        match &self.row {\n            QueryResultRow::SqlxSqlite(sqlite_row) => Some(sqlite_row),\n            #[allow(unreachable_patterns)]\n            _ => None,\n        }\n    }\n\n    /// Access the underlying `MockRow` if we use a mock.\n    #[cfg(feature = \"mock\")]\n    pub fn try_as_mock_row(&self) -> Option<&crate::MockRow> {\n        match &self.row {\n            QueryResultRow::Mock(mock_row) => Some(mock_row),\n            #[allow(unreachable_patterns)]\n            _ => None,\n        }\n    }\n\n    /// Access the underlying `ProxyRow` if we use a proxy.\n    #[cfg(feature = \"proxy\")]\n    pub fn try_as_proxy_row(&self) -> Option<&crate::ProxyRow> {\n        match &self.row {\n            QueryResultRow::Proxy(proxy_row) => Some(proxy_row),\n            #[allow(unreachable_patterns)]\n            _ => None,\n        }\n    }\n}\n\n#[allow(unused_variables)]\nimpl Debug for QueryResultRow {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        match self {\n            #[cfg(feature = \"sqlx-mysql\")]\n            Self::SqlxMySql(row) => write!(f, \"{row:?}\"),\n            #[cfg(feature = \"sqlx-postgres\")]\n            Self::SqlxPostgres(_) => write!(f, \"QueryResultRow::SqlxPostgres cannot be inspected\"),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            Self::SqlxSqlite(_) => write!(f, \"QueryResultRow::SqlxSqlite cannot be inspected\"),\n            #[cfg(feature = \"rusqlite\")]\n            Self::Rusqlite(row) => write!(f, \"{row:?}\"),\n            #[cfg(feature = \"mock\")]\n            Self::Mock(row) => write!(f, \"{row:?}\"),\n            #[cfg(feature = \"proxy\")]\n            Self::Proxy(row) => write!(f, \"{row:?}\"),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\n// TryGetable //\n\nimpl<T: TryGetable> TryGetable for Option<T> {\n    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError> {\n        match T::try_get_by(res, index) {\n            Ok(v) => Ok(Some(v)),\n            Err(TryGetError::Null(_)) => Ok(None),\n            #[cfg(feature = \"sqlx-dep\")]\n            Err(TryGetError::DbErr(DbErr::Query(crate::RuntimeErr::SqlxError(err)))) => {\n                use std::ops::Deref;\n                match err.deref() {\n                    sqlx::Error::ColumnNotFound(_) => Ok(None),\n                    _ => Err(TryGetError::DbErr(DbErr::Query(\n                        crate::RuntimeErr::SqlxError(err),\n                    ))),\n                }\n            }\n            Err(e) => Err(e),\n        }\n    }\n}\n\n/// Column Index, used by [`TryGetable`]. Implemented for `&str` and `usize`\npub trait ColIdx: Debug + Copy {\n    #[cfg(feature = \"sqlx-mysql\")]\n    /// Type surrogate\n    type SqlxMySqlIndex: sqlx::ColumnIndex<sqlx::mysql::MySqlRow>;\n    #[cfg(feature = \"sqlx-postgres\")]\n    /// Type surrogate\n    type SqlxPostgresIndex: sqlx::ColumnIndex<sqlx::postgres::PgRow>;\n    #[cfg(feature = \"sqlx-sqlite\")]\n    /// Type surrogate\n    type SqlxSqliteIndex: sqlx::ColumnIndex<sqlx::sqlite::SqliteRow>;\n\n    #[cfg(feature = \"sqlx-mysql\")]\n    /// Basically a no-op; only to satisfy trait bounds\n    fn as_sqlx_mysql_index(&self) -> Self::SqlxMySqlIndex;\n    #[cfg(feature = \"sqlx-postgres\")]\n    /// Basically a no-op; only to satisfy trait bounds\n    fn as_sqlx_postgres_index(&self) -> Self::SqlxPostgresIndex;\n    #[cfg(feature = \"sqlx-sqlite\")]\n    /// Basically a no-op; only to satisfy trait bounds\n    fn as_sqlx_sqlite_index(&self) -> Self::SqlxSqliteIndex;\n\n    /// Self must be `&str`, return `None` otherwise\n    fn as_str(&self) -> Option<&str>;\n    /// Self must be `usize`, return `None` otherwise\n    fn as_usize(&self) -> Option<&usize>;\n}\n\nimpl ColIdx for &str {\n    #[cfg(feature = \"sqlx-mysql\")]\n    type SqlxMySqlIndex = Self;\n    #[cfg(feature = \"sqlx-postgres\")]\n    type SqlxPostgresIndex = Self;\n    #[cfg(feature = \"sqlx-sqlite\")]\n    type SqlxSqliteIndex = Self;\n\n    #[cfg(feature = \"sqlx-mysql\")]\n    #[inline]\n    fn as_sqlx_mysql_index(&self) -> Self::SqlxMySqlIndex {\n        self\n    }\n    #[cfg(feature = \"sqlx-postgres\")]\n    #[inline]\n    fn as_sqlx_postgres_index(&self) -> Self::SqlxPostgresIndex {\n        self\n    }\n    #[cfg(feature = \"sqlx-sqlite\")]\n    #[inline]\n    fn as_sqlx_sqlite_index(&self) -> Self::SqlxSqliteIndex {\n        self\n    }\n\n    #[inline]\n    fn as_str(&self) -> Option<&str> {\n        Some(self)\n    }\n    #[inline]\n    fn as_usize(&self) -> Option<&usize> {\n        None\n    }\n}\n\nimpl ColIdx for usize {\n    #[cfg(feature = \"sqlx-mysql\")]\n    type SqlxMySqlIndex = Self;\n    #[cfg(feature = \"sqlx-postgres\")]\n    type SqlxPostgresIndex = Self;\n    #[cfg(feature = \"sqlx-sqlite\")]\n    type SqlxSqliteIndex = Self;\n\n    #[cfg(feature = \"sqlx-mysql\")]\n    #[inline]\n    fn as_sqlx_mysql_index(&self) -> Self::SqlxMySqlIndex {\n        *self\n    }\n    #[cfg(feature = \"sqlx-postgres\")]\n    #[inline]\n    fn as_sqlx_postgres_index(&self) -> Self::SqlxPostgresIndex {\n        *self\n    }\n    #[cfg(feature = \"sqlx-sqlite\")]\n    #[inline]\n    fn as_sqlx_sqlite_index(&self) -> Self::SqlxSqliteIndex {\n        *self\n    }\n\n    #[inline]\n    fn as_str(&self) -> Option<&str> {\n        None\n    }\n    #[inline]\n    fn as_usize(&self) -> Option<&usize> {\n        Some(self)\n    }\n}\n\nmacro_rules! try_getable_all {\n    ( $type: ty ) => {\n        impl TryGetable for $type {\n            #[allow(unused_variables)]\n            fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                match &res.row {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    QueryResultRow::SqlxMySql(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_mysql_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    QueryResultRow::SqlxPostgres(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_postgres_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    QueryResultRow::SqlxSqlite(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_sqlite_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"rusqlite\")]\n                    QueryResultRow::Rusqlite(row) => row\n                        .try_get::<Option<$type>, _>(idx)\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"mock\")]\n                    QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[cfg(feature = \"proxy\")]\n                    QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[allow(unreachable_patterns)]\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\nmacro_rules! try_getable_unsigned {\n    ( $type: ty ) => {\n        impl TryGetable for $type {\n            #[allow(unused_variables)]\n            fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                match &res.row {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    QueryResultRow::SqlxMySql(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_mysql_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    QueryResultRow::SqlxPostgres(_) => Err(type_err(format!(\n                        \"{} unsupported by sqlx-postgres\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    QueryResultRow::SqlxSqlite(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_sqlite_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"rusqlite\")]\n                    QueryResultRow::Rusqlite(row) => row\n                        .try_get::<Option<$type>, _>(idx)\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"mock\")]\n                    QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[cfg(feature = \"proxy\")]\n                    QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[allow(unreachable_patterns)]\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\nmacro_rules! try_getable_mysql {\n    ( $type: ty ) => {\n        impl TryGetable for $type {\n            #[allow(unused_variables)]\n            fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                match &res.row {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    QueryResultRow::SqlxMySql(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_mysql_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    QueryResultRow::SqlxPostgres(_) => Err(type_err(format!(\n                        \"{} unsupported by sqlx-postgres\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    QueryResultRow::SqlxSqlite(_) => Err(type_err(format!(\n                        \"{} unsupported by sqlx-sqlite\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"rusqlite\")]\n                    QueryResultRow::Rusqlite(row) => Err(type_err(format!(\n                        \"{} unsupported by rusqlite\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"mock\")]\n                    QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[cfg(feature = \"proxy\")]\n                    QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[allow(unreachable_patterns)]\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\n#[allow(unused_macros)]\nmacro_rules! try_getable_postgres {\n    ( $type: ty ) => {\n        impl TryGetable for $type {\n            #[allow(unused_variables)]\n            fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                match &res.row {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    QueryResultRow::SqlxMySql(_) => Err(type_err(format!(\n                        \"{} unsupported by sqlx-mysql\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    QueryResultRow::SqlxPostgres(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_postgres_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    QueryResultRow::SqlxSqlite(_) => Err(type_err(format!(\n                        \"{} unsupported by sqlx-sqlite\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"rusqlite\")]\n                    QueryResultRow::Rusqlite(row) => Err(type_err(format!(\n                        \"{} unsupported by rusqlite\",\n                        stringify!($type)\n                    ))\n                    .into()),\n                    #[cfg(feature = \"mock\")]\n                    QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[cfg(feature = \"proxy\")]\n                    QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[allow(unreachable_patterns)]\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\n#[allow(unused_macros)]\nmacro_rules! try_getable_date_time {\n    ( $type: ty ) => {\n        impl TryGetable for $type {\n            #[allow(unused_variables)]\n            fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                match &res.row {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    QueryResultRow::SqlxMySql(row) => {\n                        use chrono::{DateTime, Utc};\n                        row.try_get::<Option<DateTime<Utc>>, _>(idx.as_sqlx_mysql_index())\n                            .map_err(|e| sqlx_error_to_query_err(e).into())\n                            .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                            .map(|v| v.into())\n                    }\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    QueryResultRow::SqlxPostgres(row) => row\n                        .try_get::<Option<$type>, _>(idx.as_sqlx_postgres_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    QueryResultRow::SqlxSqlite(row) => {\n                        use chrono::{DateTime, Utc};\n                        row.try_get::<Option<DateTime<Utc>>, _>(idx.as_sqlx_sqlite_index())\n                            .map_err(|e| sqlx_error_to_query_err(e).into())\n                            .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                            .map(|v| v.into())\n                    }\n                    #[cfg(feature = \"rusqlite\")]\n                    QueryResultRow::Rusqlite(row) => {\n                        use chrono::{DateTime, Utc};\n                        row.try_get::<Option<DateTime<Utc>>, _>(idx)\n                            .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                            .map(|v| v.into())\n                    }\n                    #[cfg(feature = \"mock\")]\n                    QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[cfg(feature = \"proxy\")]\n                    QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[allow(unreachable_patterns)]\n                    _ => unreachable!(),\n                }\n            }\n        }\n    };\n}\n\ntry_getable_all!(bool);\ntry_getable_all!(i8);\ntry_getable_all!(i16);\ntry_getable_all!(i32);\ntry_getable_all!(i64);\ntry_getable_unsigned!(u8);\ntry_getable_unsigned!(u16);\ntry_getable_mysql!(u64);\ntry_getable_all!(f32);\ntry_getable_all!(f64);\ntry_getable_all!(Vec<u8>);\n\n#[cfg(feature = \"with-json\")]\ntry_getable_all!(serde_json::Value);\n\n#[cfg(feature = \"with-chrono\")]\ntry_getable_all!(chrono::NaiveDate);\n\n#[cfg(feature = \"with-chrono\")]\ntry_getable_all!(chrono::NaiveTime);\n\n#[cfg(feature = \"with-chrono\")]\ntry_getable_all!(chrono::NaiveDateTime);\n\n#[cfg(feature = \"with-chrono\")]\ntry_getable_date_time!(chrono::DateTime<chrono::FixedOffset>);\n\n#[cfg(feature = \"with-chrono\")]\ntry_getable_all!(chrono::DateTime<chrono::Utc>);\n\n#[cfg(feature = \"with-chrono\")]\ntry_getable_all!(chrono::DateTime<chrono::Local>);\n\n#[cfg(feature = \"with-time\")]\ntry_getable_all!(time::Date);\n\n#[cfg(feature = \"with-time\")]\ntry_getable_all!(time::Time);\n\n#[cfg(feature = \"with-time\")]\ntry_getable_all!(time::PrimitiveDateTime);\n\n#[cfg(feature = \"with-time\")]\ntry_getable_all!(time::OffsetDateTime);\n\n#[cfg(feature = \"with-rust_decimal\")]\nuse rust_decimal::Decimal;\n\n#[cfg(feature = \"with-rust_decimal\")]\nimpl TryGetable for Decimal {\n    #[allow(unused_variables)]\n    fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(row) => row\n                .try_get::<Option<Decimal>, _>(idx.as_sqlx_mysql_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => row\n                .try_get::<Option<Decimal>, _>(idx.as_sqlx_postgres_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(row) => {\n                let val: Option<f64> = row\n                    .try_get(idx.as_sqlx_sqlite_index())\n                    .map_err(sqlx_error_to_query_err)?;\n                match val {\n                    Some(v) => Decimal::try_from(v).map_err(|e| {\n                        DbErr::TryIntoErr {\n                            from: \"f64\",\n                            into: \"Decimal\",\n                            source: Arc::new(e),\n                        }\n                        .into()\n                    }),\n                    None => Err(err_null_idx_col(idx)),\n                }\n            }\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(row) => {\n                let val: Option<f64> = row.try_get(idx)?;\n                match val {\n                    Some(v) => Decimal::try_from(v).map_err(|e| {\n                        DbErr::TryIntoErr {\n                            from: \"f64\",\n                            into: \"Decimal\",\n                            source: Arc::new(e),\n                        }\n                        .into()\n                    }),\n                    None => Err(err_null_idx_col(idx)),\n                }\n            }\n            #[cfg(feature = \"mock\")]\n            #[allow(unused_variables)]\n            QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[cfg(feature = \"proxy\")]\n            #[allow(unused_variables)]\n            QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(feature = \"with-bigdecimal\")]\nuse bigdecimal::BigDecimal;\n\n#[cfg(feature = \"with-bigdecimal\")]\nimpl TryGetable for BigDecimal {\n    #[allow(unused_variables)]\n    fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(row) => row\n                .try_get::<Option<BigDecimal>, _>(idx.as_sqlx_mysql_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => row\n                .try_get::<Option<BigDecimal>, _>(idx.as_sqlx_postgres_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(row) => {\n                let val: Option<f64> = row\n                    .try_get(idx.as_sqlx_sqlite_index())\n                    .map_err(sqlx_error_to_query_err)?;\n                match val {\n                    Some(v) => BigDecimal::try_from(v).map_err(|e| {\n                        DbErr::TryIntoErr {\n                            from: \"f64\",\n                            into: \"BigDecimal\",\n                            source: Arc::new(e),\n                        }\n                        .into()\n                    }),\n                    None => Err(err_null_idx_col(idx)),\n                }\n            }\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(row) => {\n                let val: Option<f64> = row.try_get(idx)?;\n                match val {\n                    Some(v) => BigDecimal::try_from(v).map_err(|e| {\n                        DbErr::TryIntoErr {\n                            from: \"f64\",\n                            into: \"BigDecimal\",\n                            source: Arc::new(e),\n                        }\n                        .into()\n                    }),\n                    None => Err(err_null_idx_col(idx)),\n                }\n            }\n            #[cfg(feature = \"mock\")]\n            #[allow(unused_variables)]\n            QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[cfg(feature = \"proxy\")]\n            #[allow(unused_variables)]\n            QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[allow(unused_macros)]\nmacro_rules! try_getable_uuid {\n    ( $type: ty, $conversion_fn: expr ) => {\n        #[allow(unused_variables, unreachable_code)]\n        impl TryGetable for $type {\n            fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                let res: Result<uuid::Uuid, TryGetError> = match &res.row {\n                    #[cfg(feature = \"sqlx-mysql\")]\n                    QueryResultRow::SqlxMySql(row) => row\n                        .try_get::<Option<uuid::Uuid>, _>(idx.as_sqlx_mysql_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                        .or_else(|_| {\n                            // MariaDB's UUID type stores UUIDs as hyphenated strings.\n                            // reference: https://github.com/SeaQL/sea-orm/pull/2485\n                            row.try_get::<Option<Vec<u8>>, _>(idx.as_sqlx_mysql_index())\n                                .map_err(|e| sqlx_error_to_query_err(e).into())\n                                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                                .map(|bytes| {\n                                    String::from_utf8(bytes).map_err(|e| {\n                                        DbErr::TryIntoErr {\n                                            from: \"Vec<u8>\",\n                                            into: \"String\",\n                                            source: Arc::new(e),\n                                        }\n                                        .into()\n                                    })\n                                })?\n                                .and_then(|s| {\n                                    uuid::Uuid::parse_str(&s).map_err(|e| {\n                                        DbErr::TryIntoErr {\n                                            from: \"String\",\n                                            into: \"uuid::Uuid\",\n                                            source: Arc::new(e),\n                                        }\n                                        .into()\n                                    })\n                                })\n                        }),\n                    #[cfg(feature = \"sqlx-postgres\")]\n                    QueryResultRow::SqlxPostgres(row) => row\n                        .try_get::<Option<uuid::Uuid>, _>(idx.as_sqlx_postgres_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"sqlx-sqlite\")]\n                    QueryResultRow::SqlxSqlite(row) => row\n                        .try_get::<Option<uuid::Uuid>, _>(idx.as_sqlx_sqlite_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"rusqlite\")]\n                    QueryResultRow::Rusqlite(row) => row\n                        .try_get::<Option<uuid::Uuid>, _>(idx)\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                    #[cfg(feature = \"mock\")]\n                    #[allow(unused_variables)]\n                    QueryResultRow::Mock(row) => row.try_get::<uuid::Uuid, _>(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[cfg(feature = \"proxy\")]\n                    #[allow(unused_variables)]\n                    QueryResultRow::Proxy(row) => row.try_get::<uuid::Uuid, _>(idx).map_err(|e| {\n                        debug_print!(\"{:#?}\", e.to_string());\n                        err_null_idx_col(idx)\n                    }),\n                    #[allow(unreachable_patterns)]\n                    _ => unreachable!(),\n                };\n                res.map($conversion_fn)\n            }\n        }\n    };\n}\n\n#[cfg(feature = \"with-uuid\")]\ntry_getable_uuid!(uuid::Uuid, Into::into);\n\n#[cfg(feature = \"with-uuid\")]\ntry_getable_uuid!(uuid::fmt::Braced, uuid::Uuid::braced);\n\n#[cfg(feature = \"with-uuid\")]\ntry_getable_uuid!(uuid::fmt::Hyphenated, uuid::Uuid::hyphenated);\n\n#[cfg(feature = \"with-uuid\")]\ntry_getable_uuid!(uuid::fmt::Simple, uuid::Uuid::simple);\n\n#[cfg(feature = \"with-uuid\")]\ntry_getable_uuid!(uuid::fmt::Urn, uuid::Uuid::urn);\n\n#[cfg(feature = \"with-ipnetwork\")]\ntry_getable_postgres!(ipnetwork::IpNetwork);\n\n#[cfg(feature = \"with-mac_address\")]\ntry_getable_postgres!(mac_address::MacAddress);\n\nimpl TryGetable for u32 {\n    #[allow(unused_variables)]\n    fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(row) => row\n                .try_get::<Option<u32>, _>(idx.as_sqlx_mysql_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => {\n                use sqlx::postgres::types::Oid;\n                // Since 0.6.0, SQLx has dropped direct mapping from PostgreSQL's OID to Rust's `u32`;\n                // Instead, `u32` was wrapped by a `sqlx::Oid`.\n                match row.try_get::<Option<Oid>, _>(idx.as_sqlx_postgres_index()) {\n                    Ok(opt) => opt.ok_or_else(|| err_null_idx_col(idx)).map(|oid| oid.0),\n                    Err(_) => row\n                        // Integers are always signed in PostgreSQL, so we try to get an `i32` and convert it to `u32`.\n                        .try_get::<i32, _>(idx.as_sqlx_postgres_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .map(|v| {\n                            v.try_into().map_err(|e| {\n                                DbErr::TryIntoErr {\n                                    from: \"i32\",\n                                    into: \"u32\",\n                                    source: Arc::new(e),\n                                }\n                                .into()\n                            })\n                        })\n                        .and_then(|r| r),\n                }\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(row) => row\n                .try_get::<Option<u32>, _>(idx.as_sqlx_sqlite_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(row) => row\n                .try_get::<Option<u32>, _>(idx)\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"mock\")]\n            #[allow(unused_variables)]\n            QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[cfg(feature = \"proxy\")]\n            #[allow(unused_variables)]\n            QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\nimpl TryGetable for String {\n    #[allow(unused_variables)]\n    fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(row) => row\n                .try_get::<Option<Vec<u8>>, _>(idx.as_sqlx_mysql_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                .map(|bytes| {\n                    String::from_utf8(bytes).map_err(|e| {\n                        DbErr::TryIntoErr {\n                            from: \"Vec<u8>\",\n                            into: \"String\",\n                            source: Arc::new(e),\n                        }\n                        .into()\n                    })\n                })?,\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => row\n                .try_get::<Option<String>, _>(idx.as_sqlx_postgres_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(row) => row\n                .try_get::<Option<String>, _>(idx.as_sqlx_sqlite_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(row) => row\n                .try_get::<Option<String>, _>(idx)\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"mock\")]\n            QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[cfg(feature = \"proxy\")]\n            QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[allow(dead_code)]\nfn err_null_idx_col<I: ColIdx>(idx: I) -> TryGetError {\n    TryGetError::Null(format!(\"{idx:?}\"))\n}\n\n#[cfg(feature = \"postgres-array\")]\nmod postgres_array {\n    use super::*;\n\n    #[allow(unused_macros)]\n    macro_rules! try_getable_postgres_array {\n        ( $type: ty ) => {\n            #[allow(unused_variables)]\n            impl TryGetable for Vec<$type> {\n                fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                    match &res.row {\n                        #[cfg(feature = \"sqlx-mysql\")]\n                        QueryResultRow::SqlxMySql(_) => Err(type_err(format!(\n                            \"{} unsupported by sqlx-mysql\",\n                            stringify!($type)\n                        ))\n                        .into()),\n                        #[cfg(feature = \"sqlx-postgres\")]\n                        QueryResultRow::SqlxPostgres(row) => row\n                            .try_get::<Option<Vec<$type>>, _>(idx.as_sqlx_postgres_index())\n                            .map_err(|e| sqlx_error_to_query_err(e).into())\n                            .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                        #[cfg(feature = \"sqlx-sqlite\")]\n                        QueryResultRow::SqlxSqlite(_) => Err(type_err(format!(\n                            \"{} unsupported by sqlx-sqlite\",\n                            stringify!($type)\n                        ))\n                        .into()),\n                        #[cfg(feature = \"rusqlite\")]\n                        QueryResultRow::Rusqlite(_) => Err(type_err(format!(\n                            \"{} unsupported by rusqlite\",\n                            stringify!($type)\n                        ))\n                        .into()),\n                        #[cfg(feature = \"mock\")]\n                        #[allow(unused_variables)]\n                        QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                            debug_print!(\"{:#?}\", e.to_string());\n                            err_null_idx_col(idx)\n                        }),\n                        #[cfg(feature = \"proxy\")]\n                        #[allow(unused_variables)]\n                        QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                            debug_print!(\"{:#?}\", e.to_string());\n                            err_null_idx_col(idx)\n                        }),\n                        #[allow(unreachable_patterns)]\n                        _ => unreachable!(),\n                    }\n                }\n            }\n        };\n    }\n\n    try_getable_postgres_array!(bool);\n    try_getable_postgres_array!(i8);\n    try_getable_postgres_array!(i16);\n    try_getable_postgres_array!(i32);\n    try_getable_postgres_array!(i64);\n    try_getable_postgres_array!(f32);\n    try_getable_postgres_array!(f64);\n    try_getable_postgres_array!(String);\n    try_getable_postgres_array!(Vec<u8>);\n\n    #[cfg(feature = \"with-json\")]\n    try_getable_postgres_array!(serde_json::Value);\n\n    #[cfg(feature = \"with-chrono\")]\n    try_getable_postgres_array!(chrono::NaiveDate);\n\n    #[cfg(feature = \"with-chrono\")]\n    try_getable_postgres_array!(chrono::NaiveTime);\n\n    #[cfg(feature = \"with-chrono\")]\n    try_getable_postgres_array!(chrono::NaiveDateTime);\n\n    #[cfg(feature = \"with-chrono\")]\n    try_getable_postgres_array!(chrono::DateTime<chrono::FixedOffset>);\n\n    #[cfg(feature = \"with-chrono\")]\n    try_getable_postgres_array!(chrono::DateTime<chrono::Utc>);\n\n    #[cfg(feature = \"with-chrono\")]\n    try_getable_postgres_array!(chrono::DateTime<chrono::Local>);\n\n    #[cfg(feature = \"with-time\")]\n    try_getable_postgres_array!(time::Date);\n\n    #[cfg(feature = \"with-time\")]\n    try_getable_postgres_array!(time::Time);\n\n    #[cfg(feature = \"with-time\")]\n    try_getable_postgres_array!(time::PrimitiveDateTime);\n\n    #[cfg(feature = \"with-time\")]\n    try_getable_postgres_array!(time::OffsetDateTime);\n\n    #[cfg(feature = \"with-rust_decimal\")]\n    try_getable_postgres_array!(rust_decimal::Decimal);\n\n    #[cfg(feature = \"with-bigdecimal\")]\n    try_getable_postgres_array!(bigdecimal::BigDecimal);\n\n    #[cfg(feature = \"with-ipnetwork\")]\n    try_getable_postgres_array!(ipnetwork::IpNetwork);\n\n    #[cfg(feature = \"with-mac_address\")]\n    try_getable_postgres_array!(mac_address::MacAddress);\n\n    #[allow(unused_macros)]\n    macro_rules! try_getable_postgres_array_uuid {\n        ( $type: ty, $conversion_fn: expr ) => {\n            #[allow(unused_variables, unreachable_code)]\n            impl TryGetable for Vec<$type> {\n                fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n                    let res: Result<Vec<uuid::Uuid>, TryGetError> = match &res.row {\n                        #[cfg(feature = \"sqlx-mysql\")]\n                        QueryResultRow::SqlxMySql(_) => Err(type_err(format!(\n                            \"{} unsupported by sqlx-mysql\",\n                            stringify!($type)\n                        ))\n                        .into()),\n                        #[cfg(feature = \"sqlx-postgres\")]\n                        QueryResultRow::SqlxPostgres(row) => row\n                            .try_get::<Option<Vec<uuid::Uuid>>, _>(idx.as_sqlx_postgres_index())\n                            .map_err(|e| sqlx_error_to_query_err(e).into())\n                            .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n                        #[cfg(feature = \"sqlx-sqlite\")]\n                        QueryResultRow::SqlxSqlite(_) => Err(type_err(format!(\n                            \"{} unsupported by sqlx-sqlite\",\n                            stringify!($type)\n                        ))\n                        .into()),\n                        #[cfg(feature = \"rusqlite\")]\n                        QueryResultRow::Rusqlite(_) => Err(type_err(format!(\n                            \"{} unsupported by rusqlite\",\n                            stringify!($type)\n                        ))\n                        .into()),\n                        #[cfg(feature = \"mock\")]\n                        QueryResultRow::Mock(row) => {\n                            row.try_get::<Vec<uuid::Uuid>, _>(idx).map_err(|e| {\n                                debug_print!(\"{:#?}\", e.to_string());\n                                err_null_idx_col(idx)\n                            })\n                        }\n                        #[cfg(feature = \"proxy\")]\n                        QueryResultRow::Proxy(row) => {\n                            row.try_get::<Vec<uuid::Uuid>, _>(idx).map_err(|e| {\n                                debug_print!(\"{:#?}\", e.to_string());\n                                err_null_idx_col(idx)\n                            })\n                        }\n                        #[allow(unreachable_patterns)]\n                        _ => unreachable!(),\n                    };\n                    res.map(|vec| vec.into_iter().map($conversion_fn).collect())\n                }\n            }\n        };\n    }\n\n    #[cfg(feature = \"with-uuid\")]\n    try_getable_postgres_array_uuid!(uuid::Uuid, Into::into);\n\n    #[cfg(feature = \"with-uuid\")]\n    try_getable_postgres_array_uuid!(uuid::fmt::Braced, uuid::Uuid::braced);\n\n    #[cfg(feature = \"with-uuid\")]\n    try_getable_postgres_array_uuid!(uuid::fmt::Hyphenated, uuid::Uuid::hyphenated);\n\n    #[cfg(feature = \"with-uuid\")]\n    try_getable_postgres_array_uuid!(uuid::fmt::Simple, uuid::Uuid::simple);\n\n    #[cfg(feature = \"with-uuid\")]\n    try_getable_postgres_array_uuid!(uuid::fmt::Urn, uuid::Uuid::urn);\n\n    impl TryGetable for Vec<u32> {\n        #[allow(unused_variables)]\n        fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n            match &res.row {\n                #[cfg(feature = \"sqlx-mysql\")]\n                QueryResultRow::SqlxMySql(_) => {\n                    Err(type_err(format!(\"{} unsupported by sqlx-mysql\", stringify!($type))).into())\n                }\n                #[cfg(feature = \"sqlx-postgres\")]\n                QueryResultRow::SqlxPostgres(row) => {\n                    use sqlx::postgres::types::Oid;\n                    // Since 0.6.0, SQLx has dropped direct mapping from PostgreSQL's OID to Rust's `u32`;\n                    // Instead, `u32` was wrapped by a `sqlx::Oid`.\n                    row.try_get::<Option<Vec<Oid>>, _>(idx.as_sqlx_postgres_index())\n                        .map_err(|e| sqlx_error_to_query_err(e).into())\n                        .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)))\n                        .map(|oids| oids.into_iter().map(|oid| oid.0).collect())\n                }\n                #[cfg(feature = \"sqlx-sqlite\")]\n                QueryResultRow::SqlxSqlite(_) => Err(type_err(format!(\n                    \"{} unsupported by sqlx-sqlite\",\n                    stringify!($type)\n                ))\n                .into()),\n                #[cfg(feature = \"rusqlite\")]\n                QueryResultRow::Rusqlite(_) => {\n                    Err(type_err(format!(\"{} unsupported by rusqlite\", stringify!($type))).into())\n                }\n                #[cfg(feature = \"mock\")]\n                #[allow(unused_variables)]\n                QueryResultRow::Mock(row) => row.try_get(idx).map_err(|e| {\n                    debug_print!(\"{:#?}\", e.to_string());\n                    err_null_idx_col(idx)\n                }),\n                #[cfg(feature = \"proxy\")]\n                #[allow(unused_variables)]\n                QueryResultRow::Proxy(row) => row.try_get(idx).map_err(|e| {\n                    debug_print!(\"{:#?}\", e.to_string());\n                    err_null_idx_col(idx)\n                }),\n                #[allow(unreachable_patterns)]\n                _ => unreachable!(),\n            }\n        }\n    }\n}\n\n#[cfg(feature = \"postgres-vector\")]\nimpl TryGetable for pgvector::Vector {\n    #[allow(unused_variables)]\n    fn try_get_by<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(_) => {\n                Err(type_err(\"Vector unsupported by sqlx-mysql\").into())\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => row\n                .try_get::<Option<pgvector::Vector>, _>(idx.as_sqlx_postgres_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx))),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(_) => {\n                Err(type_err(\"Vector unsupported by sqlx-sqlite\").into())\n            }\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(_) => Err(type_err(\"Vector unsupported by rusqlite\").into()),\n            #[cfg(feature = \"mock\")]\n            QueryResultRow::Mock(row) => row.try_get::<pgvector::Vector, _>(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[cfg(feature = \"proxy\")]\n            QueryResultRow::Proxy(row) => row.try_get::<pgvector::Vector, _>(idx).map_err(|e| {\n                debug_print!(\"{:#?}\", e.to_string());\n                err_null_idx_col(idx)\n            }),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\n// TryGetableMany //\n\n/// An interface to get a tuple value from the query result\npub trait TryGetableMany: Sized {\n    /// Get a tuple value from the query result with prefixed column name\n    fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError>;\n\n    /// Get a tuple value from the query result based on the order in the select expressions\n    fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError>;\n\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(all(feature = \"mock\", feature = \"macros\"))]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(1),\n    /// #         },\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"New York Cheese\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(1),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{DeriveIden, EnumIter, TryGetableMany, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// #[derive(EnumIter, DeriveIden)]\n    /// enum ResultCol {\n    ///     Name,\n    ///     NumOfCakes,\n    /// }\n    ///\n    /// let res: Vec<(String, i32)> =\n    ///     <(String, i32)>::find_by_statement::<ResultCol>(Statement::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"name\", count(\"cake\".\"id\") AS \"num_of_cakes\" FROM \"cake\"\"#,\n    ///         [],\n    ///     ))\n    ///     .all(&db)\n    ///     .await?;\n    ///\n    /// assert_eq!(\n    ///     res,\n    ///     [\n    ///         (\"Chocolate Forest\".to_owned(), 1),\n    ///         (\"New York Cheese\".to_owned(), 1),\n    ///     ]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"name\", count(\"cake\".\"id\") AS \"num_of_cakes\" FROM \"cake\"\"#,\n    ///         []\n    ///     ),]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    fn find_by_statement<C>(stmt: Statement) -> SelectorRaw<SelectGetableValue<Self, C>>\n    where\n        C: strum::IntoEnumIterator + sea_query::Iden,\n    {\n        SelectorRaw {\n            stmt,\n            selector: PhantomData,\n        }\n    }\n}\n\nimpl<T> TryGetableMany for T\nwhere\n    T: TryGetable,\n{\n    fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError> {\n        try_get_many_with_slice_len_of(1, cols)?;\n        T::try_get(res, pre, &cols[0])\n    }\n\n    fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {\n        T::try_get_by_index(res, 0)\n    }\n}\n\nimpl<T> TryGetableMany for (T,)\nwhere\n    T: TryGetableMany,\n{\n    fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError> {\n        T::try_get_many(res, pre, cols).map(|r| (r,))\n    }\n\n    fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {\n        T::try_get_many_by_index(res).map(|r| (r,))\n    }\n}\n\nmacro_rules! impl_try_get_many {\n    ( $LEN:expr, $($T:ident : $N:expr),+ $(,)? ) => {\n        impl< $($T),+ > TryGetableMany for ( $($T),+ )\n        where\n            $($T: TryGetable),+\n        {\n            fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError> {\n                try_get_many_with_slice_len_of($LEN, cols)?;\n                Ok((\n                    $($T::try_get(res, pre, &cols[$N])?),+\n                ))\n            }\n\n            fn try_get_many_by_index(res: &QueryResult) -> Result<Self, TryGetError> {\n                Ok((\n                    $($T::try_get_by_index(res, $N)?),+\n                ))\n            }\n        }\n    };\n}\n\n#[rustfmt::skip]\nmod impl_try_get_many {\n    use super::*;\n\n    impl_try_get_many!( 2, T0:0, T1:1);\n    impl_try_get_many!( 3, T0:0, T1:1, T2:2);\n    impl_try_get_many!( 4, T0:0, T1:1, T2:2, T3:3);\n    impl_try_get_many!( 5, T0:0, T1:1, T2:2, T3:3, T4:4);\n    impl_try_get_many!( 6, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5);\n    impl_try_get_many!( 7, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6);\n    impl_try_get_many!( 8, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7);\n    impl_try_get_many!( 9, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8);\n    impl_try_get_many!(10, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9);\n    impl_try_get_many!(11, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9, T10:10);\n    impl_try_get_many!(12, T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9, T10:10, T11:11);\n}\n\nfn try_get_many_with_slice_len_of(len: usize, cols: &[String]) -> Result<(), TryGetError> {\n    if cols.len() < len {\n        Err(type_err(format!(\n            \"Expect {} column names supplied but got slice of length {}\",\n            len,\n            cols.len()\n        ))\n        .into())\n    } else {\n        Ok(())\n    }\n}\n\n/// An interface to get an array of values from the query result.\n/// A type can only implement `ActiveEnum` or `TryGetableFromJson`, but not both.\n/// A blanket impl is provided for `TryGetableFromJson`, while the impl for `ActiveEnum`\n/// is provided by the `DeriveActiveEnum` macro. So as an end user you won't normally\n/// touch this trait.\npub trait TryGetableArray: Sized {\n    /// Just a delegate\n    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Vec<Self>, TryGetError>;\n}\n\nimpl<T> TryGetable for Vec<T>\nwhere\n    T: TryGetableArray,\n{\n    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError> {\n        T::try_get_by(res, index)\n    }\n}\n\n// TryGetableFromJson //\n\n/// An interface to get a JSON from the query result\n#[cfg(feature = \"with-json\")]\npub trait TryGetableFromJson: Sized\nwhere\n    for<'de> Self: serde::Deserialize<'de>,\n{\n    /// Get a JSON from the query result with prefixed column name\n    #[allow(unused_variables, unreachable_code)]\n    fn try_get_from_json<I: ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            QueryResultRow::SqlxMySql(row) => row\n                .try_get::<Option<sqlx::types::Json<Self>>, _>(idx.as_sqlx_mysql_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)).map(|json| json.0)),\n            #[cfg(feature = \"sqlx-postgres\")]\n            QueryResultRow::SqlxPostgres(row) => row\n                .try_get::<Option<sqlx::types::Json<Self>>, _>(idx.as_sqlx_postgres_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)).map(|json| json.0)),\n            #[cfg(feature = \"sqlx-sqlite\")]\n            QueryResultRow::SqlxSqlite(row) => row\n                .try_get::<Option<sqlx::types::Json<Self>>, _>(idx.as_sqlx_sqlite_index())\n                .map_err(|e| sqlx_error_to_query_err(e).into())\n                .and_then(|opt| opt.ok_or_else(|| err_null_idx_col(idx)).map(|json| json.0)),\n            #[cfg(feature = \"rusqlite\")]\n            QueryResultRow::Rusqlite(row) => row\n                .try_get::<Option<serde_json::Value>, _>(idx)?\n                .ok_or_else(|| err_null_idx_col(idx))\n                .and_then(|json| {\n                    serde_json::from_value(json).map_err(|e| crate::error::json_err(e).into())\n                }),\n            #[cfg(feature = \"mock\")]\n            QueryResultRow::Mock(row) => row\n                .try_get::<serde_json::Value, I>(idx)\n                .map_err(|e| {\n                    debug_print!(\"{:#?}\", e.to_string());\n                    err_null_idx_col(idx)\n                })\n                .and_then(|json| {\n                    serde_json::from_value(json).map_err(|e| crate::error::json_err(e).into())\n                }),\n            #[cfg(feature = \"proxy\")]\n            QueryResultRow::Proxy(row) => row\n                .try_get::<serde_json::Value, I>(idx)\n                .map_err(|e| {\n                    debug_print!(\"{:#?}\", e.to_string());\n                    err_null_idx_col(idx)\n                })\n                .and_then(|json| {\n                    serde_json::from_value(json).map_err(|e| crate::error::json_err(e).into())\n                }),\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n\n    /// Get a Vec<Self> from an Array of Json\n    fn from_json_vec(value: serde_json::Value) -> Result<Vec<Self>, TryGetError> {\n        match value {\n            serde_json::Value::Array(values) => {\n                let mut res = Vec::new();\n                for item in values {\n                    res.push(serde_json::from_value(item).map_err(crate::error::json_err)?);\n                }\n                Ok(res)\n            }\n            _ => Err(TryGetError::DbErr(DbErr::Json(\n                \"Value is not an Array\".to_owned(),\n            ))),\n        }\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl<T> TryGetable for T\nwhere\n    T: TryGetableFromJson,\n{\n    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Self, TryGetError> {\n        T::try_get_from_json(res, index)\n    }\n}\n\n#[cfg(feature = \"with-json\")]\nimpl<T> TryGetableArray for T\nwhere\n    T: TryGetableFromJson,\n{\n    fn try_get_by<I: ColIdx>(res: &QueryResult, index: I) -> Result<Vec<T>, TryGetError> {\n        T::from_json_vec(serde_json::Value::try_get_by(res, index)?)\n    }\n}\n\n// TryFromU64 //\n/// Try to convert a type to a u64\npub trait TryFromU64: Sized {\n    /// The method to convert the type to a u64\n    fn try_from_u64(n: u64) -> Result<Self, DbErr>;\n}\n\nmacro_rules! try_from_u64_err {\n    ( $type: ty ) => {\n        impl TryFromU64 for $type {\n            fn try_from_u64(_: u64) -> Result<Self, DbErr> {\n                Err(DbErr::ConvertFromU64(stringify!($type)))\n            }\n        }\n    };\n\n    ( $($gen_type: ident),* ) => {\n        impl<$( $gen_type, )*> TryFromU64 for ($( $gen_type, )*)\n        where\n            $( $gen_type: TryFromU64, )*\n        {\n            fn try_from_u64(_: u64) -> Result<Self, DbErr> {\n                Err(DbErr::ConvertFromU64(stringify!($($gen_type,)*)))\n            }\n        }\n    };\n}\n\n#[rustfmt::skip]\nmod try_from_u64_err {\n    use super::*;\n\n    try_from_u64_err!(T0, T1);\n    try_from_u64_err!(T0, T1, T2);\n    try_from_u64_err!(T0, T1, T2, T3);\n    try_from_u64_err!(T0, T1, T2, T3, T4);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5, T6);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5, T6, T7);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5, T6, T7, T8);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);\n    try_from_u64_err!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);\n}\n\nmacro_rules! try_from_u64_numeric {\n    ( $type: ty ) => {\n        impl TryFromU64 for $type {\n            fn try_from_u64(n: u64) -> Result<Self, DbErr> {\n                use std::convert::TryInto;\n                n.try_into().map_err(|e| DbErr::TryIntoErr {\n                    from: stringify!(u64),\n                    into: stringify!($type),\n                    source: Arc::new(e),\n                })\n            }\n        }\n    };\n}\n\ntry_from_u64_numeric!(i8);\ntry_from_u64_numeric!(i16);\ntry_from_u64_numeric!(i32);\ntry_from_u64_numeric!(i64);\ntry_from_u64_numeric!(u8);\ntry_from_u64_numeric!(u16);\ntry_from_u64_numeric!(u32);\ntry_from_u64_numeric!(u64);\n\nmacro_rules! try_from_u64_string {\n    ( $type: ty ) => {\n        impl TryFromU64 for $type {\n            fn try_from_u64(n: u64) -> Result<Self, DbErr> {\n                Ok(n.to_string())\n            }\n        }\n    };\n}\n\ntry_from_u64_string!(String);\n\ntry_from_u64_err!(bool);\ntry_from_u64_err!(f32);\ntry_from_u64_err!(f64);\ntry_from_u64_err!(Vec<u8>);\n\n#[cfg(feature = \"with-json\")]\ntry_from_u64_err!(serde_json::Value);\n\n#[cfg(feature = \"with-chrono\")]\ntry_from_u64_err!(chrono::NaiveDate);\n\n#[cfg(feature = \"with-chrono\")]\ntry_from_u64_err!(chrono::NaiveTime);\n\n#[cfg(feature = \"with-chrono\")]\ntry_from_u64_err!(chrono::NaiveDateTime);\n\n#[cfg(feature = \"with-chrono\")]\ntry_from_u64_err!(chrono::DateTime<chrono::FixedOffset>);\n\n#[cfg(feature = \"with-chrono\")]\ntry_from_u64_err!(chrono::DateTime<chrono::Utc>);\n\n#[cfg(feature = \"with-chrono\")]\ntry_from_u64_err!(chrono::DateTime<chrono::Local>);\n\n#[cfg(feature = \"with-time\")]\ntry_from_u64_err!(time::Date);\n\n#[cfg(feature = \"with-time\")]\ntry_from_u64_err!(time::Time);\n\n#[cfg(feature = \"with-time\")]\ntry_from_u64_err!(time::PrimitiveDateTime);\n\n#[cfg(feature = \"with-time\")]\ntry_from_u64_err!(time::OffsetDateTime);\n\n#[cfg(feature = \"with-rust_decimal\")]\ntry_from_u64_err!(rust_decimal::Decimal);\n\n#[cfg(feature = \"with-uuid\")]\ntry_from_u64_err!(uuid::Uuid);\n\n#[cfg(feature = \"with-ipnetwork\")]\ntry_from_u64_err!(ipnetwork::IpNetwork);\n\n#[cfg(feature = \"with-mac_address\")]\ntry_from_u64_err!(mac_address::MacAddress);\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use crate::RuntimeErr;\n    use sea_query::Value;\n    use std::collections::BTreeMap;\n\n    #[test]\n    fn from_try_get_error() {\n        // TryGetError::DbErr\n        let try_get_error = TryGetError::DbErr(DbErr::Query(RuntimeErr::Internal(\n            \"expected error message\".to_owned(),\n        )));\n        assert_eq!(\n            DbErr::from(try_get_error),\n            DbErr::Query(RuntimeErr::Internal(\"expected error message\".to_owned()))\n        );\n\n        // TryGetError::Null\n        let try_get_error = TryGetError::Null(\"column\".to_owned());\n        let expected = \"A null value was encountered while decoding column\".to_owned();\n        assert_eq!(DbErr::from(try_get_error), DbErr::Type(expected));\n    }\n\n    #[test]\n    fn build_with_query() {\n        use sea_orm::{DbBackend, Statement};\n        use sea_query::{\n            ColumnRef, CommonTableExpression, Cycle, Expr, ExprTrait, JoinType, SelectStatement,\n            UnionType, WithClause,\n        };\n\n        let base_query = SelectStatement::new()\n            .column(\"id\")\n            .expr(1i32)\n            .column(\"next\")\n            .column(\"value\")\n            .from(\"table\")\n            .to_owned();\n\n        let cte_referencing = SelectStatement::new()\n            .column(\"id\")\n            .expr(Expr::col(\"depth\").add(1i32))\n            .column(\"next\")\n            .column(\"value\")\n            .from(\"table\")\n            .join(\n                JoinType::InnerJoin,\n                \"cte_traversal\",\n                Expr::col((\"cte_traversal\", \"next\")).equals((\"table\", \"id\")),\n            )\n            .to_owned();\n\n        let common_table_expression = CommonTableExpression::new()\n            .query(\n                base_query\n                    .clone()\n                    .union(UnionType::All, cte_referencing)\n                    .to_owned(),\n            )\n            .columns([\"id\", \"depth\", \"next\", \"value\"])\n            .table_name(\"cte_traversal\")\n            .to_owned();\n\n        let select = SelectStatement::new()\n            .column(ColumnRef::Asterisk(None))\n            .from(\"cte_traversal\")\n            .to_owned();\n\n        let with_clause = WithClause::new()\n            .recursive(true)\n            .cte(common_table_expression)\n            .cycle(Cycle::new_from_expr_set_using(\n                Expr::column(\"id\"),\n                \"looped\",\n                \"traversal_path\",\n            ))\n            .to_owned();\n\n        let with_query = select.with(with_clause).to_owned();\n\n        assert_eq!(\n            DbBackend::MySql.build(&with_query),\n            Statement::from_sql_and_values(\n                DbBackend::MySql,\n                r\"WITH RECURSIVE `cte_traversal` (`id`, `depth`, `next`, `value`) AS (SELECT `id`, ?, `next`, `value` FROM `table` UNION ALL (SELECT `id`, `depth` + ?, `next`, `value` FROM `table` INNER JOIN `cte_traversal` ON `cte_traversal`.`next` = `table`.`id`)) SELECT * FROM `cte_traversal`\",\n                [1.into(), 1.into()]\n            )\n        );\n    }\n\n    #[test]\n    fn column_names_from_query_result() {\n        let mut values = BTreeMap::new();\n        values.insert(\"id\".to_string(), Value::Int(Some(1)));\n        values.insert(\"name\".to_string(), Value::String(Some(\"Abc\".to_owned())));\n        let query_result = QueryResult {\n            row: QueryResultRow::Mock(crate::MockRow { values }),\n        };\n        assert_eq!(\n            query_result.column_names(),\n            vec![\"id\".to_owned(), \"name\".to_owned()]\n        );\n    }\n}\n"
  },
  {
    "path": "src/executor/returning.rs",
    "content": "use super::SelectorTrait;\nuse crate::{ConnectionTrait, StatementBuilder, error::*};\nuse itertools::Itertools;\nuse std::marker::PhantomData;\n\n#[derive(Clone, Debug)]\npub(super) struct ReturningSelector<S, Q>\nwhere\n    S: SelectorTrait,\n    Q: StatementBuilder,\n{\n    pub(crate) query: Q,\n    selector: PhantomData<S>,\n}\n\nimpl<S, Q> ReturningSelector<S, Q>\nwhere\n    S: SelectorTrait,\n    Q: StatementBuilder,\n{\n    pub fn from_query(query: Q) -> Self {\n        Self {\n            query,\n            selector: PhantomData,\n        }\n    }\n\n    pub async fn one<C>(self, db: &C) -> Result<Option<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let row = db.query_one(&self.query).await?;\n        match row {\n            Some(row) => Ok(Some(S::from_raw_query_result(row)?)),\n            None => Ok(None),\n        }\n    }\n\n    pub async fn all<C>(self, db: &C) -> Result<Vec<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        db.query_all(&self.query)\n            .await?\n            .into_iter()\n            .map(|row| S::from_raw_query_result(row))\n            .try_collect()\n    }\n}\n"
  },
  {
    "path": "src/executor/select/five.rs",
    "content": "use super::*;\nuse crate::{\n    JoinType, Paginator, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, QueryTrait, Related,\n    SelectC, SelectFive, SelectSix, Topology, TopologyStar,\n    combine::{SelectD, SelectE, prepare_select_col},\n};\n\nimpl<E, F, G, H, I, TOP> SelectFive<E, F, G, H, I, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query).prepare_select()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<I, _, _>(&mut self, SelectE);\n        self\n    }\n\n    /// Left Join with a Related Entity and select all Entities.\n    pub fn find_also<T, J>(self, _: T, _: J) -> SelectSix<E, F, G, H, I, J, TopologyStar>\n    where\n        J: EntityTrait,\n        T: EntityTrait + Related<J>,\n    {\n        SelectSix::new(\n            self.join_join(JoinType::LeftJoin, T::to(), T::via())\n                .into_query(),\n        )\n    }\n}\n\nmacro_rules! impl_query_trait {\n    ( $trait: ident ) => {\n        impl<E, F, G, H, I, TOP> $trait for SelectFive<E, F, G, H, I, TOP>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n            G: EntityTrait,\n            H: EntityTrait,\n            I: EntityTrait,\n            TOP: Topology,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n    };\n}\n\nimpl<E, F, G, H, I, TOP> QueryTrait for SelectFive<E, F, G, H, I, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    TOP: Topology,\n{\n    type QueryStatement = SelectStatement;\n    fn query(&mut self) -> &mut SelectStatement {\n        &mut self.query\n    }\n    fn as_query(&self) -> &SelectStatement {\n        &self.query\n    }\n    fn into_query(self) -> SelectStatement {\n        self.query\n    }\n}\n\nimpl_query_trait!(QuerySelect);\nimpl_query_trait!(QueryFilter);\nimpl_query_trait!(QueryOrder);\n\nimpl<M, N, O, P, Q> SelectorTrait for SelectFiveModel<M, N, O, P, Q>\nwhere\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n    O: FromQueryResult + Sized,\n    P: FromQueryResult + Sized,\n    Q: FromQueryResult + Sized,\n{\n    type Item = (M, Option<N>, Option<O>, Option<P>, Option<Q>);\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, SelectA.as_str())?,\n            N::from_query_result_optional(&res, SelectB.as_str())?,\n            O::from_query_result_optional(&res, SelectC.as_str())?,\n            P::from_query_result_optional(&res, SelectD.as_str())?,\n            Q::from_query_result_optional(&res, SelectE.as_str())?,\n        ))\n    }\n}\n\nimpl<E, F, G, H, I, TOP> SelectFive<E, F, G, H, I, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    TOP: Topology,\n{\n    /// Perform a conversion into a [SelectFiveModel]\n    pub fn into_model<M, N, O, P, Q>(self) -> Selector<SelectFiveModel<M, N, O, P, Q>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n        O: FromQueryResult,\n        P: FromQueryResult,\n        Q: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Perform a conversion into a [SelectFiveModel] with [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M, N, O, P, Q>(self) -> Selector<SelectFiveModel<M, N, O, P, Q>>\n    where\n        M: PartialModelTrait,\n        N: PartialModelTrait,\n        O: PartialModelTrait,\n        P: PartialModelTrait,\n        Q: PartialModelTrait,\n    {\n        let select = QuerySelect::select_only(self);\n        let select = M::select_cols(select);\n        let select = N::select_cols(select);\n        let select = O::select_cols(select);\n        let select = P::select_cols(select);\n        let select = Q::select_cols(select);\n        select.into_model::<M, N, O, P, Q>()\n    }\n\n    /// Convert the Models into JsonValue\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(\n        self,\n    ) -> Selector<SelectFiveModel<JsonValue, JsonValue, JsonValue, JsonValue, JsonValue>> {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the Select query\n    pub async fn one<C>(\n        self,\n        db: &C,\n    ) -> Result<\n        Option<(\n            E::Model,\n            Option<F::Model>,\n            Option<G::Model>,\n            Option<H::Model>,\n            Option<I::Model>,\n        )>,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db).await\n    }\n\n    /// Get all Models from the Select query\n    pub async fn all<C>(\n        self,\n        db: &C,\n    ) -> Result<\n        Vec<(\n            E::Model,\n            Option<F::Model>,\n            Option<G::Model>,\n            Option<H::Model>,\n            Option<I::Model>,\n        )>,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db).await\n    }\n\n    /// Stream the results of a Select operation on a Model\n    pub async fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<\n        impl Stream<\n            Item = Result<\n                (\n                    E::Model,\n                    Option<F::Model>,\n                    Option<G::Model>,\n                    Option<H::Model>,\n                    Option<I::Model>,\n                ),\n                DbErr,\n            >,\n        > + 'b,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n    {\n        self.into_model().stream(db).await\n    }\n}\n\nimpl<'db, C, EE, FF, GG, HH, II, E, F, G, H, I, TOP> PaginatorTrait<'db, C>\n    for SelectFive<E, F, G, H, I, TOP>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait<Model = EE>,\n    F: EntityTrait<Model = FF>,\n    G: EntityTrait<Model = GG>,\n    H: EntityTrait<Model = HH>,\n    I: EntityTrait<Model = II>,\n    EE: FromQueryResult + Sized + Send + Sync + 'db,\n    FF: FromQueryResult + Sized + Send + Sync + 'db,\n    GG: FromQueryResult + Sized + Send + Sync + 'db,\n    HH: FromQueryResult + Sized + Send + Sync + 'db,\n    II: FromQueryResult + Sized + Send + Sync + 'db,\n    TOP: Topology,\n{\n    type Selector = SelectFiveModel<EE, FF, GG, HH, II>;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {\n        self.into_model().paginate(db, page_size)\n    }\n}\n"
  },
  {
    "path": "src/executor/select/four.rs",
    "content": "use super::*;\nuse crate::{\n    JoinType, Paginator, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, QueryTrait, Related,\n    SelectC, SelectFive, SelectFour, Topology, TopologyStar,\n    combine::{SelectD, prepare_select_col},\n};\n\nimpl<E, F, G, H, TOP> SelectFour<E, F, G, H, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query).prepare_select()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<H, _, _>(&mut self, SelectD);\n        self\n    }\n\n    /// Left Join with a Related Entity and select all Entities.\n    pub fn find_also<T, I>(self, _: T, _: I) -> SelectFive<E, F, G, H, I, TopologyStar>\n    where\n        I: EntityTrait,\n        T: EntityTrait + Related<I>,\n    {\n        SelectFive::new(\n            self.join_join(JoinType::LeftJoin, T::to(), T::via())\n                .into_query(),\n        )\n    }\n}\n\nmacro_rules! impl_query_trait {\n    ( $trait: ident ) => {\n        impl<E, F, G, H, TOP> $trait for SelectFour<E, F, G, H, TOP>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n            G: EntityTrait,\n            H: EntityTrait,\n            TOP: Topology,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n    };\n}\n\nimpl<E, F, G, H, TOP> QueryTrait for SelectFour<E, F, G, H, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    TOP: Topology,\n{\n    type QueryStatement = SelectStatement;\n    fn query(&mut self) -> &mut SelectStatement {\n        &mut self.query\n    }\n    fn as_query(&self) -> &SelectStatement {\n        &self.query\n    }\n    fn into_query(self) -> SelectStatement {\n        self.query\n    }\n}\n\nimpl_query_trait!(QuerySelect);\nimpl_query_trait!(QueryFilter);\nimpl_query_trait!(QueryOrder);\n\nimpl<M, N, O, P> SelectorTrait for SelectFourModel<M, N, O, P>\nwhere\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n    O: FromQueryResult + Sized,\n    P: FromQueryResult + Sized,\n{\n    type Item = (M, Option<N>, Option<O>, Option<P>);\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, SelectA.as_str())?,\n            N::from_query_result_optional(&res, SelectB.as_str())?,\n            O::from_query_result_optional(&res, SelectC.as_str())?,\n            P::from_query_result_optional(&res, SelectD.as_str())?,\n        ))\n    }\n}\n\nimpl<E, F, G, H, TOP> SelectFour<E, F, G, H, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    TOP: Topology,\n{\n    /// Perform a conversion into a [SelectFourModel]\n    pub fn into_model<M, N, O, P>(self) -> Selector<SelectFourModel<M, N, O, P>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n        O: FromQueryResult,\n        P: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Perform a conversion into a [SelectFourModel] with [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M, N, O, P>(self) -> Selector<SelectFourModel<M, N, O, P>>\n    where\n        M: PartialModelTrait,\n        N: PartialModelTrait,\n        O: PartialModelTrait,\n        P: PartialModelTrait,\n    {\n        let select = QuerySelect::select_only(self);\n        let select = M::select_cols(select);\n        let select = N::select_cols(select);\n        let select = O::select_cols(select);\n        let select = P::select_cols(select);\n        select.into_model::<M, N, O, P>()\n    }\n\n    /// Convert the Models into JsonValue\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(\n        self,\n    ) -> Selector<SelectFourModel<JsonValue, JsonValue, JsonValue, JsonValue>> {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the Select query\n    pub async fn one<C>(\n        self,\n        db: &C,\n    ) -> Result<\n        Option<(\n            E::Model,\n            Option<F::Model>,\n            Option<G::Model>,\n            Option<H::Model>,\n        )>,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db).await\n    }\n\n    /// Get all Models from the Select query\n    pub async fn all<C>(\n        self,\n        db: &C,\n    ) -> Result<\n        Vec<(\n            E::Model,\n            Option<F::Model>,\n            Option<G::Model>,\n            Option<H::Model>,\n        )>,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db).await\n    }\n\n    /// Stream the results of a Select operation on a Model\n    pub async fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<\n        impl Stream<\n            Item = Result<\n                (\n                    E::Model,\n                    Option<F::Model>,\n                    Option<G::Model>,\n                    Option<H::Model>,\n                ),\n                DbErr,\n            >,\n        > + 'b,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n    {\n        self.into_model().stream(db).await\n    }\n\n    /// Stream the result of the operation with PartialModel\n    pub async fn stream_partial_model<'a: 'b, 'b, C, M, N, O, P>(\n        self,\n        db: &'a C,\n    ) -> Result<\n        impl Stream<Item = Result<(M, Option<N>, Option<O>, Option<P>), DbErr>> + 'b + Send,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n        M: PartialModelTrait + Send + 'b,\n        N: PartialModelTrait + Send + 'b,\n        O: PartialModelTrait + Send + 'b,\n        P: PartialModelTrait + Send + 'b,\n    {\n        self.into_partial_model().stream(db).await\n    }\n}\n\nimpl<'db, C, EE, FF, GG, HH, E, F, G, H, TOP> PaginatorTrait<'db, C> for SelectFour<E, F, G, H, TOP>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait<Model = EE>,\n    F: EntityTrait<Model = FF>,\n    G: EntityTrait<Model = GG>,\n    H: EntityTrait<Model = HH>,\n    EE: FromQueryResult + Sized + Send + Sync + 'db,\n    FF: FromQueryResult + Sized + Send + Sync + 'db,\n    GG: FromQueryResult + Sized + Send + Sync + 'db,\n    HH: FromQueryResult + Sized + Send + Sync + 'db,\n    TOP: Topology,\n{\n    type Selector = SelectFourModel<EE, FF, GG, HH>;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {\n        self.into_model().paginate(db, page_size)\n    }\n}\n"
  },
  {
    "path": "src/executor/select/six.rs",
    "content": "use super::*;\nuse crate::{\n    Paginator, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, QueryTrait, SelectC,\n    SelectSix, Topology,\n    combine::{SelectD, SelectE, SelectF, prepare_select_col},\n};\n\nimpl<E, F, G, H, I, J, TOP> SelectSix<E, F, G, H, I, J, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    J: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query).prepare_select()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<J, _, _>(&mut self, SelectF);\n        self\n    }\n}\n\nmacro_rules! impl_query_trait {\n    ( $trait: ident ) => {\n        impl<E, F, G, H, I, J, TOP> $trait for SelectSix<E, F, G, H, I, J, TOP>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n            G: EntityTrait,\n            H: EntityTrait,\n            I: EntityTrait,\n            J: EntityTrait,\n            TOP: Topology,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n    };\n}\n\nimpl<E, F, G, H, I, J, TOP> QueryTrait for SelectSix<E, F, G, H, I, J, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    J: EntityTrait,\n    TOP: Topology,\n{\n    type QueryStatement = SelectStatement;\n    fn query(&mut self) -> &mut SelectStatement {\n        &mut self.query\n    }\n    fn as_query(&self) -> &SelectStatement {\n        &self.query\n    }\n    fn into_query(self) -> SelectStatement {\n        self.query\n    }\n}\n\nimpl_query_trait!(QuerySelect);\nimpl_query_trait!(QueryFilter);\nimpl_query_trait!(QueryOrder);\n\nimpl<M, N, O, P, Q, R> SelectorTrait for SelectSixModel<M, N, O, P, Q, R>\nwhere\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n    O: FromQueryResult + Sized,\n    P: FromQueryResult + Sized,\n    Q: FromQueryResult + Sized,\n    R: FromQueryResult + Sized,\n{\n    type Item = (M, Option<N>, Option<O>, Option<P>, Option<Q>, Option<R>);\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, SelectA.as_str())?,\n            N::from_query_result_optional(&res, SelectB.as_str())?,\n            O::from_query_result_optional(&res, SelectC.as_str())?,\n            P::from_query_result_optional(&res, SelectD.as_str())?,\n            Q::from_query_result_optional(&res, SelectE.as_str())?,\n            R::from_query_result_optional(&res, SelectF.as_str())?,\n        ))\n    }\n}\n\nimpl<E, F, G, H, I, J, TOP> SelectSix<E, F, G, H, I, J, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    J: EntityTrait,\n    TOP: Topology,\n{\n    /// Perform a conversion into a [SelectSixModel]\n    pub fn into_model<M, N, O, P, Q, R>(self) -> Selector<SelectSixModel<M, N, O, P, Q, R>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n        O: FromQueryResult,\n        P: FromQueryResult,\n        Q: FromQueryResult,\n        R: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Perform a conversion into a [SelectSixModel] with [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M, N, O, P, Q, R>(self) -> Selector<SelectSixModel<M, N, O, P, Q, R>>\n    where\n        M: PartialModelTrait,\n        N: PartialModelTrait,\n        O: PartialModelTrait,\n        P: PartialModelTrait,\n        Q: PartialModelTrait,\n        R: PartialModelTrait,\n    {\n        let select = QuerySelect::select_only(self);\n        let select = M::select_cols(select);\n        let select = N::select_cols(select);\n        let select = O::select_cols(select);\n        let select = P::select_cols(select);\n        let select = Q::select_cols(select);\n        let select = R::select_cols(select);\n        select.into_model::<M, N, O, P, Q, R>()\n    }\n\n    /// Convert the Models into JsonValue\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(\n        self,\n    ) -> Selector<SelectSixModel<JsonValue, JsonValue, JsonValue, JsonValue, JsonValue, JsonValue>>\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the Select query\n    pub async fn one<C>(\n        self,\n        db: &C,\n    ) -> Result<\n        Option<(\n            E::Model,\n            Option<F::Model>,\n            Option<G::Model>,\n            Option<H::Model>,\n            Option<I::Model>,\n            Option<J::Model>,\n        )>,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db).await\n    }\n\n    /// Get all Models from the Select query\n    pub async fn all<C>(\n        self,\n        db: &C,\n    ) -> Result<\n        Vec<(\n            E::Model,\n            Option<F::Model>,\n            Option<G::Model>,\n            Option<H::Model>,\n            Option<I::Model>,\n            Option<J::Model>,\n        )>,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db).await\n    }\n\n    /// Stream the results of a Select operation on a Model\n    pub async fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<\n        impl Stream<\n            Item = Result<\n                (\n                    E::Model,\n                    Option<F::Model>,\n                    Option<G::Model>,\n                    Option<H::Model>,\n                    Option<I::Model>,\n                    Option<J::Model>,\n                ),\n                DbErr,\n            >,\n        > + 'b,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n    {\n        self.into_model().stream(db).await\n    }\n}\n\nimpl<'db, C, EE, FF, GG, HH, II, JJ, E, F, G, H, I, J, TOP> PaginatorTrait<'db, C>\n    for SelectSix<E, F, G, H, I, J, TOP>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait<Model = EE>,\n    F: EntityTrait<Model = FF>,\n    G: EntityTrait<Model = GG>,\n    H: EntityTrait<Model = HH>,\n    I: EntityTrait<Model = II>,\n    J: EntityTrait<Model = JJ>,\n    EE: FromQueryResult + Sized + Send + Sync + 'db,\n    FF: FromQueryResult + Sized + Send + Sync + 'db,\n    GG: FromQueryResult + Sized + Send + Sync + 'db,\n    HH: FromQueryResult + Sized + Send + Sync + 'db,\n    II: FromQueryResult + Sized + Send + Sync + 'db,\n    JJ: FromQueryResult + Sized + Send + Sync + 'db,\n    TOP: Topology,\n{\n    type Selector = SelectSixModel<EE, FF, GG, HH, II, JJ>;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {\n        self.into_model().paginate(db, page_size)\n    }\n}\n"
  },
  {
    "path": "src/executor/select/three.rs",
    "content": "use super::*;\nuse crate::{\n    JoinType, Paginator, PaginatorTrait, QueryFilter, QueryOrder, QuerySelect, QueryTrait, Related,\n    SelectC, SelectFour, SelectThree, SelectThreeMany, Topology, TopologyChain, TopologyStar,\n    combine::prepare_select_col,\n};\n\nimpl<E, F, G, TOP> SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query).prepare_select()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<G, _, _>(&mut self, SelectC);\n        self\n    }\n\n    /// Left Join with a Related Entity and select all Entities.\n    pub fn find_also<T, H>(self, _: T, _: H) -> SelectFour<E, F, G, H, TopologyStar>\n    where\n        H: EntityTrait,\n        T: EntityTrait + Related<H>,\n    {\n        SelectFour::new(\n            self.join_join(JoinType::LeftJoin, T::to(), T::via())\n                .into_query(),\n        )\n    }\n}\n\nmacro_rules! impl_query_trait {\n    ( $trait: ident ) => {\n        impl<E, F, G, TOP> $trait for SelectThree<E, F, G, TOP>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n            G: EntityTrait,\n            TOP: Topology,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n    };\n}\n\nimpl<E, F, G, TOP> QueryTrait for SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    type QueryStatement = SelectStatement;\n    fn query(&mut self) -> &mut SelectStatement {\n        &mut self.query\n    }\n    fn as_query(&self) -> &SelectStatement {\n        &self.query\n    }\n    fn into_query(self) -> SelectStatement {\n        self.query\n    }\n}\n\nimpl_query_trait!(QuerySelect);\nimpl_query_trait!(QueryFilter);\nimpl_query_trait!(QueryOrder);\n\nimpl<M, N, O> SelectorTrait for SelectThreeModel<M, N, O>\nwhere\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n    O: FromQueryResult + Sized,\n{\n    type Item = (M, Option<N>, Option<O>);\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, SelectA.as_str())?,\n            N::from_query_result_optional(&res, SelectB.as_str())?,\n            O::from_query_result_optional(&res, SelectC.as_str())?,\n        ))\n    }\n}\n\nimpl<E, F, G, TOP> SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    /// Perform a conversion into a [SelectThreeModel]\n    pub fn into_model<M, N, O>(self) -> Selector<SelectThreeModel<M, N, O>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n        O: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Perform a conversion into a [SelectThreeModel] with [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M, N, O>(self) -> Selector<SelectThreeModel<M, N, O>>\n    where\n        M: PartialModelTrait,\n        N: PartialModelTrait,\n        O: PartialModelTrait,\n    {\n        let select = QuerySelect::select_only(self);\n        let select = M::select_cols(select);\n        let select = N::select_cols(select);\n        let select = O::select_cols(select);\n        select.into_model::<M, N, O>()\n    }\n\n    /// Convert the Models into JsonValue\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(self) -> Selector<SelectThreeModel<JsonValue, JsonValue, JsonValue>> {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the Select query\n    pub async fn one<C>(\n        self,\n        db: &C,\n    ) -> Result<Option<(E::Model, Option<F::Model>, Option<G::Model>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db).await\n    }\n\n    /// Get all Models from the Select query\n    pub async fn all<C>(\n        self,\n        db: &C,\n    ) -> Result<Vec<(E::Model, Option<F::Model>, Option<G::Model>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db).await\n    }\n\n    /// Stream the results of a Select operation on a Model\n    pub async fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<\n        impl Stream<Item = Result<(E::Model, Option<F::Model>, Option<G::Model>), DbErr>> + 'b,\n        DbErr,\n    >\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n    {\n        self.into_model().stream(db).await\n    }\n\n    /// Stream the result of the operation with PartialModel\n    pub async fn stream_partial_model<'a: 'b, 'b, C, M, N, O>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Stream<Item = Result<(M, Option<N>, Option<O>), DbErr>> + 'b + Send, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n        M: PartialModelTrait + Send + 'b,\n        N: PartialModelTrait + Send + 'b,\n        O: PartialModelTrait + Send + 'b,\n    {\n        self.into_partial_model().stream(db).await\n    }\n\n    /// Consolidate query result by first / second model depending on join topology\n    /// ```\n    /// # use sea_orm::{tests_cfg::*, *};\n    /// # async fn function(db: &DbConn) -> Result<(), DbErr> {\n    /// // fruit -> cake -> filling\n    /// let items: Vec<(fruit::Model, Vec<(cake::Model, Vec<filling::Model>)>)> = fruit::Entity::find()\n    ///     .find_also_related(cake::Entity)\n    ///     .and_also_related(filling::Entity)\n    ///     .consolidate()\n    ///     .all(db)\n    ///     .await?;\n    ///\n    /// // cake -> fruit\n    /// //      -> filling\n    /// let items: Vec<(cake::Model, Vec<fruit::Model>, Vec<filling::Model>)> = cake::Entity::find()\n    ///     .find_also_related(fruit::Entity)\n    ///     .find_also_related(filling::Entity)\n    ///     .consolidate()\n    ///     .all(db)\n    ///     .await?;\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn consolidate(self) -> SelectThreeMany<E, F, G, TOP> {\n        SelectThreeMany {\n            query: self.query,\n            entity: self.entity,\n        }\n    }\n}\n\nimpl<E, F, G, TOP> SelectThreeMany<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    /// Performs a conversion to [Selector]\n    fn into_model<M, N, O>(self) -> Selector<SelectThreeModel<M, N, O>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n        O: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n}\n\nimpl<E, F, G> SelectThreeMany<E, F, G, TopologyStar>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n{\n    /// Execute query and consolidate rows by E\n    pub async fn all<C>(\n        self,\n        db: &C,\n    ) -> Result<Vec<(E::Model, Vec<F::Model>, Vec<G::Model>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let rows = self.into_model().all(db).await?;\n        Ok(consolidate_query_result_tee::<E, F, G>(rows))\n    }\n}\n\nimpl<E, F, G> SelectThreeMany<E, F, G, TopologyChain>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n{\n    /// Execute query and consolidate rows in two passes, first by E, then by F\n    pub async fn all<C>(\n        self,\n        db: &C,\n    ) -> Result<Vec<(E::Model, Vec<(F::Model, Vec<G::Model>)>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let rows = self.into_model().all(db).await?;\n        Ok(consolidate_query_result_chain::<E, F, G>(rows))\n    }\n}\n\nimpl<'db, C, M, N, O, E, F, G, TOP> PaginatorTrait<'db, C> for SelectThree<E, F, G, TOP>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait<Model = M>,\n    F: EntityTrait<Model = N>,\n    G: EntityTrait<Model = O>,\n    M: FromQueryResult + Sized + Send + Sync + 'db,\n    N: FromQueryResult + Sized + Send + Sync + 'db,\n    O: FromQueryResult + Sized + Send + Sync + 'db,\n    TOP: Topology,\n{\n    type Selector = SelectThreeModel<M, N, O>;\n\n    fn paginate(self, db: &'db C, page_size: u64) -> Paginator<'db, C, Self::Selector> {\n        self.into_model().paginate(db, page_size)\n    }\n}\n"
  },
  {
    "path": "src/executor/select.rs",
    "content": "use super::{\n    consolidate_query_result, consolidate_query_result_chain, consolidate_query_result_tee,\n};\nuse crate::{\n    ConnectionTrait, DbBackend, EntityTrait, FromQueryResult, IdenStatic, PartialModelTrait,\n    QueryResult, QuerySelect, Select, SelectA, SelectB, SelectTwo, SelectTwoMany,\n    SelectTwoRequired, Statement, StreamTrait, TryGetableMany, error::*,\n};\nuse futures_util::{Stream, TryStreamExt};\nuse itertools::Itertools;\nuse sea_query::SelectStatement;\nuse std::{marker::PhantomData, pin::Pin};\n\nmod five;\nmod four;\nmod six;\nmod three;\n\n#[cfg(feature = \"with-json\")]\nuse crate::JsonValue;\n\n#[cfg(not(feature = \"sync\"))]\ntype PinBoxStream<'b, S> = Pin<Box<dyn Stream<Item = Result<S, DbErr>> + 'b + Send>>;\n#[cfg(feature = \"sync\")]\ntype PinBoxStream<'b, S> = Box<dyn Iterator<Item = Result<S, DbErr>> + 'b + Send>;\n\n/// Defines a type to do `SELECT` operations through a [SelectStatement] on a Model\n#[derive(Clone, Debug)]\npub struct Selector<S>\nwhere\n    S: SelectorTrait,\n{\n    pub(crate) query: SelectStatement,\n    selector: PhantomData<S>,\n}\n\n/// Performs a raw `SELECT` operation on a model\n#[derive(Clone, Debug)]\npub struct SelectorRaw<S>\nwhere\n    S: SelectorTrait,\n{\n    pub(crate) stmt: Statement,\n    pub(super) selector: PhantomData<S>,\n}\n\n/// A Trait for any type that can perform SELECT queries\npub trait SelectorTrait {\n    #[allow(missing_docs)]\n    type Item: Sized;\n\n    /// The method to perform a query on a Model\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr>;\n}\n\n/// Get tuple from query result based on a list of column identifiers\n#[derive(Debug)]\npub struct SelectGetableValue<T, C>\nwhere\n    T: TryGetableMany,\n    C: strum::IntoEnumIterator + sea_query::Iden,\n{\n    columns: PhantomData<C>,\n    model: PhantomData<T>,\n}\n\n/// Get tuple from query result based on column index\n#[derive(Debug)]\npub struct SelectGetableTuple<T>\nwhere\n    T: TryGetableMany,\n{\n    model: PhantomData<T>,\n}\n\n/// Helper class to handle query result for 1 Model\n#[derive(Debug)]\npub struct SelectModel<M>\nwhere\n    M: FromQueryResult,\n{\n    model: PhantomData<M>,\n}\n\n/// Defines a type to get two Models, with the second being optional\n#[derive(Clone, Debug)]\npub struct SelectTwoModel<M, N>\nwhere\n    M: FromQueryResult,\n    N: FromQueryResult,\n{\n    model: PhantomData<(M, N)>,\n}\n\n/// Defines a type to get two Models\n#[derive(Clone, Debug)]\npub struct SelectTwoRequiredModel<M, N>\nwhere\n    M: FromQueryResult,\n    N: FromQueryResult,\n{\n    model: PhantomData<(M, N)>,\n}\n\n/// Helper class to handle query result for 3 Models\n#[derive(Clone, Debug)]\npub struct SelectThreeModel<M, N, O>\nwhere\n    M: FromQueryResult,\n    N: FromQueryResult,\n    O: FromQueryResult,\n{\n    model: PhantomData<(M, N, O)>,\n}\n\n/// Helper class to handle query result for 4 Models\n#[derive(Clone, Debug)]\npub struct SelectFourModel<M, N, O, P>\nwhere\n    M: FromQueryResult,\n    N: FromQueryResult,\n    O: FromQueryResult,\n    P: FromQueryResult,\n{\n    model: PhantomData<(M, N, O, P)>,\n}\n\n/// Helper class to handle query result for 5 Models\n#[derive(Clone, Debug)]\npub struct SelectFiveModel<M, N, O, P, Q>\nwhere\n    M: FromQueryResult,\n    N: FromQueryResult,\n    O: FromQueryResult,\n    P: FromQueryResult,\n    Q: FromQueryResult,\n{\n    model: PhantomData<(M, N, O, P, Q)>,\n}\n\n/// Helper class to handle query result for 6 Models\n#[derive(Clone, Debug)]\npub struct SelectSixModel<M, N, O, P, Q, R>\nwhere\n    M: FromQueryResult,\n    N: FromQueryResult,\n    O: FromQueryResult,\n    P: FromQueryResult,\n    Q: FromQueryResult,\n    R: FromQueryResult,\n{\n    model: PhantomData<(M, N, O, P, Q, R)>,\n}\n\nimpl<T, C> Default for SelectGetableValue<T, C>\nwhere\n    T: TryGetableMany,\n    C: strum::IntoEnumIterator + sea_query::Iden,\n{\n    fn default() -> Self {\n        Self {\n            columns: PhantomData,\n            model: PhantomData,\n        }\n    }\n}\n\nimpl<T, C> SelectorTrait for SelectGetableValue<T, C>\nwhere\n    T: TryGetableMany,\n    C: strum::IntoEnumIterator + sea_query::Iden,\n{\n    type Item = T;\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        let cols: Vec<String> = C::iter().map(|col| col.to_string()).collect();\n        T::try_get_many(&res, \"\", &cols).map_err(Into::into)\n    }\n}\n\nimpl<T> SelectorTrait for SelectGetableTuple<T>\nwhere\n    T: TryGetableMany,\n{\n    type Item = T;\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        T::try_get_many_by_index(&res).map_err(Into::into)\n    }\n}\n\nimpl<M> SelectorTrait for SelectModel<M>\nwhere\n    M: FromQueryResult + Sized,\n{\n    type Item = M;\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        M::from_query_result(&res, \"\")\n    }\n}\n\nimpl<M, N> SelectorTrait for SelectTwoModel<M, N>\nwhere\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n{\n    type Item = (M, Option<N>);\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, SelectA.as_str())?,\n            N::from_query_result_optional(&res, SelectB.as_str())?,\n        ))\n    }\n}\n\nimpl<M, N> SelectorTrait for SelectTwoRequiredModel<M, N>\nwhere\n    M: FromQueryResult + Sized,\n    N: FromQueryResult + Sized,\n{\n    type Item = (M, N);\n\n    fn from_raw_query_result(res: QueryResult) -> Result<Self::Item, DbErr> {\n        Ok((\n            M::from_query_result(&res, SelectA.as_str())?,\n            N::from_query_result(&res, SelectB.as_str())?,\n        ))\n    }\n}\n\nimpl<E> Select<E>\nwhere\n    E: EntityTrait,\n{\n    /// Perform a Select operation on a Model using a [Statement]\n    #[allow(clippy::wrong_self_convention)]\n    pub fn from_raw_sql(self, stmt: Statement) -> SelectorRaw<SelectModel<E::Model>> {\n        SelectorRaw {\n            stmt,\n            selector: PhantomData,\n        }\n    }\n\n    /// Return a [Selector] from `Self` that wraps a [SelectModel]\n    pub fn into_model<M>(self) -> Selector<SelectModel<M>>\n    where\n        M: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Return a [Selector] from `Self` that wraps a [SelectModel] with a [PartialModel](PartialModelTrait)\n    ///\n    /// ```\n    /// # #[cfg(feature = \"macros\")]\n    /// # {\n    /// use sea_orm::{\n    ///     entity::*,\n    ///     query::*,\n    ///     tests_cfg::cake::{self, Entity as Cake},\n    ///     DbBackend, DerivePartialModel,\n    /// };\n    /// use sea_query::{Expr, Func, SimpleExpr};\n    ///\n    /// #[derive(DerivePartialModel)]\n    /// #[sea_orm(entity = \"Cake\")]\n    /// struct PartialCake {\n    ///     name: String,\n    ///     #[sea_orm(\n    ///         from_expr = r#\"SimpleExpr::FunctionCall(Func::upper(Expr::col((Cake, cake::Column::Name))))\"#\n    ///     )]\n    ///     name_upper: String,\n    /// }\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .into_partial_model::<PartialCake>()\n    ///         .into_statement(DbBackend::Sqlite)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"name\" AS \"name\", UPPER(\"cake\".\"name\") AS \"name_upper\" FROM \"cake\"\"#\n    /// );\n    /// # }\n    /// ```\n    pub fn into_partial_model<M>(self) -> Selector<SelectModel<M>>\n    where\n        M: PartialModelTrait,\n    {\n        M::select_cols(QuerySelect::select_only(self)).into_model::<M>()\n    }\n\n    /// Get a selectable Model as a [JsonValue] for SQL JSON operations\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(self) -> Selector<SelectModel<JsonValue>> {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(all(feature = \"mock\", feature = \"macros\"))]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[\n    /// #         maplit::btreemap! {\n    /// #             \"cake_name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #         },\n    /// #         maplit::btreemap! {\n    /// #             \"cake_name\" => Into::<Value>::into(\"New York Cheese\"),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{DeriveColumn, EnumIter, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n    /// enum QueryAs {\n    ///     CakeName,\n    /// }\n    ///\n    /// let res: Vec<String> = cake::Entity::find()\n    ///     .select_only()\n    ///     .column_as(cake::Column::Name, QueryAs::CakeName)\n    ///     .into_values::<_, QueryAs>()\n    ///     .all(&db)\n    ///     .await?;\n    ///\n    /// assert_eq!(\n    ///     res,\n    ///     [\"Chocolate Forest\".to_owned(), \"New York Cheese\".to_owned()]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"name\" AS \"cake_name\" FROM \"cake\"\"#,\n    ///         []\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(all(feature = \"mock\", feature = \"macros\"))]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[\n    /// #         maplit::btreemap! {\n    /// #             \"cake_name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(2i64),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{DeriveColumn, EnumIter, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n    /// enum QueryAs {\n    ///     CakeName,\n    ///     NumOfCakes,\n    /// }\n    ///\n    /// let res: Vec<(String, i64)> = cake::Entity::find()\n    ///     .select_only()\n    ///     .column_as(cake::Column::Name, QueryAs::CakeName)\n    ///     .column_as(cake::Column::Id.count(), QueryAs::NumOfCakes)\n    ///     .group_by(cake::Column::Name)\n    ///     .into_values::<_, QueryAs>()\n    ///     .all(&db)\n    ///     .await?;\n    ///\n    /// assert_eq!(res, [(\"Chocolate Forest\".to_owned(), 2i64)]);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         [\n    ///             r#\"SELECT \"cake\".\"name\" AS \"cake_name\", COUNT(\"cake\".\"id\") AS \"num_of_cakes\"\"#,\n    ///             r#\"FROM \"cake\" GROUP BY \"cake\".\"name\"\"#,\n    ///         ]\n    ///         .join(\" \")\n    ///         .as_str(),\n    ///         []\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn into_values<T, C>(self) -> Selector<SelectGetableValue<T, C>>\n    where\n        T: TryGetableMany,\n        C: strum::IntoEnumIterator + sea_query::Iden,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(all(feature = \"mock\", feature = \"macros\"))]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results(vec![vec![\n    /// #         maplit::btreemap! {\n    /// #             \"cake_name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #         },\n    /// #         maplit::btreemap! {\n    /// #             \"cake_name\" => Into::<Value>::into(\"New York Cheese\"),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let res: Vec<String> = cake::Entity::find()\n    ///     .select_only()\n    ///     .column(cake::Column::Name)\n    ///     .into_tuple()\n    ///     .all(&db)\n    ///     .await?;\n    ///\n    /// assert_eq!(\n    ///     res,\n    ///     vec![\"Chocolate Forest\".to_owned(), \"New York Cheese\".to_owned()]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     vec![Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"name\" FROM \"cake\"\"#,\n    ///         vec![]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    ///\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(all(feature = \"mock\", feature = \"macros\"))]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results(vec![vec![\n    /// #         maplit::btreemap! {\n    /// #             \"cake_name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(2i64),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let res: Vec<(String, i64)> = cake::Entity::find()\n    ///     .select_only()\n    ///     .column(cake::Column::Name)\n    ///     .column(cake::Column::Id)\n    ///     .group_by(cake::Column::Name)\n    ///     .into_tuple()\n    ///     .all(&db)\n    ///     .await?;\n    ///\n    /// assert_eq!(res, vec![(\"Chocolate Forest\".to_owned(), 2i64)]);\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     vec![Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         vec![\n    ///             r#\"SELECT \"cake\".\"name\", \"cake\".\"id\"\"#,\n    ///             r#\"FROM \"cake\" GROUP BY \"cake\".\"name\"\"#,\n    ///         ]\n    ///         .join(\" \")\n    ///         .as_str(),\n    ///         vec![]\n    ///     )]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn into_tuple<T>(self) -> Selector<SelectGetableTuple<T>>\n    where\n        T: TryGetableMany,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the SELECT query\n    pub async fn one<C>(self, db: &C) -> Result<Option<E::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db).await\n    }\n\n    /// Get all Models from the SELECT query\n    pub async fn all<C>(self, db: &C) -> Result<Vec<E::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db).await\n    }\n\n    /// Stream the results of a SELECT operation on a Model\n    pub async fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Stream<Item = Result<E::Model, DbErr>> + 'b + Send, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n    {\n        self.into_model().stream(db).await\n    }\n\n    /// Stream the result of the operation with PartialModel\n    pub async fn stream_partial_model<'a: 'b, 'b, C, M>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Stream<Item = Result<M, DbErr>> + 'b + Send, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n        M: PartialModelTrait + Send + 'b,\n    {\n        self.into_partial_model().stream(db).await\n    }\n}\n\nimpl<E, F> SelectTwo<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    /// Perform a conversion into a [SelectTwoModel]\n    pub fn into_model<M, N>(self) -> Selector<SelectTwoModel<M, N>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Perform a conversion into a [SelectTwoModel] with [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M, N>(self) -> Selector<SelectTwoModel<M, N>>\n    where\n        M: PartialModelTrait,\n        N: PartialModelTrait,\n    {\n        let select = QuerySelect::select_only(self);\n        let select = M::select_cols(select);\n        let select = N::select_cols(select);\n        select.into_model::<M, N>()\n    }\n\n    /// Convert the Models into JsonValue\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(self) -> Selector<SelectTwoModel<JsonValue, JsonValue>> {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the Select query\n    pub async fn one<C>(self, db: &C) -> Result<Option<(E::Model, Option<F::Model>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db).await\n    }\n\n    /// Get all Models from the Select query\n    pub async fn all<C>(self, db: &C) -> Result<Vec<(E::Model, Option<F::Model>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db).await\n    }\n\n    /// Stream the results of a Select operation on a Model\n    pub async fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Stream<Item = Result<(E::Model, Option<F::Model>), DbErr>> + 'b, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n    {\n        self.into_model().stream(db).await\n    }\n\n    /// Stream the result of the operation with PartialModel\n    pub async fn stream_partial_model<'a: 'b, 'b, C, M, N>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Stream<Item = Result<(M, Option<N>), DbErr>> + 'b + Send, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n        M: PartialModelTrait + Send + 'b,\n        N: PartialModelTrait + Send + 'b,\n    {\n        self.into_partial_model().stream(db).await\n    }\n}\n\nimpl<E, F> SelectTwoMany<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    /// Performs a conversion to [Selector]\n    fn into_model<M, N>(self) -> Selector<SelectTwoModel<M, N>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get all Models from the select operation and consolidate result based on left Model.\n    ///\n    /// > `SelectTwoMany::one()` method has been dropped (#486)\n    /// >\n    /// > You can get `(Entity, Vec<relatedEntity>)` by first querying a single model from Entity,\n    /// > then use [`ModelTrait::find_related`] on the model.\n    /// >\n    /// > See https://www.sea-ql.org/SeaORM/docs/basic-crud/select#lazy-loading for details.\n    pub async fn all<C>(self, db: &C) -> Result<Vec<(E::Model, Vec<F::Model>)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let rows = self.into_model().all(db).await?;\n        Ok(consolidate_query_result::<E, F>(rows))\n    }\n\n    // pub fn paginate()\n    // we could not implement paginate easily, if the number of children for a\n    // parent is larger than one page, then we will end up splitting it in two pages\n    // so the correct way is actually perform query in two stages\n    // paginate the parent model and then populate the children\n\n    // pub fn count()\n    // we should only count the number of items of the parent model\n}\n\nimpl<E, F> SelectTwoRequired<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    /// Perform a conversion into a [SelectTwoRequiredModel]\n    pub fn into_model<M, N>(self) -> Selector<SelectTwoRequiredModel<M, N>>\n    where\n        M: FromQueryResult,\n        N: FromQueryResult,\n    {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Perform a conversion into a [SelectTwoRequiredModel] with [PartialModel](PartialModelTrait)\n    pub fn into_partial_model<M, N>(self) -> Selector<SelectTwoRequiredModel<M, N>>\n    where\n        M: PartialModelTrait,\n        N: PartialModelTrait,\n    {\n        let select = QuerySelect::select_only(self);\n        let select = M::select_cols(select);\n        let select = N::select_cols(select);\n        select.into_model::<M, N>()\n    }\n\n    /// Convert the Models into JsonValue\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(self) -> Selector<SelectTwoRequiredModel<JsonValue, JsonValue>> {\n        Selector {\n            query: self.query,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get one Model from the Select query\n    pub async fn one<C>(self, db: &C) -> Result<Option<(E::Model, F::Model)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().one(db).await\n    }\n\n    /// Get all Models from the Select query\n    pub async fn all<C>(self, db: &C) -> Result<Vec<(E::Model, F::Model)>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.into_model().all(db).await\n    }\n\n    /// Stream the results of a Select operation on a Model\n    pub async fn stream<'a: 'b, 'b, C>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Stream<Item = Result<(E::Model, F::Model), DbErr>> + 'b, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n    {\n        self.into_model().stream(db).await\n    }\n\n    /// Stream the result of the operation with PartialModel\n    pub async fn stream_partial_model<'a: 'b, 'b, C, M, N>(\n        self,\n        db: &'a C,\n    ) -> Result<impl Stream<Item = Result<(M, N), DbErr>> + 'b + Send, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n        M: PartialModelTrait + Send + 'b,\n        N: PartialModelTrait + Send + 'b,\n    {\n        self.into_partial_model().stream(db).await\n    }\n}\n\nimpl<S> Selector<S>\nwhere\n    S: SelectorTrait,\n{\n    /// Get the SQL statement\n    pub fn into_statement(self, builder: DbBackend) -> Statement {\n        builder.build(&self.query)\n    }\n\n    /// Get an item from the Select query\n    pub async fn one<C>(mut self, db: &C) -> Result<Option<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        self.query.limit(1);\n        let row = db.query_one(&self.query).await?;\n        match row {\n            Some(row) => Ok(Some(S::from_raw_query_result(row)?)),\n            None => Ok(None),\n        }\n    }\n\n    /// Get all items from the Select query\n    pub async fn all<C>(self, db: &C) -> Result<Vec<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        db.query_all(&self.query)\n            .await?\n            .into_iter()\n            .map(|row| S::from_raw_query_result(row))\n            .try_collect()\n    }\n\n    /// Stream the results of the Select operation\n    pub async fn stream<'a: 'b, 'b, C>(self, db: &'a C) -> Result<PinBoxStream<'b, S::Item>, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n        S: 'b,\n        S::Item: Send,\n    {\n        let stream = db.stream(&self.query).await?;\n\n        #[cfg(not(feature = \"sync\"))]\n        {\n            Ok(Box::pin(stream.and_then(|row| {\n                futures_util::future::ready(S::from_raw_query_result(row))\n            })))\n        }\n        #[cfg(feature = \"sync\")]\n        {\n            Ok(Box::new(\n                stream.map(|item| item.and_then(S::from_raw_query_result)),\n            ))\n        }\n    }\n}\n\nimpl<S> SelectorRaw<S>\nwhere\n    S: SelectorTrait,\n{\n    /// Select a custom Model from a raw SQL [Statement].\n    pub fn from_statement<M>(stmt: Statement) -> SelectorRaw<SelectModel<M>>\n    where\n        M: FromQueryResult,\n    {\n        SelectorRaw {\n            stmt,\n            selector: PhantomData,\n        }\n    }\n\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(1),\n    /// #         },\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"New York Cheese\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(1),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{FromQueryResult, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// #[derive(Debug, PartialEq, FromQueryResult)]\n    /// struct SelectResult {\n    ///     name: String,\n    ///     num_of_cakes: i32,\n    /// }\n    ///\n    /// let res: Vec<SelectResult> = cake::Entity::find()\n    ///     .from_raw_sql(Statement::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"name\", count(\"cake\".\"id\") AS \"num_of_cakes\" FROM \"cake\"\"#,\n    ///         [],\n    ///     ))\n    ///     .into_model::<SelectResult>()\n    ///     .all(&db)\n    ///     .await?;\n    ///\n    /// assert_eq!(\n    ///     res,\n    ///     [\n    ///         SelectResult {\n    ///             name: \"Chocolate Forest\".to_owned(),\n    ///             num_of_cakes: 1,\n    ///         },\n    ///         SelectResult {\n    ///             name: \"New York Cheese\".to_owned(),\n    ///             num_of_cakes: 1,\n    ///         },\n    ///     ]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"name\", count(\"cake\".\"id\") AS \"num_of_cakes\" FROM \"cake\"\"#,\n    ///         []\n    ///     ),]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub fn into_model<M>(self) -> SelectorRaw<SelectModel<M>>\n    where\n        M: FromQueryResult,\n    {\n        SelectorRaw {\n            stmt: self.stmt,\n            selector: PhantomData,\n        }\n    }\n\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([[\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"Chocolate Forest\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(1),\n    /// #         },\n    /// #         maplit::btreemap! {\n    /// #             \"name\" => Into::<Value>::into(\"New York Cheese\"),\n    /// #             \"num_of_cakes\" => Into::<Value>::into(1),\n    /// #         },\n    /// #     ]])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};\n    ///\n    /// let res: Vec<serde_json::Value> = cake::Entity::find().from_raw_sql(\n    ///     Statement::from_sql_and_values(\n    ///         DbBackend::Postgres, r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#, []\n    ///     )\n    /// )\n    /// .into_json()\n    /// .all(&db)\n    /// .await?;\n    ///\n    /// assert_eq!(\n    ///     res,\n    ///     [\n    ///         serde_json::json!({\n    ///             \"name\": \"Chocolate Forest\",\n    ///             \"num_of_cakes\": 1,\n    ///         }),\n    ///         serde_json::json!({\n    ///             \"name\": \"New York Cheese\",\n    ///             \"num_of_cakes\": 1,\n    ///         }),\n    ///     ]\n    /// );\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [\n    ///     Transaction::from_sql_and_values(\n    ///             DbBackend::Postgres, r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#, []\n    ///     ),\n    /// ]);\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    #[cfg(feature = \"with-json\")]\n    pub fn into_json(self) -> SelectorRaw<SelectModel<JsonValue>> {\n        SelectorRaw {\n            stmt: self.stmt,\n            selector: PhantomData,\n        }\n    }\n\n    /// Get the SQL statement\n    pub fn into_statement(self) -> Statement {\n        self.stmt\n    }\n\n    /// Get an item from the Select query\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Cake\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, raw_sql, tests_cfg::cake};\n    ///\n    /// let id = 1;\n    ///\n    /// let _: Option<cake::Model> = cake::Entity::find()\n    ///     .from_raw_sql(raw_sql!(\n    ///         Postgres,\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"id\" = {id}\"#\n    ///     ))\n    ///     .one(&db)\n    ///     .await?;\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"id\" = $1\"#,\n    ///         [1.into()]\n    ///     ),]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub async fn one<C>(self, db: &C) -> Result<Option<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let row = db.query_one_raw(self.stmt).await?;\n        match row {\n            Some(row) => Ok(Some(S::from_raw_query_result(row)?)),\n            None => Ok(None),\n        }\n    }\n\n    /// Get all items from the Select query\n    /// ```\n    /// # use sea_orm::{error::*, tests_cfg::*, *};\n    /// #\n    /// # #[smol_potat::main]\n    /// # #[cfg(feature = \"mock\")]\n    /// # pub async fn main() -> Result<(), DbErr> {\n    /// #\n    /// # let db = MockDatabase::new(DbBackend::Postgres)\n    /// #     .append_query_results([\n    /// #         [cake::Model {\n    /// #             id: 1,\n    /// #             name: \"Cake\".to_owned(),\n    /// #         }],\n    /// #     ])\n    /// #     .into_connection();\n    /// #\n    /// use sea_orm::{entity::*, query::*, raw_sql, tests_cfg::cake};\n    ///\n    /// let _: Vec<cake::Model> = cake::Entity::find()\n    ///     .from_raw_sql(raw_sql!(\n    ///         Postgres,\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#\n    ///     ))\n    ///     .all(&db)\n    ///     .await?;\n    ///\n    /// assert_eq!(\n    ///     db.into_transaction_log(),\n    ///     [Transaction::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n    ///         []\n    ///     ),]\n    /// );\n    /// #\n    /// # Ok(())\n    /// # }\n    /// ```\n    pub async fn all<C>(self, db: &C) -> Result<Vec<S::Item>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        db.query_all_raw(self.stmt)\n            .await?\n            .into_iter()\n            .map(|row| S::from_raw_query_result(row))\n            .try_collect()\n    }\n\n    /// Stream the results of the Select operation\n    pub async fn stream<'a: 'b, 'b, C>(self, db: &'a C) -> Result<PinBoxStream<'b, S::Item>, DbErr>\n    where\n        C: ConnectionTrait + StreamTrait + Send,\n        S: 'b,\n        S::Item: Send,\n    {\n        let stream = db.stream_raw(self.stmt).await?;\n\n        #[cfg(not(feature = \"sync\"))]\n        {\n            Ok(Box::pin(stream.and_then(|row| {\n                futures_util::future::ready(S::from_raw_query_result(row))\n            })))\n        }\n        #[cfg(feature = \"sync\")]\n        {\n            Ok(Box::new(\n                stream.map(|item| item.and_then(S::from_raw_query_result)),\n            ))\n        }\n    }\n}\n"
  },
  {
    "path": "src/executor/select_ext.rs",
    "content": "use crate::{\n    ConnectionTrait, DbErr, EntityTrait, Select, SelectFive, SelectFour, SelectSix, SelectThree,\n    SelectTwo, Selector, SelectorRaw, SelectorTrait, Topology,\n};\nuse sea_query::{Expr, SelectStatement};\n\n// TODO: Move count here\n#[async_trait::async_trait]\n/// Helper trait for selectors with convenient methods\npub trait SelectExt {\n    /// This method is unstable and is only used for internal testing.\n    /// It may be removed in the future.\n    #[doc(hidden)]\n    fn exists_query(self) -> SelectStatement;\n    /// Check if any records exist\n    async fn exists<C>(self, db: &C) -> Result<bool, DbErr>\n    where\n        C: ConnectionTrait,\n        Self: Send + Sized,\n    {\n        let stmt = self.exists_query();\n        Ok(db.query_one(&stmt).await?.is_some())\n    }\n}\n\nfn into_exists_query(mut stmt: SelectStatement) -> SelectStatement {\n    stmt.clear_selects();\n    // Expr::Custom has fewer branches, but this may not have any significant impact on performance.\n    stmt.expr(Expr::cust(\"1\"));\n    stmt.reset_limit();\n    stmt.reset_offset();\n    stmt.clear_order_by();\n    stmt\n}\n\nimpl<S> SelectExt for Selector<S>\nwhere\n    S: SelectorTrait,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\n#[async_trait::async_trait]\nimpl<S> SelectExt for SelectorRaw<S>\nwhere\n    S: SelectorTrait,\n{\n    fn exists_query(self) -> SelectStatement {\n        let stmt = self.stmt;\n        let sub_query_sql = stmt.sql.trim().trim_end_matches(';').trim();\n        let exists_sql = format!(\"1 FROM ({sub_query_sql}) AS sub_query LIMIT 1\");\n\n        let mut query = SelectStatement::new();\n        query.expr(if let Some(values) = stmt.values {\n            Expr::cust_with_values(exists_sql, values.0)\n        } else {\n            Expr::cust(exists_sql)\n        });\n        query\n    }\n}\n\nimpl<E> SelectExt for Select<E>\nwhere\n    E: EntityTrait,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\nimpl<E, F> SelectExt for SelectTwo<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\nimpl<E, F, G, TOP> SelectExt for SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\nimpl<E, F, G, H, TOP> SelectExt for SelectFour<E, F, G, H, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    TOP: Topology,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\nimpl<E, F, G, H, I, TOP> SelectExt for SelectFive<E, F, G, H, I, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    TOP: Topology,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\nimpl<E, F, G, H, I, J, TOP> SelectExt for SelectSix<E, F, G, H, I, J, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    J: EntityTrait,\n    TOP: Topology,\n{\n    fn exists_query(self) -> SelectStatement {\n        into_exists_query(self.query)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::SelectExt;\n    use crate::entity::prelude::*;\n    use crate::{DbBackend, QueryOrder, QuerySelect, Statement, tests_cfg::*};\n\n    #[test]\n    fn exists_query_select_basic() {\n        let stmt = fruit::Entity::find().exists_query();\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(sql, r#\"SELECT 1 FROM \"fruit\"\"#);\n    }\n\n    #[test]\n    fn exists_query_select_strips_limit_offset_order() {\n        let stmt = fruit::Entity::find()\n            .filter(fruit::Column::Id.gt(1))\n            .order_by_asc(fruit::Column::Id)\n            .limit(2)\n            .offset(4)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(sql, r#\"SELECT 1 FROM \"fruit\" WHERE \"fruit\".\"id\" > 1\"#);\n    }\n\n    #[test]\n    fn exists_query_selector_basic() {\n        let stmt = fruit::Entity::find()\n            .into_model::<fruit::Model>()\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(sql, r#\"SELECT 1 FROM \"fruit\"\"#);\n    }\n\n    #[test]\n    fn exists_query_selector_complex() {\n        let stmt = fruit::Entity::find()\n            .filter(fruit::Column::Id.gt(1))\n            .order_by_desc(fruit::Column::Id)\n            .limit(2)\n            .offset(4)\n            .into_model::<fruit::Model>()\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(sql, r#\"SELECT 1 FROM \"fruit\" WHERE \"fruit\".\"id\" > 1\"#);\n    }\n\n    #[test]\n    fn exists_query_selector_raw_simple() {\n        let raw_stmt =\n            Statement::from_string(DbBackend::Postgres, r#\"SELECT \"fruit\".\"id\" FROM \"fruit\"\"#);\n        let stmt = fruit::Entity::find().from_raw_sql(raw_stmt).exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            r#\"SELECT 1 FROM (SELECT \"fruit\".\"id\" FROM \"fruit\") AS sub_query LIMIT 1\"#\n        );\n    }\n\n    #[test]\n    fn exists_query_selector_raw_complex() {\n        let raw_stmt = Statement::from_string(\n            DbBackend::Postgres,\n            r#\"SELECT \"fruit\".\"id\" FROM \"fruit\" WHERE \"fruit\".\"id\" > 1 ORDER BY \"fruit\".\"id\" DESC LIMIT 5 OFFSET 2\"#,\n        );\n        let stmt = fruit::Entity::find().from_raw_sql(raw_stmt).exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            r#\"SELECT 1 FROM (SELECT \"fruit\".\"id\" FROM \"fruit\" WHERE \"fruit\".\"id\" > 1 ORDER BY \"fruit\".\"id\" DESC LIMIT 5 OFFSET 2) AS sub_query LIMIT 1\"#\n        );\n    }\n\n    #[test]\n    fn exists_query_select_two_simple() {\n        let stmt = cake::Entity::find()\n            .find_also_related(fruit::Entity)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            r#\"SELECT 1 FROM \"cake\" LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#\n        );\n    }\n\n    #[test]\n    fn exists_query_select_two_complex() {\n        let stmt = cake::Entity::find()\n            .find_also_related(fruit::Entity)\n            .filter(cake::Column::Id.gt(1))\n            .order_by_desc(cake::Column::Id)\n            .limit(2)\n            .offset(4)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake\"\"#,\n                r#\"LEFT JOIN \"fruit\" ON \"cake\".\"id\" = \"fruit\".\"cake_id\"\"#,\n                r#\"WHERE \"cake\".\"id\" > 1\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_three_simple() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_three_complex() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .filter(cake_filling::Column::CakeId.gt(1))\n            .order_by_desc(cake_filling::Column::CakeId)\n            .limit(2)\n            .offset(4)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"WHERE \"cake_filling\".\"cake_id\" > 1\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_four_simple() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .find_also(filling::Entity, ingredient::Entity)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"LEFT JOIN \"ingredient\" ON \"filling\".\"id\" = \"ingredient\".\"filling_id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_four_complex() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .find_also(filling::Entity, ingredient::Entity)\n            .filter(cake_filling::Column::CakeId.gt(1))\n            .order_by_desc(cake_filling::Column::CakeId)\n            .limit(2)\n            .offset(4)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"LEFT JOIN \"ingredient\" ON \"filling\".\"id\" = \"ingredient\".\"filling_id\"\"#,\n                r#\"WHERE \"cake_filling\".\"cake_id\" > 1\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_five_simple() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .find_also(filling::Entity, ingredient::Entity)\n            .find_also(cake_filling::Entity, cake_filling_price::Entity)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"LEFT JOIN \"ingredient\" ON \"filling\".\"id\" = \"ingredient\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"public\".\"cake_filling_price\" ON \"cake_filling\".\"cake_id\" = \"cake_filling_price\".\"cake_id\" AND \"cake_filling\".\"filling_id\" = \"cake_filling_price\".\"filling_id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_five_complex() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .find_also(filling::Entity, ingredient::Entity)\n            .find_also(cake_filling::Entity, cake_filling_price::Entity)\n            .filter(cake_filling::Column::CakeId.gt(1))\n            .order_by_desc(cake_filling::Column::CakeId)\n            .limit(2)\n            .offset(4)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"LEFT JOIN \"ingredient\" ON \"filling\".\"id\" = \"ingredient\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"public\".\"cake_filling_price\" ON \"cake_filling\".\"cake_id\" = \"cake_filling_price\".\"cake_id\" AND \"cake_filling\".\"filling_id\" = \"cake_filling_price\".\"filling_id\"\"#,\n                r#\"WHERE \"cake_filling\".\"cake_id\" > 1\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_six_simple() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .find_also(filling::Entity, ingredient::Entity)\n            .find_also(cake_filling::Entity, cake_filling_price::Entity)\n            .find_also(filling::Entity, cake_compact::Entity)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"LEFT JOIN \"ingredient\" ON \"filling\".\"id\" = \"ingredient\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"public\".\"cake_filling_price\" ON \"cake_filling\".\"cake_id\" = \"cake_filling_price\".\"cake_id\" AND \"cake_filling\".\"filling_id\" = \"cake_filling_price\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"cake_filling\" ON \"filling\".\"id\" = \"cake_filling\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn exists_query_select_six_complex() {\n        let stmt = cake_filling::Entity::find()\n            .find_also_related(cake::Entity)\n            .find_also(cake_filling::Entity, filling::Entity)\n            .find_also(filling::Entity, ingredient::Entity)\n            .find_also(cake_filling::Entity, cake_filling_price::Entity)\n            .find_also(filling::Entity, cake_compact::Entity)\n            .filter(cake_filling::Column::CakeId.gt(1))\n            .order_by_desc(cake_filling::Column::CakeId)\n            .limit(2)\n            .offset(4)\n            .exists_query();\n\n        let sql = DbBackend::Postgres.build(&stmt).to_string();\n        assert_eq!(\n            sql,\n            [\n                r#\"SELECT 1 FROM \"cake_filling\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"LEFT JOIN \"filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n                r#\"LEFT JOIN \"ingredient\" ON \"filling\".\"id\" = \"ingredient\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"public\".\"cake_filling_price\" ON \"cake_filling\".\"cake_id\" = \"cake_filling_price\".\"cake_id\" AND \"cake_filling\".\"filling_id\" = \"cake_filling_price\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"cake_filling\" ON \"filling\".\"id\" = \"cake_filling\".\"filling_id\"\"#,\n                r#\"LEFT JOIN \"cake\" ON \"cake_filling\".\"cake_id\" = \"cake\".\"id\"\"#,\n                r#\"WHERE \"cake_filling\".\"cake_id\" > 1\"#,\n            ]\n            .join(\" \")\n        );\n    }\n}\n"
  },
  {
    "path": "src/executor/update.rs",
    "content": "use super::ReturningSelector;\nuse crate::{\n    ActiveModelTrait, ColumnTrait, ConnectionTrait, EntityTrait, IntoActiveModel, Iterable,\n    PrimaryKeyTrait, SelectModel, UpdateMany, UpdateOne, ValidatedUpdateOne, error::*,\n};\nuse sea_query::{FromValueTuple, Query, UpdateStatement};\n\n/// Defines an update operation\n#[derive(Clone, Debug)]\npub struct Updater {\n    query: UpdateStatement,\n    check_record_exists: bool,\n}\n\n/// The result of an update operation on an ActiveModel\n#[derive(Clone, Debug, PartialEq, Eq, Default)]\npub struct UpdateResult {\n    /// The rows affected by the update operation\n    pub rows_affected: u64,\n}\n\nimpl<A> ValidatedUpdateOne<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Execute an UPDATE operation on an ActiveModel\n    pub async fn exec<C>(self, db: &C) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        Updater::new(self.query)\n            .exec_update_and_return_updated(self.model, db)\n            .await\n    }\n}\n\nimpl<A> UpdateOne<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Execute an UPDATE operation on an ActiveModel\n    pub async fn exec<C>(self, db: &C) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\n    where\n        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,\n        C: ConnectionTrait,\n    {\n        self.0?.exec(db).await\n    }\n}\n\nimpl<'a, E> UpdateMany<E>\nwhere\n    E: EntityTrait,\n{\n    /// Execute an update operation on multiple ActiveModels\n    pub async fn exec<C>(self, db: &'a C) -> Result<UpdateResult, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Updater::new(self.query).exec(db).await\n    }\n\n    /// Execute an update operation and return the updated model (use `RETURNING` syntax if supported)\n    pub async fn exec_with_returning<C>(self, db: &'a C) -> Result<Vec<E::Model>, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        Updater::new(self.query)\n            .exec_update_with_returning::<E, _>(db)\n            .await\n    }\n}\n\nimpl Updater {\n    /// Instantiate an update using an [UpdateStatement]\n    fn new(query: UpdateStatement) -> Self {\n        Self {\n            query,\n            check_record_exists: false,\n        }\n    }\n\n    /// Execute an update operation\n    pub async fn exec<C>(self, db: &C) -> Result<UpdateResult, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.is_noop() {\n            return Ok(UpdateResult::default());\n        }\n        let result = db.execute(&self.query).await?;\n        if self.check_record_exists && result.rows_affected() == 0 {\n            return Err(DbErr::RecordNotUpdated);\n        }\n        Ok(UpdateResult {\n            rows_affected: result.rows_affected(),\n        })\n    }\n\n    async fn exec_update_and_return_updated<A, C>(\n        mut self,\n        model: A,\n        db: &C,\n    ) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\n    where\n        A: ActiveModelTrait,\n        C: ConnectionTrait,\n    {\n        type Entity<A> = <A as ActiveModelTrait>::Entity;\n        type Model<A> = <Entity<A> as EntityTrait>::Model;\n        type Column<A> = <Entity<A> as EntityTrait>::Column;\n\n        if self.is_noop() {\n            return find_updated_model_by_id(model, db).await;\n        }\n\n        match db.support_returning() {\n            true => {\n                let db_backend = db.get_database_backend();\n                let returning = Query::returning().exprs(\n                    Column::<A>::iter().map(|c| c.select_as(c.into_returning_expr(db_backend))),\n                );\n                self.query.returning(returning);\n                let found: Option<Model<A>> =\n                    ReturningSelector::<SelectModel<Model<A>>, _>::from_query(self.query)\n                        .one(db)\n                        .await?;\n                // If we got `None` then we are updating a row that does not exist.\n                match found {\n                    Some(model) => Ok(model),\n                    None => Err(DbErr::RecordNotUpdated),\n                }\n            }\n            false => {\n                // If we updating a row that does not exist then an error will be thrown here.\n                self.check_record_exists = true;\n                self.exec(db).await?;\n                find_updated_model_by_id(model, db).await\n            }\n        }\n    }\n\n    async fn exec_update_with_returning<E, C>(mut self, db: &C) -> Result<Vec<E::Model>, DbErr>\n    where\n        E: EntityTrait,\n        C: ConnectionTrait,\n    {\n        if self.is_noop() {\n            return Ok(vec![]);\n        }\n\n        let db_backend = db.get_database_backend();\n        match db.support_returning() {\n            true => {\n                let returning = Query::returning().exprs(\n                    E::Column::iter().map(|c| c.select_as(c.into_returning_expr(db_backend))),\n                );\n                self.query.returning(returning);\n                let models: Vec<E::Model> =\n                    ReturningSelector::<SelectModel<E::Model>, _>::from_query(self.query)\n                        .all(db)\n                        .await?;\n                Ok(models)\n            }\n            false => Err(DbErr::BackendNotSupported {\n                db: db_backend.as_str(),\n                ctx: \"UPDATE RETURNING\",\n            }),\n        }\n    }\n\n    fn is_noop(&self) -> bool {\n        self.query.get_values().is_empty()\n    }\n}\n\nasync fn find_updated_model_by_id<A, C>(\n    model: A,\n    db: &C,\n) -> Result<<A::Entity as EntityTrait>::Model, DbErr>\nwhere\n    A: ActiveModelTrait,\n    C: ConnectionTrait,\n{\n    type Entity<A> = <A as ActiveModelTrait>::Entity;\n    type ValueType<A> = <<Entity<A> as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::ValueType;\n\n    let primary_key_value = match model.get_primary_key_value() {\n        Some(val) => ValueType::<A>::from_value_tuple(val),\n        None => return Err(DbErr::UpdateGetPrimaryKey),\n    };\n    let found = Entity::<A>::find_by_id(primary_key_value).one(db).await?;\n    // If we cannot select the updated row from db by the cached primary key\n    match found {\n        Some(model) => Ok(model),\n        None => Err(DbErr::RecordNotFound(\n            \"Failed to find updated item\".to_owned(),\n        )),\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{\n        ColumnTrait, DbBackend, DbErr, EntityTrait, IntoActiveModel, MockDatabase, MockExecResult,\n        QueryFilter, Set, Transaction, Update, UpdateResult, tests_cfg::cake,\n    };\n    use pretty_assertions::assert_eq;\n    use sea_query::Expr;\n\n    #[smol_potat::test]\n    async fn update_record_not_found_1() -> Result<(), DbErr> {\n        use crate::ActiveModelTrait;\n\n        let updated_cake = cake::Model {\n            id: 1,\n            name: \"Cheese Cake\".to_owned(),\n        };\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([\n                vec![updated_cake.clone()],\n                vec![],\n                vec![],\n                vec![],\n                vec![updated_cake.clone()],\n                vec![updated_cake.clone()],\n                vec![updated_cake.clone()],\n            ])\n            .append_exec_results([MockExecResult {\n                last_insert_id: 0,\n                rows_affected: 0,\n            }])\n            .into_connection();\n\n        let model = cake::Model {\n            id: 1,\n            name: \"New York Cheese\".to_owned(),\n        };\n\n        assert_eq!(\n            cake::ActiveModel {\n                name: Set(\"Cheese Cake\".to_owned()),\n                ..model.clone().into_active_model()\n            }\n            .update(&db)\n            .await?,\n            cake::Model {\n                id: 1,\n                name: \"Cheese Cake\".to_owned(),\n            }\n        );\n\n        let model = cake::Model {\n            id: 2,\n            name: \"New York Cheese\".to_owned(),\n        };\n\n        assert_eq!(\n            cake::ActiveModel {\n                name: Set(\"Cheese Cake\".to_owned()),\n                ..model.clone().into_active_model()\n            }\n            .update(&db)\n            .await,\n            Err(DbErr::RecordNotUpdated)\n        );\n\n        assert_eq!(\n            cake::Entity::update(cake::ActiveModel {\n                name: Set(\"Cheese Cake\".to_owned()),\n                ..model.clone().into_active_model()\n            })\n            .exec(&db)\n            .await,\n            Err(DbErr::RecordNotUpdated)\n        );\n\n        assert_eq!(\n            Update::one(cake::ActiveModel {\n                name: Set(\"Cheese Cake\".to_owned()),\n                ..model.clone().into_active_model()\n            })\n            .exec(&db)\n            .await,\n            Err(DbErr::RecordNotUpdated)\n        );\n\n        assert_eq!(\n            Update::many(cake::Entity)\n                .col_expr(cake::Column::Name, Expr::value(\"Cheese Cake\".to_owned()))\n                .filter(cake::Column::Id.eq(2))\n                .exec(&db)\n                .await,\n            Ok(UpdateResult { rows_affected: 0 })\n        );\n\n        assert_eq!(\n            updated_cake.clone().into_active_model().save(&db).await?,\n            updated_cake.clone().into_active_model()\n        );\n\n        assert_eq!(\n            updated_cake.clone().into_active_model().update(&db).await?,\n            updated_cake\n        );\n\n        assert_eq!(\n            cake::Entity::update(updated_cake.clone().into_active_model())\n                .exec(&db)\n                .await?,\n            updated_cake\n        );\n\n        assert_eq!(\n            cake::Entity::update_many().exec(&db).await?.rows_affected,\n            0\n        );\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"cake\" SET \"name\" = $1 WHERE \"cake\".\"id\" = $2 RETURNING \"id\", \"name\"\"#,\n                    [\"Cheese Cake\".into(), 1i32.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"cake\" SET \"name\" = $1 WHERE \"cake\".\"id\" = $2 RETURNING \"id\", \"name\"\"#,\n                    [\"Cheese Cake\".into(), 2i32.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"cake\" SET \"name\" = $1 WHERE \"cake\".\"id\" = $2 RETURNING \"id\", \"name\"\"#,\n                    [\"Cheese Cake\".into(), 2i32.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"cake\" SET \"name\" = $1 WHERE \"cake\".\"id\" = $2 RETURNING \"id\", \"name\"\"#,\n                    [\"Cheese Cake\".into(), 2i32.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"UPDATE \"cake\" SET \"name\" = $1 WHERE \"cake\".\"id\" = $2\"#,\n                    [\"Cheese Cake\".into(), 2i32.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = $1 LIMIT $2\"#,\n                    [1.into(), 1u64.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = $1 LIMIT $2\"#,\n                    [1.into(), 1u64.into()]\n                ),\n                Transaction::from_sql_and_values(\n                    DbBackend::Postgres,\n                    r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = $1 LIMIT $2\"#,\n                    [1.into(), 1u64.into()]\n                ),\n            ]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn update_error() {\n        use crate::{DbBackend, DbErr, MockDatabase};\n\n        let db = MockDatabase::new(DbBackend::MySql).into_connection();\n\n        assert!(matches!(\n            Update::one(cake::ActiveModel {\n                ..Default::default()\n            })\n            .exec(&db)\n            .await,\n            Err(DbErr::PrimaryKeyNotSet { .. })\n        ));\n\n        assert!(matches!(\n            cake::Entity::update(cake::ActiveModel::default())\n                .exec(&db)\n                .await,\n            Err(DbErr::PrimaryKeyNotSet { .. })\n        ));\n    }\n}\n"
  },
  {
    "path": "src/lib.rs",
    "content": "#![cfg_attr(docsrs, feature(doc_cfg))]\n#![warn(missing_docs)]\n#![deny(\n    missing_debug_implementations,\n    clippy::missing_panics_doc,\n    clippy::unwrap_used,\n    clippy::print_stderr,\n    clippy::print_stdout\n)]\n\n//! <div align=\"center\">\n//!\n//!   <img alt=\"SeaORM\" src=\"https://www.sea-ql.org/blog/img/SeaORM 2.0 Banner.png\"/>\n//!\n//!   <h1></h1>\n//!   <h3>SeaORM is a powerful ORM for building web services in Rust</h3>\n//!\n//!   [![crate](https://img.shields.io/crates/v/sea-orm.svg)](https://crates.io/crates/sea-orm)\n//!   [![build status](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml/badge.svg)](https://github.com/SeaQL/sea-orm/actions/workflows/rust.yml)\n//!   [![GitHub stars](https://img.shields.io/github/stars/SeaQL/sea-orm.svg?style=social&label=Star&maxAge=1)](https://github.com/SeaQL/sea-orm/stargazers/)\n//!   <br>Support us with a ⭐ !\n//!\n//! </div>\n//!\n//! # 🐚 SeaORM\n//!\n//! [中文文档](https://github.com/SeaQL/sea-orm/blob/master/README-zh.md)\n//!\n//! ### Advanced Relations\n//!\n//! Model complex relationships 1-1, 1-N, M-N, and even self-referential in a high-level, conceptual way.\n//!\n//! ### Familiar Concepts\n//!\n//! Inspired by popular ORMs in the Ruby, Python, and Node.js ecosystem, SeaORM offers a developer experience that feels instantly recognizable.\n//!\n//! ### Feature Rich\n//!\n//! SeaORM is a batteries-included ORM with filters, pagination, and nested queries to accelerate building REST, GraphQL, and gRPC APIs.\n//!\n//! ### Production Ready\n//!\n//! With 250k+ weekly downloads, SeaORM is production-ready, trusted by startups and enterprises worldwide.\n//!\n//! ## Getting Started\n//!\n//! [![Discord](https://img.shields.io/discord/873880840487206962?label=Discord)](https://discord.com/invite/uCPdDXzbdv)\n//! Join our Discord server to chat with others!\n//!\n//! + [Documentation](https://www.sea-ql.org/SeaORM)\n//!\n//! Integration examples:\n//!\n//! + [Actix Example](https://github.com/SeaQL/sea-orm/tree/master/examples/actix_example)\n//! + [Axum Example](https://github.com/SeaQL/sea-orm/tree/master/examples/axum_example)\n//! + [GraphQL Example](https://github.com/SeaQL/sea-orm/tree/master/examples/graphql_example)\n//! + [jsonrpsee Example](https://github.com/SeaQL/sea-orm/tree/master/examples/jsonrpsee_example)\n//! + [Loco Example](https://github.com/SeaQL/sea-orm/tree/master/examples/loco_example) / [Loco REST Starter](https://github.com/SeaQL/sea-orm/tree/master/examples/loco_starter)\n//! + [Poem Example](https://github.com/SeaQL/sea-orm/tree/master/examples/poem_example)\n//! + [Rocket Example](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_example) / [Rocket OpenAPI Example](https://github.com/SeaQL/sea-orm/tree/master/examples/rocket_okapi_example)\n//! + [Salvo Example](https://github.com/SeaQL/sea-orm/tree/master/examples/salvo_example)\n//! + [Tonic Example](https://github.com/SeaQL/sea-orm/tree/master/examples/tonic_example)\n//! + [Seaography Example (Bakery)](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) / [Seaography Example (Sakila)](https://github.com/SeaQL/seaography/tree/main/examples/sqlite)\n//!\n//! If you want a simple, clean example that fits in a single file that demonstrates the best of SeaORM, you can try:\n//! + [Quickstart](https://github.com/SeaQL/sea-orm/blob/master/examples/quickstart/src/main.rs)\n//!\n//! Let's have a quick walk through of the unique features of SeaORM.\n//!\n//! ## Expressive Entity format\n//! You don't have to write this by hand! Entity files can be generated from an existing database using `sea-orm-cli`,\n//! following is generated with `--entity-format dense` *(new in 2.0)*.\n//! ```\n//! # #[cfg(feature = \"macros\")]\n//! # mod entities {\n//! # mod profile {\n//! # use sea_orm::entity::prelude::*;\n//! # #[sea_orm::model]\n//! # #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n//! # #[sea_orm(table_name = \"profile\")]\n//! # pub struct Model {\n//! #     #[sea_orm(primary_key)]\n//! #     pub id: i32,\n//! #     pub picture: String,\n//! #     #[sea_orm(unique)]\n//! #     pub user_id: i32,\n//! #     #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n//! #     pub user: HasOne<super::user::Entity>,\n//! # }\n//! # impl ActiveModelBehavior for ActiveModel {}\n//! # }\n//! # mod tag {\n//! # use sea_orm::entity::prelude::*;\n//! # #[sea_orm::model]\n//! # #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n//! # #[sea_orm(table_name = \"post\")]\n//! # pub struct Model {\n//! #     #[sea_orm(primary_key)]\n//! #     pub id: i32,\n//! #     #[sea_orm(has_many, via = \"post_tag\")]\n//! #     pub tags: HasMany<super::tag::Entity>,\n//! # }\n//! # impl ActiveModelBehavior for ActiveModel {}\n//! # }\n//! # mod post_tag {\n//! # use sea_orm::entity::prelude::*;\n//! # #[sea_orm::model]\n//! # #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n//! # #[sea_orm(table_name = \"post_tag\")]\n//! # pub struct Model {\n//! #     #[sea_orm(primary_key, auto_increment = false)]\n//! #     pub post_id: i32,\n//! #     #[sea_orm(primary_key, auto_increment = false)]\n//! #     pub tag_id: i32,\n//! #     #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n//! #     pub post: Option<super::post::Entity>,\n//! #     #[sea_orm(belongs_to, from = \"tag_id\", to = \"id\")]\n//! #     pub tag: Option<super::tag::Entity>,\n//! # }\n//! # impl ActiveModelBehavior for ActiveModel {}\n//! # }\n//! mod user {\n//!     use sea_orm::entity::prelude::*;\n//!\n//!     #[sea_orm::model]\n//!     #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n//!     #[sea_orm(table_name = \"user\")]\n//!     pub struct Model {\n//!         #[sea_orm(primary_key)]\n//!         pub id: i32,\n//!         pub name: String,\n//!         #[sea_orm(unique)]\n//!         pub email: String,\n//!         #[sea_orm(has_one)]\n//!         pub profile: HasOne<super::profile::Entity>,\n//!         #[sea_orm(has_many)]\n//!         pub posts: HasMany<super::post::Entity>,\n//!     }\n//! # impl ActiveModelBehavior for ActiveModel {}\n//! }\n//! mod post {\n//!     use sea_orm::entity::prelude::*;\n//!\n//!     #[sea_orm::model]\n//!     #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n//!     #[sea_orm(table_name = \"post\")]\n//!     pub struct Model {\n//!         #[sea_orm(primary_key)]\n//!         pub id: i32,\n//!         pub user_id: i32,\n//!         pub title: String,\n//!         #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n//!         pub author: HasOne<super::user::Entity>,\n//!         #[sea_orm(has_many, via = \"post_tag\")] // M-N relation with junction\n//!         pub tags: HasMany<super::tag::Entity>,\n//!     }\n//! # impl ActiveModelBehavior for ActiveModel {}\n//! }\n//! # }\n//! ```\n//!\n//! ## Smart Entity Loader\n//! The Entity Loader intelligently uses join for 1-1 and data loader for 1-N relations,\n//! eliminating the N+1 problem even when performing nested queries.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, prelude::*, entity::*, query::*, tests_cfg::*};\n//! # async fn function(db: &DbConn) -> Result<(), DbErr> {\n//! // join paths:\n//! // user -> profile\n//! // user -> post\n//! //         post -> post_tag -> tag\n//! let smart_user = user::Entity::load()\n//!     .filter_by_id(42) // shorthand for .filter(user::COLUMN.id.eq(42))\n//!     .with(profile::Entity) // 1-1 uses join\n//!     .with((post::Entity, tag::Entity)) // 1-N uses data loader\n//!     .one(db)\n//!     .await?\n//!     .unwrap();\n//!\n//! // 3 queries are executed under the hood:\n//! // 1. SELECT FROM user JOIN profile WHERE id = $\n//! // 2. SELECT FROM post WHERE user_id IN (..)\n//! // 3. SELECT FROM tag JOIN post_tag WHERE post_id IN (..)\n//!\n//! smart_user\n//!     == user::ModelEx {\n//!         id: 42,\n//!         name: \"Bob\".into(),\n//!         email: \"bob@sea-ql.org\".into(),\n//!         profile: HasOne::Loaded(\n//!             profile::ModelEx {\n//! #           id: 1,\n//!                 picture: \"image.jpg\".into(),\n//! #           user_id: 1,\n//! #           user: HasOne::Unloaded,\n//!             }\n//!             .into(),\n//!         ),\n//!         posts: HasMany::Loaded(vec![post::ModelEx {\n//! #           id: 2,\n//! #           user_id: 1,\n//!             title: \"Nice weather\".into(),\n//! #           author: HasOne::Unloaded,\n//! #           comments: HasMany::Unloaded,\n//!             tags: HasMany::Loaded(vec![tag::ModelEx {\n//! #               id: 3,\n//!                 tag: \"sunny\".into(),\n//! #               posts: HasMany::Unloaded,\n//!             }]),\n//!         }]),\n//!     };\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ## ActiveModel: nested persistence made simple\n//! Persist an entire object graph: user, profile (1-1), posts (1-N), and tags (M-N)\n//! in a single operation using a fluent builder API. SeaORM automatically determines\n//! the dependencies and inserts or deletes objects in the correct order.\n//!\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! # async fn function(db: &DbConn) -> Result<(), DbErr> {\n//! // this creates the nested object as shown above:\n//! let user = user::ActiveModel::builder()\n//!     .set_name(\"Bob\")\n//!     .set_email(\"bob@sea-ql.org\")\n//!     .set_profile(profile::ActiveModel::builder().set_picture(\"image.jpg\"))\n//!     .add_post(\n//!         post::ActiveModel::builder()\n//!             .set_title(\"Nice weather\")\n//!             .add_tag(tag::ActiveModel::builder().set_tag(\"sunny\")),\n//!     )\n//!     .save(db)\n//!     .await?;\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ## Schema first or Entity first? Your choice\n//!\n//! SeaORM provides a powerful migration system that lets you create tables, modify schemas, and seed data with ease.\n//!\n//! With SeaORM 2.0, you also get a first-class [Entity First Workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/):\n//! simply define new entities or add columns to existing ones,\n//! and SeaORM will automatically detect the changes and create the new tables, columns, unique keys, and foreign keys.\n//!\n//! ```ignore\n//! // SeaORM resolves foreign key dependencies and creates the tables in topological order.\n//! // Requires the `entity-registry` and `schema-sync` feature flags.\n//! db.get_schema_registry(\"my_crate::entity::*\").sync(db).await;\n//! ```\n//!\n//! ## Ergonomic Raw SQL\n//!\n//! Let SeaORM handle 95% of your transactional queries.\n//! For the remaining cases that are too complex to express,\n//! SeaORM still offers convenient support for writing raw SQL.\n//! ```\n//! # use sea_orm::{DbErr, DbConn};\n//! # async fn function(db: &DbConn) -> Result<(), DbErr> {\n//! # use sea_orm::{entity::*, query::*, tests_cfg::*, raw_sql};\n//! # struct Item<'a> { name: &'a str }\n//! let user = Item { name: \"Bob\" }; // nested parameter access\n//! let ids = [2, 3, 4]; // expanded by the `..` operator\n//!\n//! let user: Option<user::Model> = user::Entity::find()\n//!     .from_raw_sql(raw_sql!(\n//!         Sqlite,\n//!         r#\"SELECT \"id\", \"name\" FROM \"user\"\n//!            WHERE \"name\" LIKE {user.name}\n//!            AND \"id\" in ({..ids})\n//!         \"#\n//!     ))\n//!     .one(db)\n//!     .await?;\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ## Synchronous Support\n//!\n//! [`sea-orm-sync`](https://crates.io/crates/sea-orm-sync) provides the full SeaORM API without requiring an async runtime, making it ideal for lightweight CLI programs with SQLite.\n//!\n//! See the [quickstart example](https://github.com/SeaQL/sea-orm/blob/master/sea-orm-sync/examples/quickstart/src/main.rs) for usage.\n//!\n//! ## Basics\n//!\n//! ### Select\n//! SeaORM models 1-N and M-N relationships at the Entity level,\n//! letting you traverse many-to-many links through a junction table in a single call.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! # async fn function(db: &DbConn) -> Result<(), DbErr> {\n//! // find all models\n//! let cakes: Vec<cake::Model> = Cake::find().all(db).await?;\n//!\n//! // find and filter\n//! let chocolate: Vec<cake::Model> = Cake::find()\n//!     .filter(Cake::COLUMN.name.contains(\"chocolate\"))\n//!     .all(db)\n//!     .await?;\n//!\n//! // find one model\n//! let cheese: Option<cake::Model> = Cake::find_by_id(1).one(db).await?;\n//! let cheese: cake::Model = cheese.unwrap();\n//!\n//! // find related models (lazy)\n//! let fruit: Option<fruit::Model> = cheese.find_related(Fruit).one(db).await?;\n//!\n//! // find related models (eager): for 1-1 relations\n//! let cake_with_fruit: Vec<(cake::Model, Option<fruit::Model>)> =\n//!     Cake::find().find_also_related(Fruit).all(db).await?;\n//!\n//! // find related models (eager): works for both 1-N and M-N relations\n//! let cake_with_fillings: Vec<(cake::Model, Vec<filling::Model>)> = Cake::find()\n//!     .find_with_related(Filling) // for M-N relations, two joins are performed\n//!     .all(db) // rows are automatically consolidated by left entity\n//!     .await?;\n//! # Ok(())\n//! # }\n//! ```\n//! ### Nested Select\n//!\n//! Partial models prevent overfetching by letting you querying only the fields\n//! you need; it also makes writing deeply nested relational queries simple.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! # async fn function(db: &DbConn) -> Result<(), DbErr> {\n//! use sea_orm::DerivePartialModel;\n//!\n//! #[derive(DerivePartialModel)]\n//! #[sea_orm(entity = \"cake::Entity\")]\n//! struct CakeWithFruit {\n//!     id: i32,\n//!     name: String,\n//!     #[sea_orm(nested)]\n//!     fruit: Option<fruit::Model>, // this can be a regular or another partial model\n//! }\n//!\n//! let cakes: Vec<CakeWithFruit> = Cake::find()\n//!     .left_join(fruit::Entity) // no need to specify join condition\n//!     .into_partial_model() // only the columns in the partial model will be selected\n//!     .all(db)\n//!     .await?;\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ### Insert\n//! SeaORM's ActiveModel lets you work directly with Rust data structures and\n//! persist them through a simple API.\n//! It's easy to insert large batches of rows from different data sources.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! # async fn function(db: &DbConn) -> Result<(), DbErr> {\n//! let apple = fruit::ActiveModel {\n//!     name: Set(\"Apple\".to_owned()),\n//!     ..Default::default() // no need to set primary key\n//! };\n//!\n//! let pear = fruit::ActiveModel {\n//!     name: Set(\"Pear\".to_owned()),\n//!     ..Default::default()\n//! };\n//!\n//! // insert one: Active Record style\n//! let apple = apple.insert(db).await?;\n//! apple.id == 1;\n//! # let apple = fruit::ActiveModel {\n//! #     name: Set(\"Apple\".to_owned()),\n//! #     ..Default::default() // no need to set primary key\n//! # };\n//!\n//! // insert one: repository style\n//! let result = Fruit::insert(apple).exec(db).await?;\n//! result.last_insert_id == 1;\n//! # let apple = fruit::ActiveModel {\n//! #     name: Set(\"Apple\".to_owned()),\n//! #     ..Default::default() // no need to set primary key\n//! # };\n//!\n//! // insert many returning last insert id\n//! let result = Fruit::insert_many([apple, pear]).exec(db).await?;\n//! result.last_insert_id == Some(2);\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ### Insert (advanced)\n//! You can take advantage of database specific features to perform upsert and idempotent insert.\n//! ```\n//! # use sea_orm::{DbConn, TryInsertResult, DbErr, entity::*, query::*, tests_cfg::*};\n//! # async fn function_1(db: &DbConn) -> Result<(), DbErr> {\n//! # let apple = fruit::ActiveModel {\n//! #     name: Set(\"Apple\".to_owned()),\n//! #     ..Default::default() // no need to set primary key\n//! # };\n//! # let pear = fruit::ActiveModel {\n//! #     name: Set(\"Pear\".to_owned()),\n//! #     ..Default::default()\n//! # };\n//! // insert many with returning (if supported by database)\n//! let models: Vec<fruit::Model> = Fruit::insert_many([apple, pear])\n//!     .exec_with_returning(db)\n//!     .await?;\n//! models[0]\n//!     == fruit::Model {\n//!         id: 1, // database assigned value\n//!         name: \"Apple\".to_owned(),\n//!         cake_id: None,\n//!     };\n//! # Ok(())\n//! # }\n//!\n//! # async fn function_2(db: &DbConn) -> Result<(), DbErr> {\n//! # let apple = fruit::ActiveModel {\n//! #     name: Set(\"Apple\".to_owned()),\n//! #     ..Default::default() // no need to set primary key\n//! # };\n//! # let pear = fruit::ActiveModel {\n//! #     name: Set(\"Pear\".to_owned()),\n//! #     ..Default::default()\n//! # };\n//! // insert with ON CONFLICT on primary key do nothing, with MySQL specific polyfill\n//! let result = Fruit::insert_many([apple, pear])\n//!     .on_conflict_do_nothing()\n//!     .exec(db)\n//!     .await?;\n//!\n//! matches!(result, TryInsertResult::Conflicted);\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ### Update\n//! ActiveModel avoids race conditions by updating only the fields you've changed,\n//! never overwriting untouched columns.\n//! You can also craft complex bulk update queries with a fluent query building API.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! use sea_orm::sea_query::{Expr, Value};\n//!\n//! # async fn function(db: &DbConn) -> Result<(), DbErr> {\n//! let pear: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;\n//! let mut pear: fruit::ActiveModel = pear.unwrap().into();\n//!\n//! pear.name = Set(\"Sweet pear\".to_owned()); // update value of a single field\n//!\n//! // update one: only changed columns will be updated\n//! let pear: fruit::Model = pear.update(db).await?;\n//!\n//! // update many: UPDATE \"fruit\" SET \"cake_id\" = \"cake_id\" + 2\n//! //               WHERE \"fruit\".\"name\" LIKE '%Apple%'\n//! Fruit::update_many()\n//!     .col_expr(fruit::COLUMN.cake_id, fruit::COLUMN.cake_id.add(2))\n//!     .filter(fruit::COLUMN.name.contains(\"Apple\"))\n//!     .exec(db)\n//!     .await?;\n//! # Ok(())\n//! # }\n//! ```\n//! ### Save\n//! You can perform \"insert or update\" operation with ActiveModel, making it easy to compose transactional operations.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! # async fn function(db: &DbConn) -> Result<(), DbErr> {\n//! let banana = fruit::ActiveModel {\n//!     id: NotSet,\n//!     name: Set(\"Banana\".to_owned()),\n//!     ..Default::default()\n//! };\n//!\n//! // create, because primary key `id` is `NotSet`\n//! let mut banana = banana.save(db).await?;\n//!\n//! banana.id == Unchanged(2);\n//! banana.name = Set(\"Banana Mongo\".to_owned());\n//!\n//! // update, because primary key `id` is present\n//! let banana = banana.save(db).await?;\n//! # Ok(())\n//! # }\n//! ```\n//! ### Delete\n//! The same ActiveModel API consistent with insert and update.\n//! ```\n//! # use sea_orm::{DbConn, DbErr, entity::*, query::*, tests_cfg::*};\n//! # async fn function(db: &DbConn) -> Result<(), DbErr> {\n//! // delete one: Active Record style\n//! let orange: Option<fruit::Model> = Fruit::find_by_id(1).one(db).await?;\n//! let orange: fruit::Model = orange.unwrap();\n//! orange.delete(db).await?;\n//!\n//! // delete one: repository style\n//! let orange = fruit::ActiveModel {\n//!     id: Set(2),\n//!     ..Default::default()\n//! };\n//! fruit::Entity::delete(orange).exec(db).await?;\n//!\n//! // delete many: DELETE FROM \"fruit\" WHERE \"fruit\".\"name\" LIKE '%Orange%'\n//! fruit::Entity::delete_many()\n//!     .filter(fruit::COLUMN.name.contains(\"Orange\"))\n//!     .exec(db)\n//!     .await?;\n//!\n//! # Ok(())\n//! # }\n//! ```\n//! ### Raw SQL Query\n//! The `raw_sql!` macro is like the `format!` macro but without the risk of SQL injection.\n//! It supports nested parameter interpolation, array and tuple expansion, and even repeating group,\n//! offering great flexibility in crafting complex queries.\n//!\n//! ```\n//! # use sea_orm::{DbErr, DbConn};\n//! # async fn functio(db: &DbConn) -> Result<(), DbErr> {\n//! # use sea_orm::{query::*, FromQueryResult, raw_sql};\n//! #[derive(FromQueryResult)]\n//! struct CakeWithBakery {\n//!     name: String,\n//!     #[sea_orm(nested)]\n//!     bakery: Option<Bakery>,\n//! }\n//!\n//! #[derive(FromQueryResult)]\n//! struct Bakery {\n//!     #[sea_orm(alias = \"bakery_name\")]\n//!     name: String,\n//! }\n//!\n//! let cake_ids = [2, 3, 4]; // expanded by the `..` operator\n//!\n//! // can use many APIs with raw SQL, including nested select\n//! let cake: Option<CakeWithBakery> = CakeWithBakery::find_by_statement(raw_sql!(\n//!     Sqlite,\n//!     r#\"SELECT \"cake\".\"name\", \"bakery\".\"name\" AS \"bakery_name\"\n//!        FROM \"cake\"\n//!        LEFT JOIN \"bakery\" ON \"cake\".\"bakery_id\" = \"bakery\".\"id\"\n//!        WHERE \"cake\".\"id\" IN ({..cake_ids})\"#\n//! ))\n//! .one(db)\n//! .await?;\n//! # Ok(())\n//! # }\n//! ```\n//!\n//! ## 🧭 Seaography: instant GraphQL API\n//!\n//! [Seaography](https://github.com/SeaQL/seaography) is a GraphQL framework built for SeaORM.\n//! Seaography allows you to build GraphQL resolvers quickly.\n//! With just a few commands, you can launch a fullly-featured GraphQL server from SeaORM entities,\n//! complete with filter, pagination, relational queries and mutations!\n//!\n//! Look at the [Seaography Example](https://github.com/SeaQL/sea-orm/tree/master/examples/seaography_example) to learn more.\n//!\n//! <img src=\"https://raw.githubusercontent.com/SeaQL/sea-orm/master/examples/seaography_example/Seaography%20example.png\"/>\n//!\n//! ## 🖥️ SeaORM Pro: Professional Admin Panel\n//!\n//! [SeaORM Pro](https://github.com/SeaQL/sea-orm-pro/) is an admin panel solution allowing you to quickly and easily launch an admin panel for your application - frontend development skills not required, but certainly nice to have!\n//!\n//! SeaORM Pro has been updated to support the latest features in SeaORM 2.0.\n//!\n//! Features:\n//!\n//! + Full CRUD\n//! + Built on React + GraphQL\n//! + Built-in GraphQL resolver\n//! + Customize the UI with TOML config\n//! + Role Based Access Control *(new in 2.0)*\n//!\n//! Read the [Getting Started](https://www.sea-ql.org/sea-orm-pro/docs/install-and-config/getting-started/) guide to learn more.\n//!\n//! ![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-dark.png#gh-dark-mode-only)\n//! ![](https://raw.githubusercontent.com/SeaQL/sea-orm/refs/heads/master/docs/sea-orm-pro-light.png#gh-light-mode-only)\n//!\n//! ## SQL Server Support\n//!\n//! [SQL Server for SeaORM](https://www.sea-ql.org/SeaORM-X/) offers the same SeaORM API for MSSQL. We ported all test cases and examples, complemented by MSSQL specific documentation. If you are building enterprise software, you can [request commercial access](https://forms.office.com/r/1MuRPJmYBR). It is currently based on SeaORM 1.0, but we will offer free upgrade to existing users when SeaORM 2.0 is finalized.\n//!\n//! ## Releases\n//!\n//! SeaORM 2.0 has reached its release candidate phase. We'd love for you to try it out and help shape the final release by [sharing your feedback](https://github.com/SeaQL/sea-orm/discussions/).\n//!\n//! + [Change Log](https://github.com/SeaQL/sea-orm/tree/master/CHANGELOG.md)\n//!\n//! SeaORM 2.0 is shaping up to be our most significant release yet - with a few breaking changes, plenty of enhancements, and a clear focus on developer experience.\n//!\n//! + [A Sneak Peek at SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-16-sea-orm-2.0/)\n//! + [SeaORM 2.0: A closer look](https://www.sea-ql.org/blog/2025-09-24-sea-orm-2.0/)\n//! + [Role Based Access Control in SeaORM 2.0](https://www.sea-ql.org/blog/2025-09-30-sea-orm-rbac/)\n//! + [Seaography 2.0: A Powerful and Extensible GraphQL Framework](https://www.sea-ql.org/blog/2025-10-08-seaography/)\n//! + [SeaORM 2.0: New Entity Format](https://www.sea-ql.org/blog/2025-10-20-sea-orm-2.0/)\n//! + [SeaORM 2.0: Entity First Workflow](https://www.sea-ql.org/blog/2025-10-30-sea-orm-2.0/)\n//! + [SeaORM 2.0: Strongly-Typed Column](https://www.sea-ql.org/blog/2025-11-11-sea-orm-2.0/)\n//! + [What's new in SeaORM Pro 2.0](https://www.sea-ql.org/blog/2025-11-21-whats-new-in-seaormpro-2.0/)\n//! + [SeaORM 2.0: Nested ActiveModel](https://www.sea-ql.org/blog/2025-11-25-sea-orm-2.0/)\n//! + [A walk-through of SeaORM 2.0](https://www.sea-ql.org/blog/2025-12-05-sea-orm-2.0/)\n//! + [How we made SeaORM synchronous](https://www.sea-ql.org/blog/2025-12-12-sea-orm-2.0/)\n//! + [SeaORM 2.0 Migration Guide](https://www.sea-ql.org/blog/2026-01-12-sea-orm-2.0/)\n//! + [SeaORM now supports Arrow & Parquet](https://www.sea-ql.org/blog/2026-02-22-sea-orm-arrow/)\n//! + [SeaORM 2.0 with SQL Server Support](https://www.sea-ql.org/blog/2026-02-25-sea-orm-x/)\n//!\n//! If you make extensive use of SeaQuery, we recommend checking out our blog post on SeaQuery 1.0 release:\n//!\n//! + [The road to SeaQuery 1.0](https://www.sea-ql.org/blog/2025-08-30-sea-query-1.0/)\n//!\n//! ## License\n//!\n//! Licensed under either of\n//!\n//! -   Apache License, Version 2.0\n//!     ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)\n//! -   MIT license\n//!     ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)\n//!\n//! at your option.\n//!\n//! ## Contribution\n//!\n//! Unless you explicitly state otherwise, any contribution intentionally submitted\n//! for inclusion in the work by you, as defined in the Apache-2.0 license, shall be\n//! dual licensed as above, without any additional terms or conditions.\n//!\n//! We invite you to participate, contribute and together help build Rust's future.\n//!\n//! A big shout out to our contributors!\n//!\n//! [![Contributors](https://opencollective.com/sea-orm/contributors.svg?width=1000&button=false)](https://github.com/SeaQL/sea-orm/graphs/contributors)\n//!\n//! ## Who's using SeaORM?\n//!\n//! Here is a short list of awesome open source software built with SeaORM. Feel free to [submit yours](https://github.com/SeaQL/sea-orm/blob/master/COMMUNITY.md#built-with-seaorm)!\n//!\n//! | Project | GitHub | Tagline |\n//! |---------|--------|---------|\n//! | [Zed](https://github.com/zed-industries/zed) | ![GitHub stars](https://img.shields.io/github/stars/zed-industries/zed.svg?style=social) | A high-performance, multiplayer code editor |\n//! | [OpenObserve](https://github.com/openobserve/openobserve) | ![GitHub stars](https://img.shields.io/github/stars/openobserve/openobserve.svg?style=social) | Open-source observability platform |\n//! | [RisingWave](https://github.com/risingwavelabs/risingwave) | ![GitHub stars](https://img.shields.io/github/stars/risingwavelabs/risingwave.svg?style=social) | Stream processing and management platform |\n//! | [LLDAP](https://github.com/nitnelave/lldap) | ![GitHub stars](https://img.shields.io/github/stars/nitnelave/lldap.svg?style=social) | A light LDAP server for user management |\n//! | [Warpgate](https://github.com/warp-tech/warpgate) | ![GitHub stars](https://img.shields.io/github/stars/warp-tech/warpgate.svg?style=social) | Smart SSH bastion that works with any SSH client |\n//! | [Svix](https://github.com/svix/svix-webhooks) | ![GitHub stars](https://img.shields.io/github/stars/svix/svix-webhooks.svg?style=social) | The enterprise ready webhooks service |\n//! | [Ryot](https://github.com/IgnisDa/ryot) | ![GitHub stars](https://img.shields.io/github/stars/ignisda/ryot.svg?style=social) | The only self hosted tracker you will ever need |\n//! | [Lapdev](https://github.com/lapce/lapdev) | ![GitHub stars](https://img.shields.io/github/stars/lapce/lapdev.svg?style=social) | Self-hosted remote development enviroment |\n//! | [System Initiative](https://github.com/systeminit/si) | ![GitHub stars](https://img.shields.io/github/stars/systeminit/si.svg?style=social) | DevOps Automation Platform |\n//! | [OctoBase](https://github.com/toeverything/OctoBase) | ![GitHub stars](https://img.shields.io/github/stars/toeverything/OctoBase.svg?style=social) | A light-weight, scalable, offline collaborative data backend |\n//!\n//! ## Sponsorship\n//!\n//! [SeaQL.org](https://www.sea-ql.org/) is an independent open-source organization run by passionate developers.\n//! If you feel generous, a small donation via [GitHub Sponsor](https://github.com/sponsors/SeaQL) will be greatly appreciated, and goes a long way towards sustaining the organization.\n//!\n//! ### Gold Sponsors\n//!\n//! <table><tr>\n//! <td><a href=\"https://qdx.co/\">\n//!   <img src=\"https://www.sea-ql.org/static/sponsors/QDX.svg\" width=\"138\"/>\n//! </a></td>\n//! </tr></table>\n//!\n//! [QDX](https://qdx.co/) pioneers quantum dynamics-powered drug discovery, leveraging AI and supercomputing to accelerate molecular modeling.\n//! We're immensely grateful to QDX for sponsoring the development of SeaORM, the SQL toolkit that powers their data intensive applications.\n//!\n//! ### Silver Sponsors\n//!\n//! We're grateful to our silver sponsors: Digital Ocean, for sponsoring our servers. And JetBrains, for sponsoring our IDE.\n//!\n//! <table><tr>\n//! <td><a href=\"https://www.digitalocean.com/\">\n//!   <img src=\"https://www.sea-ql.org/static/sponsors/DigitalOcean.svg\" width=\"125\">\n//! </a></td>\n//!\n//! <td><a href=\"https://www.jetbrains.com/\">\n//!   <img src=\"https://www.sea-ql.org/static/sponsors/JetBrains.svg\" width=\"125\">\n//! </a></td>\n//! </tr></table>\n//!\n//! ## Mascot\n//!\n//! A friend of Ferris, Terres the hermit crab is the official mascot of SeaORM. His hobby is collecting shells.\n//!\n//! <img alt=\"Terres\" src=\"https://www.sea-ql.org/SeaORM/img/Terres.png\" width=\"400\"/>\n//!\n//! ## 🦀 Rustacean Sticker Pack\n//! The Rustacean Sticker Pack is the perfect way to express your passion for Rust. Our stickers are made with a premium water-resistant vinyl with a unique matte finish.\n//!\n//! Sticker Pack Contents:\n//!\n//! + Logo of SeaQL projects: SeaQL, SeaORM, SeaQuery, Seaography\n//! + Mascots: Ferris the Crab x 3, Terres the Hermit Crab\n//! + The Rustacean wordmark\n//!\n//! [Support SeaQL and get a Sticker Pack!](https://www.sea-ql.org/sticker-pack/) All proceeds contributes directly to the ongoing development of SeaQL projects.\n//!\n//! <a href=\"https://www.sea-ql.org/sticker-pack/\"><img alt=\"Rustacean Sticker Pack by SeaQL\" src=\"https://www.sea-ql.org/static/sticker-pack-1s.jpg\" width=\"600\"/></a>\n#![doc(\n    html_logo_url = \"https://raw.githubusercontent.com/SeaQL/sea-query/master/docs/SeaQL icon dark.png\"\n)]\n\nmod database;\nmod docs;\nmod driver;\npub mod dynamic;\n/// Module for the Entity type and operations\npub mod entity;\n/// Error types for all database operations\npub mod error;\n/// This module performs execution of queries on a Model or ActiveModel\nmod executor;\n/// Types and methods to perform metric collection\npub mod metric;\n/// Types and methods to perform queries\npub mod query;\n#[cfg(feature = \"rbac\")]\n#[cfg_attr(docsrs, doc(cfg(feature = \"rbac\")))]\npub mod rbac;\n/// Types that defines the schemas of an Entity\npub mod schema;\n/// Helpers for working with Value\npub mod value;\n\n#[doc(hidden)]\n#[cfg(all(feature = \"macros\", feature = \"tests-cfg\"))]\npub mod tests_cfg;\nmod util;\n\npub use database::*;\n#[allow(unused_imports)]\npub use driver::*;\npub use entity::*;\npub use error::*;\npub use executor::*;\npub use query::*;\npub use schema::*;\n\n#[cfg(feature = \"macros\")]\npub use sea_orm_macros::{\n    DeriveActiveEnum, DeriveActiveModel, DeriveActiveModelBehavior, DeriveActiveModelEx,\n    DeriveArrowSchema, DeriveColumn, DeriveDisplay, DeriveEntity, DeriveEntityModel, DeriveIden,\n    DeriveIntoActiveModel, DeriveMigrationName, DeriveModel, DeriveModelEx, DerivePartialModel,\n    DerivePrimaryKey, DeriveRelatedEntity, DeriveRelation, DeriveValueType, FromJsonQueryResult,\n    FromQueryResult, raw_sql, sea_orm_compact_model as compact_model, sea_orm_model as model,\n};\n\npub use sea_query;\npub use sea_query::Iden;\n\npub use sea_orm_macros::EnumIter;\npub use strum;\n\n#[cfg(feature = \"with-arrow\")]\npub use sea_orm_arrow::arrow;\n\n#[cfg(feature = \"sqlx-dep\")]\npub use sqlx;\n"
  },
  {
    "path": "src/metric.rs",
    "content": "use std::{sync::Arc, time::Duration};\n\npub(crate) type Callback = Arc<dyn Fn(&Info<'_>) + Send + Sync>;\n\n#[allow(unused_imports)]\npub(crate) use inner::metric;\n\n#[derive(Debug)]\n/// Query execution infos\npub struct Info<'a> {\n    /// Query executiuon duration\n    pub elapsed: Duration,\n    /// Query data\n    pub statement: &'a crate::Statement,\n    /// Query execution failed\n    pub failed: bool,\n}\n\nmod inner {\n    #[allow(unused_macros)]\n    macro_rules! metric {\n        ($metric_callback:expr, $stmt:expr, $code:block) => {{\n            let _start = $metric_callback.is_some().then(std::time::SystemTime::now);\n            let res = $code;\n            if let (Some(_start), Some(callback)) = (_start, $metric_callback.as_deref()) {\n                let info = crate::metric::Info {\n                    elapsed: _start.elapsed().unwrap_or_default(),\n                    statement: $stmt,\n                    failed: res.is_err(),\n                };\n                callback(&info);\n            }\n            res\n        }};\n    }\n    pub(crate) use metric;\n}\n"
  },
  {
    "path": "src/query/combine.rs",
    "content": "use crate::{\n    ColumnTrait, EntityTrait, IdenStatic, Iterable, QueryTrait, Select, SelectTwo, SelectTwoMany,\n    SelectTwoRequired,\n};\nuse core::marker::PhantomData;\nuse sea_query::{Iden, IntoIden, Order, SelectExpr, SelectStatement, SimpleExpr};\nuse std::borrow::Cow;\n\nmacro_rules! select_def {\n    ( $ident: ident, $str: expr ) => {\n        /// Implements the traits [Iden] for select alias\n        #[derive(Debug, Clone, Copy)]\n        pub struct $ident;\n\n        impl Iden for $ident {\n            fn quoted(&self) -> Cow<'static, str> {\n                Cow::Borrowed(IdenStatic::as_str(self))\n            }\n\n            fn unquoted(&self) -> &str {\n                IdenStatic::as_str(self)\n            }\n        }\n\n        impl IdenStatic for $ident {\n            fn as_str(&self) -> &'static str {\n                $str\n            }\n        }\n    };\n}\n\nselect_def!(SelectA, \"A_\");\nselect_def!(SelectB, \"B_\");\nselect_def!(SelectC, \"C_\");\nselect_def!(SelectD, \"D_\");\nselect_def!(SelectE, \"E_\");\nselect_def!(SelectF, \"F_\");\n\nimpl<E> Select<E>\nwhere\n    E: EntityTrait,\n{\n    pub(crate) fn apply_alias(mut self, pre: &str) -> Self {\n        self.query().exprs_mut_for_each(|sel| {\n            match &sel.alias {\n                Some(alias) => {\n                    let alias = format!(\"{}{}\", pre, alias.to_string().as_str());\n                    sel.alias = Some(alias.into_iden());\n                }\n                None => {\n                    let col = match &sel.expr {\n                        SimpleExpr::Column(col_ref) => match col_ref.column() {\n                            Some(col) => col,\n                            None => {\n                                panic!(\"cannot apply alias for Column with asterisk\");\n                            }\n                        },\n                        SimpleExpr::AsEnum(_, simple_expr) => match simple_expr.as_ref() {\n                            SimpleExpr::Column(col_ref) => match col_ref.column() {\n                                Some(col) => col,\n                                None => {\n                                    panic!(\"cannot apply alias for AsEnum with asterisk\")\n                                }\n                            },\n                            _ => {\n                                panic!(\"cannot apply alias for AsEnum with expr other than Column\")\n                            }\n                        },\n                        _ => panic!(\"cannot apply alias for expr other than Column or AsEnum\"),\n                    };\n                    let alias = format!(\"{}{}\", pre, col.to_string().as_str());\n                    sel.alias = Some(alias.into_iden());\n                }\n            };\n        });\n        self\n    }\n\n    /// Selects extra Entity and returns it together with the Entity from `Self`\n    pub fn select_also<F>(mut self, _: F) -> SelectTwo<E, F>\n    where\n        F: EntityTrait,\n    {\n        self = self.apply_alias(SelectA.as_str());\n        SelectTwo::new(self.into_query())\n    }\n\n    /// Only used by Entity loader\n    #[doc(hidden)]\n    pub fn select_also_fake<F>(mut self, _: F) -> SelectTwo<E, F>\n    where\n        F: EntityTrait,\n    {\n        self = self.apply_alias(SelectA.as_str());\n        SelectTwo::new_without_prepare(self.into_query())\n    }\n\n    /// Makes a SELECT operation in conjunction to another relation\n    pub fn select_with<F>(mut self, _: F) -> SelectTwoMany<E, F>\n    where\n        F: EntityTrait,\n    {\n        self = self.apply_alias(SelectA.as_str());\n        SelectTwoMany::new(self.into_query())\n    }\n\n    /// Selects extra Entity and returns it together with the Entity from `Self`\n    pub fn select_two_required<F>(mut self, _: F) -> SelectTwoRequired<E, F>\n    where\n        F: EntityTrait,\n    {\n        self = self.apply_alias(SelectA.as_str());\n        SelectTwoRequired::new(self.into_query())\n    }\n}\n\nimpl<E, F> SelectTwo<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query).prepare_select()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<F, _, _>(&mut self, SelectB);\n        self\n    }\n}\n\nimpl<E, F> SelectTwoMany<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query)\n            .prepare_select()\n            .prepare_order_by()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<F, _, _>(&mut self, SelectB);\n        self\n    }\n\n    fn prepare_order_by(mut self) -> Self {\n        for col in <E::PrimaryKey as Iterable>::iter() {\n            self.query.order_by((E::default(), col), Order::Asc);\n        }\n        self\n    }\n}\n\nimpl<E, F> SelectTwoRequired<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    pub(crate) fn new(query: SelectStatement) -> Self {\n        Self::new_without_prepare(query).prepare_select()\n    }\n\n    pub(crate) fn new_without_prepare(query: SelectStatement) -> Self {\n        Self {\n            query,\n            entity: PhantomData,\n        }\n    }\n\n    fn prepare_select(mut self) -> Self {\n        prepare_select_col::<F, Self, _>(&mut self, SelectB);\n        self\n    }\n}\n\npub(crate) fn prepare_select_col<F, S, A>(selector: &mut S, alias: A)\nwhere\n    F: EntityTrait,\n    S: QueryTrait<QueryStatement = SelectStatement>,\n    A: IdenStatic,\n{\n    for col in <F::Column as Iterable>::iter() {\n        let alias = format!(\"{}{}\", alias.as_str(), col.as_str());\n        selector.query().expr(SelectExpr {\n            expr: col.select_as(col.into_expr()),\n            alias: Some(alias.into_iden()),\n            window: None,\n        });\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::{cake, fruit};\n    use crate::{ColumnTrait, DbBackend, EntityTrait, QueryFilter, QuerySelect, QueryTrait};\n\n    #[test]\n    fn alias_1() {\n        assert_eq!(\n            cake::Entity::find()\n                .column_as(cake::Column::Id, \"B\")\n                .apply_alias(\"A_\")\n                .build(DbBackend::MySql)\n                .to_string(),\n            \"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`, `cake`.`id` AS `A_B` FROM `cake`\",\n        );\n    }\n\n    #[test]\n    fn select_also_1() {\n        assert_eq!(\n            cake::Entity::find()\n                .left_join(fruit::Entity)\n                .select_also(fruit::Entity)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                \"`fruit`.`id` AS `B_id`, `fruit`.`name` AS `B_name`, `fruit`.`cake_id` AS `B_cake_id`\",\n                \"FROM `cake` LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`\",\n            ].join(\" \")\n        );\n    }\n\n    #[test]\n    fn select_with_1() {\n        assert_eq!(\n            cake::Entity::find()\n                .left_join(fruit::Entity)\n                .select_with(fruit::Entity)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                \"`fruit`.`id` AS `B_id`, `fruit`.`name` AS `B_name`, `fruit`.`cake_id` AS `B_cake_id`\",\n                \"FROM `cake` LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`\",\n                \"ORDER BY `cake`.`id` ASC\",\n            ].join(\" \")\n        );\n    }\n\n    #[test]\n    fn select_also_2() {\n        assert_eq!(\n            cake::Entity::find()\n                .left_join(fruit::Entity)\n                .select_also(fruit::Entity)\n                .filter(cake::Column::Id.eq(1))\n                .filter(fruit::Column::Id.eq(2))\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                \"`fruit`.`id` AS `B_id`, `fruit`.`name` AS `B_name`, `fruit`.`cake_id` AS `B_cake_id`\",\n                \"FROM `cake` LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`\",\n                \"WHERE `cake`.`id` = 1 AND `fruit`.`id` = 2\",\n            ].join(\" \")\n        );\n    }\n\n    #[test]\n    fn select_with_2() {\n        assert_eq!(\n            cake::Entity::find()\n                .left_join(fruit::Entity)\n                .select_with(fruit::Entity)\n                .filter(cake::Column::Id.eq(1))\n                .filter(fruit::Column::Id.eq(2))\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                \"`fruit`.`id` AS `B_id`, `fruit`.`name` AS `B_name`, `fruit`.`cake_id` AS `B_cake_id`\",\n                \"FROM `cake` LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`\",\n                \"WHERE `cake`.`id` = 1 AND `fruit`.`id` = 2\",\n                \"ORDER BY `cake`.`id` ASC\",\n            ].join(\" \")\n        );\n    }\n}\n"
  },
  {
    "path": "src/query/debug.rs",
    "content": "use crate::{QueryTrait, Statement, database::*};\n\n/// This structure provides debug capabilities\n#[derive(Debug)]\npub struct DebugQuery<'a, Q, T> {\n    /// The query to debug\n    pub query: &'a Q,\n    /// The value of the query\n    pub value: T,\n}\n\nmacro_rules! debug_query_build {\n    ($impl_obj:ty, $db_expr:expr) => {\n        impl<'a, Q> DebugQuery<'a, Q, $impl_obj>\n        where\n            Q: QueryTrait,\n        {\n            /// This macro builds a [Statement] when invoked\n            pub fn build(&self) -> Statement {\n                let func = $db_expr;\n                let db_backend = func(self);\n                self.query.build(db_backend)\n            }\n        }\n    };\n}\n\ndebug_query_build!(DbBackend, |x: &DebugQuery<_, DbBackend>| x.value);\ndebug_query_build!(&DbBackend, |x: &DebugQuery<_, &DbBackend>| *x.value);\ndebug_query_build!(DatabaseConnection, |x: &DebugQuery<\n    _,\n    DatabaseConnection,\n>| x.value.get_database_backend());\ndebug_query_build!(&DatabaseConnection, |x: &DebugQuery<\n    _,\n    &DatabaseConnection,\n>| x.value.get_database_backend());\n\n/// Helper to get a `Statement` from an object that impl `QueryTrait`.\n///\n/// # Example\n///\n/// ```\n/// # #[cfg(feature = \"mock\")]\n/// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, DbBackend};\n/// #\n/// # let conn = MockDatabase::new(DbBackend::Postgres)\n/// #     .into_connection();\n/// #\n/// use sea_orm::{debug_query_stmt, entity::*, query::*, tests_cfg::cake};\n///\n/// let c = cake::Entity::insert(cake::ActiveModel {\n///     id: ActiveValue::set(1),\n///     name: ActiveValue::set(\"Apple Pie\".to_owned()),\n/// });\n///\n/// let raw_sql = debug_query_stmt!(&c, &conn).to_string();\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#\n/// );\n///\n/// let raw_sql = debug_query_stmt!(&c, conn).to_string();\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#\n/// );\n///\n/// let raw_sql = debug_query_stmt!(&c, DbBackend::MySql).to_string();\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO `cake` (`id`, `name`) VALUES (1, 'Apple Pie')\"#\n/// );\n///\n/// let raw_sql = debug_query_stmt!(&c, &DbBackend::MySql).to_string();\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO `cake` (`id`, `name`) VALUES (1, 'Apple Pie')\"#\n/// );\n/// ```\n#[macro_export]\nmacro_rules! debug_query_stmt {\n    ($query:expr,$value:expr) => {\n        $crate::DebugQuery {\n            query: $query,\n            value: $value,\n        }\n        .build();\n    };\n}\n\n/// Helper to get a raw SQL string from an object that impl `QueryTrait`.\n///\n/// # Example\n///\n/// ```\n/// # #[cfg(feature = \"mock\")]\n/// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, DbBackend};\n/// #\n/// # let conn = MockDatabase::new(DbBackend::Postgres)\n/// #     .into_connection();\n/// #\n/// use sea_orm::{debug_query, entity::*, query::*, tests_cfg::cake};\n///\n/// let c = cake::Entity::insert(cake::ActiveModel {\n///     id: ActiveValue::set(1),\n///     name: ActiveValue::set(\"Apple Pie\".to_owned()),\n/// });\n///\n/// let raw_sql = debug_query!(&c, &conn);\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#\n/// );\n///\n/// let raw_sql = debug_query!(&c, conn);\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#\n/// );\n///\n/// let raw_sql = debug_query!(&c, DbBackend::Sqlite);\n/// assert_eq!(\n///     raw_sql,\n///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#\n/// );\n/// ```\n#[macro_export]\nmacro_rules! debug_query {\n    ($query:expr,$value:expr) => {\n        $crate::debug_query_stmt!($query, $value).to_string();\n    };\n}\n"
  },
  {
    "path": "src/query/delete.rs",
    "content": "use crate::{\n    ActiveModelTrait, ActiveValue, ColumnTrait, DbBackend, DbErr, EntityTrait, IntoActiveModel,\n    Iterable, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryTrait,\n    query::column_tuple_in_condition,\n    sea_query::{IntoValueTuple, ValueTuple},\n};\nuse core::marker::PhantomData;\nuse sea_query::DeleteStatement;\n\n/// Defines the structure for a delete operation\n#[derive(Clone, Debug)]\npub struct Delete;\n\n/// A request to delete an [`ActiveModel`](ActiveModelTrait).\n///\n/// The primary key must be set.\n/// Otherwise, it's impossible to generate the SQL condition and find the record.\n/// In that case, [`exec`][Self::exec] will return an error and not send any queries to the database.\n///\n/// If you want to use [`QueryTrait`] and access the generated SQL query,\n/// you need to convert into [`ValidatedDeleteOne`] first.\n#[derive(Clone, Debug)]\npub struct DeleteOne<E: EntityTrait>(pub(crate) Result<ValidatedDeleteOne<E>, DbErr>);\n\n/// A validated [`DeleteOne`] request, where the primary key is set\n/// and it's possible to generate the right SQL condition.\n#[derive(Clone, Debug)]\npub struct ValidatedDeleteOne<E: EntityTrait> {\n    pub(crate) query: DeleteStatement,\n    pub(crate) entity: PhantomData<E>,\n}\n\nimpl<E: EntityTrait> TryFrom<DeleteOne<E>> for ValidatedDeleteOne<E> {\n    type Error = DbErr;\n\n    fn try_from(value: DeleteOne<E>) -> Result<Self, Self::Error> {\n        value.0\n    }\n}\n\nimpl<E: EntityTrait> DeleteOne<E> {\n    /// Check whether the primary key is set and we can proceed with the operation.\n    pub fn validate(self) -> Result<ValidatedDeleteOne<E>, DbErr> {\n        self.try_into()\n    }\n}\n\n/// Perform a delete operation on multiple models\n#[derive(Clone, Debug)]\npub struct DeleteMany<E>\nwhere\n    E: EntityTrait,\n{\n    pub(crate) query: DeleteStatement,\n    pub(crate) entity: PhantomData<E>,\n}\n\nimpl Delete {\n    /// Delete one Model or ActiveModel\n    ///\n    /// Model\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     Delete::one(cake::Model {\n    ///         id: 1,\n    ///         name: \"Apple Pie\".to_owned(),\n    ///     })\n    ///     .validate()\n    ///     .unwrap()\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"DELETE FROM \"cake\" WHERE \"cake\".\"id\" = 1\"#,\n    /// );\n    /// ```\n    /// ActiveModel\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     Delete::one(cake::ActiveModel {\n    ///         id: ActiveValue::set(1),\n    ///         name: ActiveValue::set(\"Apple Pie\".to_owned()),\n    ///     })\n    ///     .validate()\n    ///     .unwrap()\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"DELETE FROM \"cake\" WHERE \"cake\".\"id\" = 1\"#,\n    /// );\n    /// ```\n    //\n    // (non-doc comment for maintainers)\n    // Ideally, we would make this method fallible instead of stashing and delaying the error.\n    // But that's a bigger breaking change.\n    pub fn one<E, A, M>(model: M) -> DeleteOne<E>\n    where\n        E: EntityTrait,\n        A: ActiveModelTrait<Entity = E>,\n        M: IntoActiveModel<A>,\n    {\n        let model = model.into_active_model();\n        let mut myself = ValidatedDeleteOne {\n            query: DeleteStatement::new()\n                .from_table(A::Entity::default().table_ref())\n                .to_owned(),\n            entity: PhantomData,\n        };\n        // Build the SQL condition from the primary key columns.\n        for key in <A::Entity as EntityTrait>::PrimaryKey::iter() {\n            let col = key.into_column();\n            let av = model.get(col);\n            match av {\n                ActiveValue::Set(value) | ActiveValue::Unchanged(value) => {\n                    myself = myself.filter(col.eq(value));\n                }\n                ActiveValue::NotSet => {\n                    return DeleteOne(Err(DbErr::PrimaryKeyNotSet { ctx: \"DeleteOne\" }));\n                }\n            }\n        }\n        DeleteOne(Ok(myself))\n    }\n\n    #[doc(hidden)]\n    pub fn _one_only_for_use_by_model_ex<E: EntityTrait>(entity: E) -> ValidatedDeleteOne<E> {\n        ValidatedDeleteOne {\n            query: DeleteStatement::new()\n                .from_table(entity.table_ref())\n                .to_owned(),\n            entity: PhantomData,\n        }\n    }\n\n    /// Delete many ActiveModel\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::fruit};\n    ///\n    /// assert_eq!(\n    ///     Delete::many(fruit::Entity)\n    ///         .filter(fruit::Column::Name.contains(\"Apple\"))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"DELETE FROM \"fruit\" WHERE \"fruit\".\"name\" LIKE '%Apple%'\"#,\n    /// );\n    /// ```\n    pub fn many<E>(entity: E) -> DeleteMany<E>\n    where\n        E: EntityTrait,\n    {\n        DeleteMany {\n            query: DeleteStatement::new()\n                .from_table(entity.table_ref())\n                .to_owned(),\n            entity: PhantomData,\n        }\n    }\n}\n\nimpl<E> QueryFilter for ValidatedDeleteOne<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = DeleteStatement;\n\n    fn query(&mut self) -> &mut DeleteStatement {\n        &mut self.query\n    }\n}\n\nimpl<E> QueryFilter for DeleteMany<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = DeleteStatement;\n\n    fn query(&mut self) -> &mut DeleteStatement {\n        &mut self.query\n    }\n}\n\nimpl<E> DeleteMany<E>\nwhere\n    E: EntityTrait,\n{\n    /// Filter by vector of IDs by primary key\n    ///\n    /// # Panics\n    ///\n    /// Should not panic.\n    pub fn filter_by_ids<I>(mut self, values: I) -> Self\n    where\n        I: IntoIterator<Item = <E::PrimaryKey as PrimaryKeyTrait>::ValueType>,\n    {\n        self.query.cond_where(\n            column_tuple_in_condition(\n                &E::default().table_ref(),\n                &E::primary_key_identity(),\n                &values\n                    .into_iter()\n                    .map(|v| v.into_value_tuple())\n                    .collect::<Vec<_>>(),\n                DbBackend::Sqlite,\n            )\n            .expect(\"trait bound ensured arity\"),\n        );\n        self\n    }\n\n    #[doc(hidden)]\n    /// # Panics\n    ///\n    /// Panic if `ValueTuple` arity does not match primary key\n    pub fn filter_by_value_tuples(mut self, values: &[ValueTuple], db_backend: DbBackend) -> Self {\n        self.query.cond_where(\n            column_tuple_in_condition(\n                &E::default().table_ref(),\n                &E::primary_key_identity(),\n                values,\n                db_backend,\n            )\n            .expect(\"\"),\n        );\n        self\n    }\n}\n\nimpl<E> QueryTrait for ValidatedDeleteOne<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = DeleteStatement;\n\n    fn query(&mut self) -> &mut DeleteStatement {\n        &mut self.query\n    }\n\n    fn as_query(&self) -> &DeleteStatement {\n        &self.query\n    }\n\n    fn into_query(self) -> DeleteStatement {\n        self.query\n    }\n}\n\nimpl<E> QueryTrait for DeleteMany<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = DeleteStatement;\n\n    fn query(&mut self) -> &mut DeleteStatement {\n        &mut self.query\n    }\n\n    fn as_query(&self) -> &DeleteStatement {\n        &self.query\n    }\n\n    fn into_query(self) -> DeleteStatement {\n        self.query\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::{cake, fruit};\n    use crate::{DbBackend, entity::*, query::*};\n\n    #[test]\n    fn delete_1() {\n        assert_eq!(\n            Delete::one(cake::Model {\n                id: 1,\n                name: \"Apple Pie\".to_owned(),\n            })\n            .validate()\n            .unwrap()\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"DELETE FROM \"cake\" WHERE \"cake\".\"id\" = 1\"#,\n        );\n        assert_eq!(\n            Delete::one(cake::ActiveModel {\n                id: ActiveValue::set(1),\n                name: ActiveValue::set(\"Apple Pie\".to_owned()),\n            })\n            .validate()\n            .unwrap()\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"DELETE FROM \"cake\" WHERE \"cake\".\"id\" = 1\"#,\n        );\n    }\n\n    #[test]\n    fn delete_2() {\n        assert_eq!(\n            Delete::many(fruit::Entity)\n                .filter(fruit::Column::Name.contains(\"Cheese\"))\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"DELETE FROM \"fruit\" WHERE \"fruit\".\"name\" LIKE '%Cheese%'\"#,\n        );\n    }\n}\n"
  },
  {
    "path": "src/query/helper.rs",
    "content": "use crate::{\n    ActiveModelTrait, ColumnAsExpr, ColumnTrait, EntityTrait, Identity, IntoIdentity,\n    IntoSimpleExpr, Iterable, ModelTrait, PrimaryKeyToColumn, RelationDef,\n};\nuse sea_query::{\n    Alias, Expr, ExprTrait, IntoCondition, IntoIden, LockBehavior, LockType, NullOrdering, SeaRc,\n    SelectExpr, SelectStatement, SimpleExpr,\n};\npub use sea_query::{Condition, ConditionalStatement, DynIden, JoinType, Order, OrderedStatement};\n\nuse sea_query::IntoColumnRef;\n\n// LINT: when the column does not appear in tables selected from\n// LINT: when there is a group by clause, but some columns don't have aggregate functions\n// LINT: when the join table or column does not exists\n/// Abstract API for performing queries\npub trait QuerySelect: Sized {\n    #[allow(missing_docs)]\n    type QueryStatement;\n\n    /// Add the select SQL statement\n    fn query(&mut self) -> &mut SelectStatement;\n\n    /// Clear the selection list\n    fn select_only(mut self) -> Self {\n        self.query().clear_selects();\n        self\n    }\n\n    /// Add a select column\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .column(cake::Column::Name)\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"name\" FROM \"cake\"\"#\n    /// );\n    /// ```\n    ///\n    /// Enum column will be casted into text (PostgreSQL only)\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::lunch_set};\n    ///\n    /// assert_eq!(\n    ///     lunch_set::Entity::find()\n    ///         .select_only()\n    ///         .column(lunch_set::Column::Tea)\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT CAST(\"lunch_set\".\"tea\" AS \"text\") FROM \"lunch_set\"\"#\n    /// );\n    /// assert_eq!(\n    ///     lunch_set::Entity::find()\n    ///         .select_only()\n    ///         .column(lunch_set::Column::Tea)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     r#\"SELECT `lunch_set`.`tea` FROM `lunch_set`\"#\n    /// );\n    /// ```\n    fn column<C>(mut self, col: C) -> Self\n    where\n        C: ColumnTrait,\n    {\n        self.query().expr(col.select_as(col.into_expr()));\n        self\n    }\n\n    /// Add a select column with alias\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .column_as(cake::Column::Id.count(), \"count\")\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT COUNT(\"cake\".\"id\") AS \"count\" FROM \"cake\"\"#\n    /// );\n    /// ```\n    fn column_as<C, I>(mut self, col: C, alias: I) -> Self\n    where\n        C: ColumnAsExpr,\n        I: IntoIdentity,\n    {\n        self.query().expr(SelectExpr {\n            expr: col.into_column_as_expr(),\n            alias: Some(SeaRc::new(alias.into_identity())),\n            window: None,\n        });\n        self\n    }\n\n    /// Select columns\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .columns([cake::Column::Id, cake::Column::Name])\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#\n    /// );\n    /// ```\n    ///\n    /// Conditionally select all columns expect a specific column\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .columns(cake::Column::iter().filter(|col| match col {\n    ///             cake::Column::Id => false,\n    ///             _ => true,\n    ///         }))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"name\" FROM \"cake\"\"#\n    /// );\n    /// ```\n    ///\n    /// Enum column will be casted into text (PostgreSQL only)\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::lunch_set};\n    ///\n    /// assert_eq!(\n    ///     lunch_set::Entity::find()\n    ///         .select_only()\n    ///         .columns([lunch_set::Column::Name, lunch_set::Column::Tea])\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"lunch_set\".\"name\", CAST(\"lunch_set\".\"tea\" AS \"text\") FROM \"lunch_set\"\"#\n    /// );\n    /// assert_eq!(\n    ///     lunch_set::Entity::find()\n    ///         .select_only()\n    ///         .columns([lunch_set::Column::Name, lunch_set::Column::Tea])\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     r#\"SELECT `lunch_set`.`name`, `lunch_set`.`tea` FROM `lunch_set`\"#\n    /// );\n    /// ```\n    fn columns<C, I>(mut self, cols: I) -> Self\n    where\n        C: ColumnTrait,\n        I: IntoIterator<Item = C>,\n    {\n        for col in cols.into_iter() {\n            self = self.column(col);\n        }\n        self\n    }\n\n    /// Add an offset expression. Passing in None would remove the offset.\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .offset(10)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` OFFSET 10\"\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .offset(Some(10))\n    ///         .offset(Some(20))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` OFFSET 20\"\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .offset(10)\n    ///         .offset(None)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\"\n    /// );\n    /// ```\n    fn offset<T>(mut self, offset: T) -> Self\n    where\n        T: Into<Option<u64>>,\n    {\n        if let Some(offset) = offset.into() {\n            self.query().offset(offset);\n        } else {\n            self.query().reset_offset();\n        }\n        self\n    }\n\n    /// Add a limit expression. Passing in None would remove the limit.\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .limit(10)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` LIMIT 10\"\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .limit(Some(10))\n    ///         .limit(Some(20))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` LIMIT 20\"\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .limit(10)\n    ///         .limit(None)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\"\n    /// );\n    /// ```\n    fn limit<T>(mut self, limit: T) -> Self\n    where\n        T: Into<Option<u64>>,\n    {\n        if let Some(limit) = limit.into() {\n            self.query().limit(limit);\n        } else {\n            self.query().reset_limit();\n        }\n        self\n    }\n\n    /// Add a group by column\n    /// ```\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake, DbBackend};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .column(cake::Column::Name)\n    ///         .group_by(cake::Column::Name)\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"name\" FROM \"cake\" GROUP BY \"cake\".\"name\"\"#\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .column_as(cake::Column::Id.count(), \"count\")\n    ///         .column_as(cake::Column::Id.sum(), \"sum_of_id\")\n    ///         .group_by(cake::Column::Name)\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT COUNT(\"cake\".\"id\") AS \"count\", SUM(\"cake\".\"id\") AS \"sum_of_id\" FROM \"cake\" GROUP BY \"cake\".\"name\"\"#\n    /// );\n    /// ```\n    fn group_by<C>(mut self, col: C) -> Self\n    where\n        C: IntoSimpleExpr,\n    {\n        self.query().add_group_by([col.into_simple_expr()]);\n        self\n    }\n\n    /// Add an AND HAVING expression\n    /// ```\n    /// use sea_orm::{sea_query::{Alias, Expr, ExprTrait}, entity::*, query::*, tests_cfg::cake, DbBackend};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .having(cake::Column::Id.eq(4))\n    ///         .having(cake::Column::Id.eq(5))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` HAVING `cake`.`id` = 4 AND `cake`.`id` = 5\"\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .column_as(cake::Column::Id.count(), \"count\")\n    ///         .column_as(cake::Column::Id.sum(), \"sum_of_id\")\n    ///         .group_by(cake::Column::Name)\n    ///         .having(Expr::col(\"count\").gt(6))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT COUNT(`cake`.`id`) AS `count`, SUM(`cake`.`id`) AS `sum_of_id` FROM `cake` GROUP BY `cake`.`name` HAVING `count` > 6\"\n    /// );\n    /// ```\n    fn having<F>(mut self, filter: F) -> Self\n    where\n        F: IntoCondition,\n    {\n        self.query().cond_having(filter.into_condition());\n        self\n    }\n\n    /// Add a DISTINCT expression\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    /// struct Input {\n    ///     name: Option<String>,\n    /// }\n    /// let input = Input {\n    ///     name: Some(\"cheese\".to_owned()),\n    /// };\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(\n    ///             Condition::all().add_option(input.name.map(|n| cake::Column::Name.contains(&n)))\n    ///         )\n    ///         .distinct()\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT DISTINCT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE '%cheese%'\"\n    /// );\n    /// ```\n    fn distinct(mut self) -> Self {\n        self.query().distinct();\n        self\n    }\n\n    /// Add a DISTINCT ON expression\n    /// NOTE: this function is only supported by `sqlx-postgres`\n    /// ```\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake, DbBackend};\n    /// struct Input {\n    ///     name: Option<String>,\n    /// }\n    /// let input = Input {\n    ///     name: Some(\"cheese\".to_owned()),\n    /// };\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(\n    ///             Condition::all().add_option(input.name.map(|n| cake::Column::Name.contains(&n)))\n    ///         )\n    ///         .distinct_on([(cake::Entity, cake::Column::Name)])\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT DISTINCT ON (\"cake\".\"name\") \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"name\" LIKE '%cheese%'\"#\n    /// );\n    /// ```\n    fn distinct_on<T, I>(mut self, cols: I) -> Self\n    where\n        T: IntoColumnRef,\n        I: IntoIterator<Item = T>,\n    {\n        self.query().distinct_on(cols);\n        self\n    }\n\n    #[doc(hidden)]\n    fn join_join(mut self, join: JoinType, rel: RelationDef, via: Option<RelationDef>) -> Self {\n        if let Some(via) = via {\n            self = self.join(join, via)\n        }\n        self.join(join, rel)\n    }\n\n    #[doc(hidden)]\n    fn join_join_rev(mut self, join: JoinType, rel: RelationDef, via: Option<RelationDef>) -> Self {\n        self = self.join_rev(join, rel);\n        if let Some(via) = via {\n            self = self.join_rev(join, via)\n        }\n        self\n    }\n\n    /// Join via [`RelationDef`].\n    fn join(mut self, join: JoinType, rel: RelationDef) -> Self {\n        self.query().join(join, rel.to_tbl.clone(), rel);\n        self\n    }\n\n    /// Join via [`RelationDef`] but in reverse direction.\n    /// Assume when there exist a relation A to B.\n    /// You can reverse join B from A.\n    fn join_rev(mut self, join: JoinType, rel: RelationDef) -> Self {\n        self.query().join(join, rel.from_tbl.clone(), rel);\n        self\n    }\n\n    /// Join via [`RelationDef`] with table alias.\n    fn join_as<I>(mut self, join: JoinType, mut rel: RelationDef, alias: I) -> Self\n    where\n        I: IntoIden,\n    {\n        let alias = alias.into_iden();\n        rel.to_tbl = rel.to_tbl.alias(alias.clone());\n        self.query().join(join, rel.to_tbl.clone(), rel);\n        self\n    }\n\n    /// Join via [`RelationDef`] with table alias but in reverse direction.\n    /// Assume when there exist a relation A to B.\n    /// You can reverse join B from A.\n    fn join_as_rev<I>(mut self, join: JoinType, mut rel: RelationDef, alias: I) -> Self\n    where\n        I: IntoIden,\n    {\n        let alias = alias.into_iden();\n        rel.from_tbl = rel.from_tbl.alias(alias.clone());\n        self.query().join(join, rel.from_tbl.clone(), rel);\n        self\n    }\n\n    /// Select lock\n    fn lock(mut self, lock_type: LockType) -> Self {\n        self.query().lock(lock_type);\n        self\n    }\n\n    /// Select lock shared\n    fn lock_shared(mut self) -> Self {\n        self.query().lock_shared();\n        self\n    }\n\n    /// Select lock exclusive\n    fn lock_exclusive(mut self) -> Self {\n        self.query().lock_exclusive();\n        self\n    }\n\n    /// Row locking with behavior (if supported).\n    ///\n    /// See [`SelectStatement::lock_with_behavior`](https://docs.rs/sea-query/*/sea_query/query/struct.SelectStatement.html#method.lock_with_behavior).\n    fn lock_with_behavior(mut self, r#type: LockType, behavior: LockBehavior) -> Self {\n        self.query().lock_with_behavior(r#type, behavior);\n        self\n    }\n\n    /// Add an expression to the select expression list.\n    /// ```\n    /// use sea_orm::sea_query::Expr;\n    /// use sea_orm::{DbBackend, QuerySelect, QueryTrait, entity::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .expr(Expr::col((cake::Entity, cake::Column::Id)))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id` FROM `cake`\"\n    /// );\n    /// ```\n    fn expr<T>(mut self, expr: T) -> Self\n    where\n        T: Into<SelectExpr>,\n    {\n        self.query().expr(expr);\n        self\n    }\n\n    /// Add select expressions from vector of [`SelectExpr`].\n    /// ```\n    /// use sea_orm::sea_query::Expr;\n    /// use sea_orm::{DbBackend, QuerySelect, QueryTrait, entity::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .exprs([\n    ///             Expr::col((cake::Entity, cake::Column::Id)),\n    ///             Expr::col((cake::Entity, cake::Column::Name)),\n    ///         ])\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\"\n    /// );\n    /// ```\n    fn exprs<T, I>(mut self, exprs: I) -> Self\n    where\n        T: Into<SelectExpr>,\n        I: IntoIterator<Item = T>,\n    {\n        self.query().exprs(exprs);\n        self\n    }\n\n    /// Select column.\n    /// ```\n    /// use sea_orm::sea_query::{Alias, Expr, Func};\n    /// use sea_orm::{DbBackend, QuerySelect, QueryTrait, entity::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .expr_as(\n    ///             Func::upper(Expr::col((cake::Entity, cake::Column::Name))),\n    ///             \"name_upper\"\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name`, UPPER(`cake`.`name`) AS `name_upper` FROM `cake`\"\n    /// );\n    /// ```\n    fn expr_as<T, A>(mut self, expr: T, alias: A) -> Self\n    where\n        T: Into<SimpleExpr>,\n        A: IntoIdentity,\n    {\n        self.query().expr_as(expr, alias.into_identity());\n        self\n    }\n\n    /// Shorthand of `expr_as(Expr::col((T, C)), A)`.\n    ///\n    /// ```\n    /// use sea_orm::sea_query::{Alias, Expr, Func};\n    /// use sea_orm::{DbBackend, QuerySelect, QueryTrait, entity::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .select_only()\n    ///         .tbl_col_as((cake::Entity, cake::Column::Name), \"cake_name\")\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`name` AS `cake_name` FROM `cake`\"\n    /// );\n    /// ```\n    fn tbl_col_as<T, C, A>(mut self, (tbl, col): (T, C), alias: A) -> Self\n    where\n        T: IntoIden + 'static,\n        C: IntoIden + 'static,\n        A: IntoIdentity,\n    {\n        self.query()\n            .expr_as(Expr::col((tbl, col)), alias.into_identity());\n        self\n    }\n}\n\n// LINT: when the column does not appear in tables selected from\n/// Performs ORDER BY operations\npub trait QueryOrder: Sized {\n    #[allow(missing_docs)]\n    type QueryStatement: OrderedStatement;\n\n    /// Add the query to perform an ORDER BY operation\n    fn query(&mut self) -> &mut SelectStatement;\n\n    /// Add an order_by expression\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .order_by(cake::Column::Id, Order::Asc)\n    ///         .order_by(cake::Column::Name, Order::Desc)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` ORDER BY `cake`.`id` ASC, `cake`.`name` DESC\"\n    /// );\n    /// ```\n    fn order_by<C>(mut self, col: C, ord: Order) -> Self\n    where\n        C: IntoSimpleExpr,\n    {\n        self.query().order_by_expr(col.into_simple_expr(), ord);\n        self\n    }\n\n    /// Add an order_by expression (ascending)\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .order_by_asc(cake::Column::Id)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` ORDER BY `cake`.`id` ASC\"\n    /// );\n    /// ```\n    fn order_by_asc<C>(mut self, col: C) -> Self\n    where\n        C: IntoSimpleExpr,\n    {\n        self.query()\n            .order_by_expr(col.into_simple_expr(), Order::Asc);\n        self\n    }\n\n    /// Add an order_by expression (descending)\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .order_by_desc(cake::Column::Id)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` ORDER BY `cake`.`id` DESC\"\n    /// );\n    /// ```\n    fn order_by_desc<C>(mut self, col: C) -> Self\n    where\n        C: IntoSimpleExpr,\n    {\n        self.query()\n            .order_by_expr(col.into_simple_expr(), Order::Desc);\n        self\n    }\n\n    /// Add an order_by expression with nulls ordering option\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    /// use sea_query::NullOrdering;\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .order_by_with_nulls(cake::Column::Id, Order::Asc, NullOrdering::First)\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" ORDER BY \"cake\".\"id\" ASC NULLS FIRST\"#\n    /// );\n    /// ```\n    fn order_by_with_nulls<C>(mut self, col: C, ord: Order, nulls: NullOrdering) -> Self\n    where\n        C: IntoSimpleExpr,\n    {\n        self.query()\n            .order_by_expr_with_nulls(col.into_simple_expr(), ord, nulls);\n        self\n    }\n}\n\n// LINT: when the column does not appear in tables selected from\n/// Perform a FILTER opertation on a statement\npub trait QueryFilter: Sized {\n    #[allow(missing_docs)]\n    type QueryStatement: ConditionalStatement;\n\n    /// Add the query to perform a FILTER on\n    fn query(&mut self) -> &mut Self::QueryStatement;\n\n    /// Add an AND WHERE expression\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.eq(4))\n    ///         .filter(cake::Column::Id.eq(5))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = 4 AND `cake`.`id` = 5\"\n    /// );\n    /// ```\n    ///\n    /// Add a condition tree.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(\n    ///             Condition::any()\n    ///                 .add(cake::Column::Id.eq(4))\n    ///                 .add(cake::Column::Id.eq(5))\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = 4 OR `cake`.`id` = 5\"\n    /// );\n    /// ```\n    ///\n    /// Like above, but using the `IN` operator.\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.is_in([4, 5]))\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` IN (4, 5)\"\n    /// );\n    /// ```\n    ///\n    /// Like above, but using the `ANY` operator. Postgres only.\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(cake::Column::Id.eq_any([4, 5]))\n    ///         .build(DbBackend::Postgres),\n    ///     Statement::from_sql_and_values(\n    ///         DbBackend::Postgres,\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = ANY($1)\"#,\n    ///         [vec![4, 5].into()]\n    ///     )\n    /// );\n    /// ```\n    ///\n    /// Add a runtime-built condition tree.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    /// struct Input {\n    ///     name: Option<String>,\n    /// }\n    /// let input = Input {\n    ///     name: Some(\"cheese\".to_owned()),\n    /// };\n    ///\n    /// let mut conditions = Condition::all();\n    /// if let Some(name) = input.name {\n    ///     conditions = conditions.add(cake::Column::Name.contains(&name));\n    /// }\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(conditions)\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE '%cheese%'\"\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(Condition::all())\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE TRUE\"\n    /// );\n    /// ```\n    ///\n    /// Add a runtime-built condition tree, functional-way.\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    /// struct Input {\n    ///     name: Option<String>,\n    /// }\n    /// let input = Input {\n    ///     name: Some(\"cheese\".to_owned()),\n    /// };\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(\n    ///             Condition::all().add_option(input.name.map(|n| cake::Column::Name.contains(&n)))\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`name` LIKE '%cheese%'\"\n    /// );\n    /// ```\n    ///\n    /// A slightly more complex example.\n    /// ```\n    /// use sea_orm::{entity::*, query::*, tests_cfg::cake, sea_query::{Expr, ExprTrait}, DbBackend};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .filter(\n    ///             Condition::all()\n    ///                 .add(\n    ///                     Condition::all()\n    ///                         .not()\n    ///                         .add(Expr::val(1).eq(1))\n    ///                         .add(Expr::val(2).eq(2))\n    ///                 )\n    ///                 .add(\n    ///                     Condition::any()\n    ///                         .add(Expr::val(3).eq(3))\n    ///                         .add(Expr::val(4).eq(4))\n    ///                 )\n    ///         )\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE (NOT (1 = 1 AND 2 = 2)) AND (3 = 3 OR 4 = 4)\"#\n    /// );\n    /// ```\n    /// Use a sea_query expression\n    /// ```\n    /// use sea_orm::{entity::*, query::*, sea_query::{Expr, ExprTrait}, tests_cfg::fruit, DbBackend};\n    ///\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .filter(Expr::col(fruit::Column::CakeId).is_null())\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `cake_id` IS NULL\"\n    /// );\n    /// ```\n    fn filter<F>(mut self, filter: F) -> Self\n    where\n        F: IntoCondition,\n    {\n        self.query().cond_where(filter.into_condition());\n        self\n    }\n\n    /// Like [`Self::filter`], but without consuming self\n    fn filter_mut<F>(&mut self, filter: F)\n    where\n        F: IntoCondition,\n    {\n        self.query().cond_where(filter.into_condition());\n    }\n\n    /// Apply a where condition using the model's primary key\n    /// ```\n    /// # use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::{cake, fruit}};\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .left_join(cake::Entity)\n    ///         .belongs_to(&cake::Model {\n    ///             id: 12,\n    ///             name: \"\".into(),\n    ///         })\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     [\n    ///         \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\",\n    ///         \"LEFT JOIN `cake` ON `fruit`.`cake_id` = `cake`.`id`\",\n    ///         \"WHERE `cake`.`id` = 12\",\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    /// ```\n    fn belongs_to<M>(mut self, model: &M) -> Self\n    where\n        M: ModelTrait,\n    {\n        for key in <M::Entity as EntityTrait>::PrimaryKey::iter() {\n            let col = key.into_column();\n            self = self.filter(col.eq(model.get(col)));\n        }\n        self\n    }\n\n    /// Like `belongs_to`, but for an ActiveModel. Panic if primary key is not set.\n    #[doc(hidden)]\n    fn belongs_to_active_model<AM>(mut self, model: &AM) -> Self\n    where\n        AM: ActiveModelTrait,\n    {\n        for key in <AM::Entity as EntityTrait>::PrimaryKey::iter() {\n            let col = key.into_column();\n            self = self.filter(col.eq(model.get(col).unwrap()));\n        }\n        self\n    }\n\n    /// Like `belongs_to`, but via a table alias\n    /// ```\n    /// # use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::{cake, fruit}};\n    /// assert_eq!(\n    ///     fruit::Entity::find()\n    ///         .join_as(JoinType::LeftJoin, fruit::Relation::Cake.def(), \"puff\")\n    ///         .belongs_to_tbl_alias(\n    ///             &cake::Model {\n    ///                 id: 12,\n    ///                 name: \"\".into(),\n    ///             },\n    ///             \"puff\"\n    ///         )\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     [\n    ///         \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\",\n    ///         \"LEFT JOIN `cake` AS `puff` ON `fruit`.`cake_id` = `puff`.`id`\",\n    ///         \"WHERE `puff`.`id` = 12\",\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    /// ```\n    fn belongs_to_tbl_alias<M>(mut self, model: &M, tbl_alias: &str) -> Self\n    where\n        M: ModelTrait,\n    {\n        for key in <M::Entity as EntityTrait>::PrimaryKey::iter() {\n            let col = key.into_column();\n            let expr = Expr::col((Alias::new(tbl_alias), col)).eq(model.get(col));\n            self = self.filter(expr);\n        }\n        self\n    }\n}\n\npub(crate) fn join_tbl_on_condition(\n    from_tbl: DynIden,\n    to_tbl: DynIden,\n    owner_keys: Identity,\n    foreign_keys: Identity,\n) -> Condition {\n    let mut cond = Condition::all();\n    for (owner_key, foreign_key) in owner_keys.into_iter().zip(foreign_keys.into_iter()) {\n        cond = cond\n            .add(Expr::col((from_tbl.clone(), owner_key)).equals((to_tbl.clone(), foreign_key)));\n    }\n    cond\n}\n"
  },
  {
    "path": "src/query/insert.rs",
    "content": "use crate::{\n    ActiveModelTrait, ActiveValue, ColumnTrait, EntityName, EntityTrait, IntoActiveModel, Iterable,\n    PrimaryKeyTrait, QueryTrait,\n};\nuse core::marker::PhantomData;\nuse sea_query::{Expr, InsertStatement, Keyword, OnConflict, SimpleExpr, Value, ValueTuple};\n\n/// Performs INSERT operations on a ActiveModel\n#[derive(Debug)]\npub struct Insert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    pub(crate) query: InsertStatement,\n    pub(crate) primary_key: Option<ValueTuple>,\n    pub(crate) model: PhantomData<A>,\n}\n\n/// Performs INSERT operations on many ActiveModels\n#[derive(Debug)]\npub struct InsertMany<A>\nwhere\n    A: ActiveModelTrait,\n{\n    pub(crate) query: InsertStatement,\n    pub(crate) primary_key: Option<ValueTuple>,\n    pub(crate) empty: bool,\n    pub(crate) model: PhantomData<A>,\n}\n\n/// Wrapper of [`Insert`] / [`InsertMany`], treats \"no row inserted/id returned\" as a normal outcome.\n///\n/// Its `exec*` methods return [`crate::TryInsertResult`].\n/// Mapping empty input to [`crate::TryInsertResult::Empty`] (no SQL executed) and\n/// `DbErr::RecordNotInserted` to [`crate::TryInsertResult::Conflicted`].\n///\n/// Useful for idempotent inserts such as `ON CONFLICT ... DO NOTHING` (Postgres / SQLite) or the\n/// MySQL polyfill (`ON DUPLICATE KEY UPDATE pk = pk`).\n#[derive(Debug)]\npub struct TryInsert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    pub(crate) insert_struct: Insert<A>,\n    pub(crate) empty: bool,\n}\n\nimpl<A> Insert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Insert one Model or ActiveModel\n    ///\n    /// Model\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     Insert::one(cake::Model {\n    ///         id: 1,\n    ///         name: \"Apple Pie\".to_owned(),\n    ///     })\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#,\n    /// );\n    /// ```\n    /// ActiveModel\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     Insert::one(cake::ActiveModel {\n    ///         id: NotSet,\n    ///         name: Set(\"Apple Pie\".to_owned()),\n    ///     })\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"name\") VALUES ('Apple Pie')\"#,\n    /// );\n    /// ```\n    pub fn one<M>(m: M) -> Self\n    where\n        M: IntoActiveModel<A>,\n    {\n        let mut query = InsertStatement::new();\n        query\n            .into_table(A::Entity::default().table_ref())\n            .or_default_values();\n\n        let mut am: A = m.into_active_model();\n        let primary_key =\n            if !<<A::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::auto_increment() {\n                am.get_primary_key_value()\n            } else {\n                None\n            };\n        let mut columns = Vec::new();\n        let mut values = Vec::new();\n\n        for col in <A::Entity as EntityTrait>::Column::iter() {\n            let av = am.take(col);\n\n            match av {\n                ActiveValue::Set(value) | ActiveValue::Unchanged(value) => {\n                    columns.push(col);\n                    values.push(col.save_as(Expr::val(value)));\n                }\n                ActiveValue::NotSet => {}\n            }\n        }\n\n        query.columns(columns);\n        query.values_panic(values);\n\n        Self {\n            query,\n            primary_key,\n            model: PhantomData,\n        }\n    }\n\n    /// Insert many Model or ActiveModel.\n    /// Alias to [`InsertMany::many`].\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     Insert::many([\n    ///         cake::Model {\n    ///             id: 1,\n    ///             name: \"Apple Pie\".to_owned(),\n    ///         },\n    ///         cake::Model {\n    ///             id: 2,\n    ///             name: \"Orange Scone\".to_owned(),\n    ///         }\n    ///     ])\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie'), (2, 'Orange Scone')\"#,\n    /// );\n    /// ```\n    pub fn many<M, I>(models: I) -> InsertMany<A>\n    where\n        M: IntoActiveModel<A>,\n        I: IntoIterator<Item = M>,\n    {\n        InsertMany::many(models)\n    }\n\n    /// Set ON CONFLICT logic\n    ///\n    /// on conflict do nothing\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, sea_query::OnConflict, tests_cfg::cake};\n    ///\n    /// let orange = cake::ActiveModel {\n    ///     id: ActiveValue::set(2),\n    ///     name: ActiveValue::set(\"Orange\".to_owned()),\n    /// };\n    /// assert_eq!(\n    ///     cake::Entity::insert(orange)\n    ///         .on_conflict(\n    ///             OnConflict::column(cake::Column::Name)\n    ///                 .do_nothing()\n    ///                 .to_owned()\n    ///         )\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO NOTHING\"#,\n    /// );\n    /// ```\n    ///\n    /// on conflict do update (upsert)\n    /// ```\n    /// use sea_orm::{entity::*, query::*, sea_query::OnConflict, tests_cfg::cake, DbBackend};\n    ///\n    /// let orange = cake::ActiveModel {\n    ///     id: ActiveValue::set(2),\n    ///     name: ActiveValue::set(\"Orange\".to_owned()),\n    /// };\n    /// let query = cake::Entity::insert(orange)\n    ///     .on_conflict(\n    ///         OnConflict::column(cake::Column::Name)\n    ///             .update_column(cake::Column::Name)\n    ///             .to_owned()\n    ///     );\n    /// assert_eq!(\n    ///     query\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     \"INSERT INTO `cake` (`id`, `name`) VALUES (2, 'Orange') ON DUPLICATE KEY UPDATE `name` = VALUES(`name`)\"\n    /// );\n    /// assert_eq!(\n    ///     query\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO UPDATE SET \"name\" = \"excluded\".\"name\"\"#,\n    /// );\n    /// assert_eq!(\n    ///     query\n    ///         .build(DbBackend::Sqlite)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO UPDATE SET \"name\" = \"excluded\".\"name\"\"#,\n    /// );\n    /// ```\n    pub fn on_conflict(mut self, on_conflict: OnConflict) -> Self {\n        self.query.on_conflict(on_conflict);\n        self\n    }\n\n    /// Set ON CONFLICT do nothing, but with MySQL specific polyfill.\n    pub fn on_conflict_do_nothing_on<I>(mut self, columns: I) -> TryInsert<A>\n    where\n        I: IntoIterator<Item = <A::Entity as EntityTrait>::Column>,\n    {\n        let primary_keys = <A::Entity as EntityTrait>::PrimaryKey::iter();\n        let mut on_conflict = OnConflict::columns(columns);\n        on_conflict.do_nothing_on(primary_keys);\n        self.query.on_conflict(on_conflict);\n        TryInsert::from_one(self)\n    }\n\n    /// Allow insert statement to return without error if nothing's been inserted.\n    #[deprecated(\n        since = \"2.0.0\",\n        note = \"Please use [`TryInsert::one`] or `on_conflict_do_nothing*` methods that return [`TryInsert`], or [`Insert::try_insert`].\"\n    )]\n    pub fn do_nothing(self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        TryInsert::from_one(self)\n    }\n\n    /// Convert self into a `TryInsert`. It is just a wrapper for converting `DbErr::RecordNotInserted` -> `TryInsertResult::Conflicted`.\n    pub fn try_insert(self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        TryInsert::from_one(self)\n    }\n\n    /// Alias to [`Insert::do_nothing`].\n    #[deprecated(\n        since = \"2.0.0\",\n        note = \"Please use [`TryInsert::one`] or `on_conflict_do_nothing*` methods that return [`TryInsert`]\"\n    )]\n    pub fn on_empty_do_nothing(self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        TryInsert::from_one(self)\n    }\n\n    /// Set ON CONFLICT on primary key do nothing, but with MySQL specific polyfill.\n    ///\n    /// ```\n    /// use sea_orm::{entity::*, query::*, sea_query::OnConflict, tests_cfg::cake, DbBackend};\n    ///\n    /// let orange = cake::ActiveModel {\n    ///     id: ActiveValue::set(2),\n    ///     name: ActiveValue::set(\"Orange\".to_owned()),\n    /// };\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::insert(orange.clone())\n    ///         .on_conflict_do_nothing()\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO `cake` (`id`, `name`) VALUES (2, 'Orange') ON DUPLICATE KEY UPDATE `id` = `id`\"#,\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::insert(orange.clone())\n    ///         .on_conflict_do_nothing()\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"id\") DO NOTHING\"#,\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::insert(orange)\n    ///         .on_conflict_do_nothing()\n    ///         .build(DbBackend::Sqlite)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"id\") DO NOTHING\"#,\n    /// );\n    /// ```\n    pub fn on_conflict_do_nothing(mut self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        self.query.on_conflict(on_conflict_primary_key::<A>());\n\n        TryInsert::from_one(self)\n    }\n}\n\nimpl<A> InsertMany<A>\nwhere\n    A: ActiveModelTrait,\n{\n    /// Insert many Model or ActiveModel\n    pub fn many<M, I>(models: I) -> Self\n    where\n        M: IntoActiveModel<A>,\n        I: IntoIterator<Item = M>,\n    {\n        let mut query = InsertStatement::new();\n        query.into_table(A::Entity::default().table_ref());\n\n        let mut columns: Vec<_> = <A::Entity as EntityTrait>::Column::iter()\n            .map(|_| None)\n            .collect();\n        let mut null_value: Vec<Option<Value>> = std::iter::repeat_n(None, columns.len()).collect();\n        let mut all_values: Vec<Vec<SimpleExpr>> = Vec::new();\n        let mut primary_key = None;\n\n        for model in models.into_iter() {\n            let mut am: A = model.into_active_model();\n            primary_key =\n                if !<<A::Entity as EntityTrait>::PrimaryKey as PrimaryKeyTrait>::auto_increment() {\n                    am.get_primary_key_value()\n                } else {\n                    None\n                };\n            let mut values = Vec::with_capacity(columns.len());\n            for (idx, col) in <A::Entity as EntityTrait>::Column::iter().enumerate() {\n                let av = am.take(col);\n                match av {\n                    ActiveValue::Set(value) | ActiveValue::Unchanged(value) => {\n                        columns[idx] = Some(col); // mark the column as used\n                        null_value[idx] = Some(value.as_null()); // store the null value with the correct type\n                        values.push(col.save_as(Expr::val(value))); // same as add() above\n                    }\n                    ActiveValue::NotSet => {\n                        values.push(SimpleExpr::Keyword(Keyword::Null)); // indicate a missing value\n                    }\n                }\n            }\n            all_values.push(values);\n        }\n\n        let empty = all_values.is_empty();\n\n        if !all_values.is_empty() {\n            // filter only used column\n            query.columns(columns.iter().cloned().flatten());\n        }\n\n        for values in all_values {\n            // since we've aligned the column set, this never panics\n            query.values_panic(values.into_iter().enumerate().filter_map(|(i, v)| {\n                if columns[i].is_some() {\n                    // only if the column is used\n                    if !matches!(v, SimpleExpr::Keyword(Keyword::Null)) {\n                        // use the value expression\n                        Some(v)\n                    } else {\n                        // use null as standin, which must be Some\n                        null_value[i].clone().map(SimpleExpr::Value)\n                    }\n                } else {\n                    None\n                }\n            }));\n        }\n\n        Self {\n            query,\n            primary_key,\n            empty,\n            model: PhantomData,\n        }\n    }\n\n    /// Set ON CONFLICT logic\n    pub fn on_conflict(mut self, on_conflict: OnConflict) -> Self {\n        self.query.on_conflict(on_conflict);\n        self\n    }\n\n    /// Set ON CONFLICT do nothing, but with MySQL specific polyfill.\n    /// ```\n    /// use sea_orm::{entity::*, query::*, sea_query::OnConflict, tests_cfg::cake, DbBackend};\n    /// let orange = cake::ActiveModel {\n    ///     id: ActiveValue::set(2),\n    ///     name: ActiveValue::set(\"Orange\".to_owned()),\n    /// };\n    /// assert_eq!(\n    ///     cake::Entity::insert(orange.clone())\n    ///         .on_conflict_do_nothing_on([cake::Column::Name])\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO NOTHING\"#,\n    /// );\n    /// assert_eq!(\n    ///     cake::Entity::insert(orange)\n    ///         .on_conflict_do_nothing_on([cake::Column::Name])\n    ///         .build(DbBackend::MySql)\n    ///         .to_string(),\n    ///     r#\"INSERT INTO `cake` (`id`, `name`) VALUES (2, 'Orange') ON DUPLICATE KEY UPDATE `id` = `id`\"#,\n    /// );\n    /// ```\n    pub fn on_conflict_do_nothing_on<I>(mut self, columns: I) -> TryInsert<A>\n    where\n        I: IntoIterator<Item = <A::Entity as EntityTrait>::Column>,\n    {\n        let primary_keys = <A::Entity as EntityTrait>::PrimaryKey::iter();\n        let mut on_conflict = OnConflict::columns(columns);\n        on_conflict.do_nothing_on(primary_keys);\n        self.query.on_conflict(on_conflict);\n        TryInsert::from_many(self)\n    }\n\n    /// Allow insert statement to return without error if nothing's been inserted.\n    #[deprecated(\n        since = \"2.0.0\",\n        note = \"Please use [`TryInsert::many`] or `on_conflict_do_nothing*` methods that return [`TryInsert`], or [`InsertMany::try_insert`]\"\n    )]\n    pub fn do_nothing(self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        TryInsert::from_many(self)\n    }\n\n    /// Convert self into a `TryInsert`. It is just a wrapper for converting `DbErr::RecordNotInserted` -> `TryInsertResult::Conflicted`.\n    pub fn try_insert(self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        TryInsert::from_many(self)\n    }\n\n    /// Alias to [`InsertMany::do_nothing`].\n    #[deprecated(\n        since = \"2.0.0\",\n        note = \"Empty input is already handled by [`InsertMany::exec`] (no SQL executed). For conflict handling, use [`InsertMany::on_conflict_do_nothing`] or [`InsertMany::on_conflict_do_nothing_on`].\"\n    )]\n    pub fn on_empty_do_nothing(self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        TryInsert::from_many(self)\n    }\n\n    /// Set ON CONFLICT on primary key do nothing, but with MySQL specific polyfill.\n    /// See also [`Insert::on_conflict_do_nothing`].\n    pub fn on_conflict_do_nothing(mut self) -> TryInsert<A>\n    where\n        A: ActiveModelTrait,\n    {\n        self.query.on_conflict(on_conflict_primary_key::<A>());\n\n        TryInsert::from_many(self)\n    }\n\n    /// panic when self is empty\n    pub(crate) fn into_one(self) -> Insert<A> {\n        assert!(!self.empty);\n\n        let Self {\n            query,\n            primary_key,\n            empty: _,\n            model,\n        } = self;\n\n        Insert {\n            query,\n            primary_key,\n            model,\n        }\n    }\n}\n\nimpl<A> QueryTrait for Insert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    type QueryStatement = InsertStatement;\n\n    fn query(&mut self) -> &mut InsertStatement {\n        &mut self.query\n    }\n\n    fn as_query(&self) -> &InsertStatement {\n        &self.query\n    }\n\n    fn into_query(self) -> InsertStatement {\n        self.query\n    }\n}\n\nimpl<A> QueryTrait for InsertMany<A>\nwhere\n    A: ActiveModelTrait,\n{\n    type QueryStatement = InsertStatement;\n\n    fn query(&mut self) -> &mut InsertStatement {\n        &mut self.query\n    }\n\n    fn as_query(&self) -> &InsertStatement {\n        &self.query\n    }\n\n    fn into_query(self) -> InsertStatement {\n        self.query\n    }\n}\n\nimpl<A> TryInsert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    fn from_one(insert: Insert<A>) -> Self {\n        Self {\n            insert_struct: insert,\n            empty: false,\n        }\n    }\n\n    fn from_many(insert: InsertMany<A>) -> Self {\n        let InsertMany {\n            query,\n            primary_key,\n            empty,\n            model,\n        } = insert;\n\n        Self {\n            insert_struct: Insert {\n                query,\n                primary_key,\n                model,\n            },\n            empty,\n        }\n    }\n\n    /// Try insert one item\n    pub fn one<M>(m: M) -> Self\n    where\n        M: IntoActiveModel<A>,\n    {\n        Self::from_one(Insert::one(m))\n    }\n\n    /// Try insert many items\n    pub fn many<M, I>(models: I) -> Self\n    where\n        M: IntoActiveModel<A>,\n        I: IntoIterator<Item = M>,\n    {\n        Self::from_many(Insert::many(models))\n    }\n\n    /// Set ON CONFLICT logic\n    pub fn on_conflict(mut self, on_conflict: OnConflict) -> Insert<A> {\n        self.insert_struct.query.on_conflict(on_conflict);\n        self.insert_struct\n    }\n\n    /// Set ON CONFLICT on primary key do nothing, but with MySQL specific polyfill.\n    pub fn on_conflict_do_nothing(mut self) -> Self {\n        self.insert_struct\n            .query\n            .on_conflict(on_conflict_primary_key::<A>());\n\n        self\n    }\n\n    /// Set ON CONFLICT do nothing, but with MySQL specific polyfill.\n    pub fn on_conflict_do_nothing_on<I>(mut self, columns: I) -> Self\n    where\n        I: IntoIterator<Item = <A::Entity as EntityTrait>::Column>,\n    {\n        let primary_keys = <A::Entity as EntityTrait>::PrimaryKey::iter();\n        let mut on_conflict = OnConflict::columns(columns);\n        on_conflict.do_nothing_on(primary_keys);\n        self.insert_struct.query.on_conflict(on_conflict);\n        self\n    }\n}\n\nimpl<A> QueryTrait for TryInsert<A>\nwhere\n    A: ActiveModelTrait,\n{\n    type QueryStatement = InsertStatement;\n\n    fn query(&mut self) -> &mut InsertStatement {\n        &mut self.insert_struct.query\n    }\n\n    fn as_query(&self) -> &InsertStatement {\n        &self.insert_struct.query\n    }\n\n    fn into_query(self) -> InsertStatement {\n        self.insert_struct.query\n    }\n}\n\nfn on_conflict_primary_key<A: ActiveModelTrait>() -> OnConflict {\n    let primary_keys = <A::Entity as EntityTrait>::PrimaryKey::iter();\n    let mut on_conflict = OnConflict::columns(primary_keys.clone());\n    on_conflict.do_nothing_on(primary_keys);\n    on_conflict\n}\n\n#[cfg(test)]\nmod tests {\n    use sea_query::OnConflict;\n\n    use crate::tests_cfg::{cake, cake_filling};\n    use crate::{\n        ActiveValue, DbBackend, DbErr, EntityTrait, Insert, IntoActiveModel, NotSet, QueryTrait,\n        Set,\n    };\n\n    #[test]\n    fn insert_1() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::one(cake::ActiveModel {\n                id: ActiveValue::not_set(),\n                name: ActiveValue::set(\"Apple Pie\".to_owned()),\n            })\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"INSERT INTO \"cake\" (\"name\") VALUES ('Apple Pie')\"#,\n        );\n    }\n\n    #[test]\n    fn insert_2() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::one(cake::ActiveModel {\n                id: ActiveValue::set(1),\n                name: ActiveValue::set(\"Apple Pie\".to_owned()),\n            })\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#,\n        );\n    }\n\n    #[test]\n    fn insert_3() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::one(cake::Model {\n                id: 1,\n                name: \"Apple Pie\".to_owned(),\n            })\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie')\"#,\n        );\n    }\n\n    #[test]\n    fn insert_many_1() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::many([\n                cake::Model {\n                    id: 1,\n                    name: \"Apple Pie\".to_owned(),\n                },\n                cake::Model {\n                    id: 2,\n                    name: \"Orange Scone\".to_owned(),\n                }\n            ])\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (1, 'Apple Pie'), (2, 'Orange Scone')\"#,\n        );\n    }\n\n    #[test]\n    fn insert_many_2() {\n        assert_eq!(\n            Insert::<cake::ActiveModel>::many([\n                cake::ActiveModel {\n                    id: NotSet,\n                    name: Set(\"Apple Pie\".to_owned()),\n                },\n                cake::ActiveModel {\n                    id: NotSet,\n                    name: Set(\"Orange Scone\".to_owned()),\n                }\n            ])\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"INSERT INTO \"cake\" (\"name\") VALUES ('Apple Pie'), ('Orange Scone')\"#,\n        );\n    }\n\n    #[test]\n    fn insert_many_3() {\n        let apple = cake_filling::ActiveModel {\n            cake_id: ActiveValue::set(2),\n            filling_id: ActiveValue::NotSet,\n        };\n        let orange = cake_filling::ActiveModel {\n            cake_id: ActiveValue::NotSet,\n            filling_id: ActiveValue::set(3),\n        };\n        assert_eq!(\n            Insert::<cake_filling::ActiveModel>::many([apple, orange])\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"INSERT INTO \"cake_filling\" (\"cake_id\", \"filling_id\") VALUES (2, NULL), (NULL, 3)\"#,\n        );\n    }\n\n    #[test]\n    fn insert_6() {\n        let orange = cake::ActiveModel {\n            id: ActiveValue::set(2),\n            name: ActiveValue::set(\"Orange\".to_owned()),\n        };\n\n        assert_eq!(\n            cake::Entity::insert(orange)\n                .on_conflict(\n                    OnConflict::column(cake::Column::Name)\n                        .do_nothing()\n                        .to_owned()\n                )\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO NOTHING\"#,\n        );\n    }\n\n    #[test]\n    fn insert_7() {\n        let orange = cake::ActiveModel {\n            id: ActiveValue::set(2),\n            name: ActiveValue::set(\"Orange\".to_owned()),\n        };\n\n        assert_eq!(\n            cake::Entity::insert(orange)\n                .on_conflict(\n                    OnConflict::column(cake::Column::Name)\n                        .update_column(cake::Column::Name)\n                        .to_owned()\n                )\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO UPDATE SET \"name\" = \"excluded\".\"name\"\"#,\n        );\n    }\n\n    #[test]\n    fn test_on_conflict_do_nothing_on() {\n        let orange = cake::ActiveModel {\n            id: ActiveValue::set(2),\n            name: ActiveValue::set(\"Orange\".to_owned()),\n        };\n\n        assert_eq!(\n            cake::Entity::insert(orange.clone())\n                .on_conflict_do_nothing_on([cake::Column::Name])\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"INSERT INTO \"cake\" (\"id\", \"name\") VALUES (2, 'Orange') ON CONFLICT (\"name\") DO NOTHING\"#,\n        );\n        assert_eq!(\n            cake::Entity::insert(orange)\n                .on_conflict_do_nothing_on([cake::Column::Name])\n                .build(DbBackend::MySql)\n                .to_string(),\n            r#\"INSERT INTO `cake` (`id`, `name`) VALUES (2, 'Orange') ON DUPLICATE KEY UPDATE `id` = `id`\"#,\n        );\n    }\n\n    #[smol_potat::test]\n    async fn insert_8() -> Result<(), DbErr> {\n        use crate::{DbBackend, MockDatabase, Statement, Transaction};\n\n        mod post {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"posts\")]\n            pub struct Model {\n                #[sea_orm(primary_key, select_as = \"INTEGER\", save_as = \"TEXT\")]\n                pub id: i32,\n                pub title: String,\n                pub text: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        let model = post::Model {\n            id: 1,\n            title: \"News wrap up 2022\".into(),\n            text: \"brbrbrrrbrbrbrr...\".into(),\n        };\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[model.clone()]])\n            .into_connection();\n\n        post::Entity::insert(model.into_active_model())\n            .exec(&db)\n            .await?;\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                r#\"INSERT INTO \"posts\" (\"id\", \"title\", \"text\") VALUES (CAST($1 AS TEXT), $2, $3) RETURNING CAST(\"id\" AS INTEGER)\"#,\n                [\n                    1.into(),\n                    \"News wrap up 2022\".into(),\n                    \"brbrbrrrbrbrbrr...\".into(),\n                ]\n            )])]\n        );\n\n        Ok(())\n    }\n\n    #[smol_potat::test]\n    async fn insert_9() -> Result<(), DbErr> {\n        use crate::{DbBackend, MockDatabase, MockExecResult, Statement, Transaction};\n\n        mod post {\n            use crate as sea_orm;\n            use crate::entity::prelude::*;\n\n            #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n            #[sea_orm(table_name = \"posts\")]\n            pub struct Model {\n                #[sea_orm(\n                    primary_key,\n                    auto_increment = false,\n                    select_as = \"INTEGER\",\n                    save_as = \"TEXT\"\n                )]\n                pub id_primary: i32,\n                #[sea_orm(\n                    primary_key,\n                    auto_increment = false,\n                    select_as = \"INTEGER\",\n                    save_as = \"TEXT\"\n                )]\n                pub id_secondary: i32,\n                pub title: String,\n                pub text: String,\n            }\n\n            #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n            pub enum Relation {}\n\n            impl ActiveModelBehavior for ActiveModel {}\n        }\n\n        let model = post::Model {\n            id_primary: 1,\n            id_secondary: 1001,\n            title: \"News wrap up 2022\".into(),\n            text: \"brbrbrrrbrbrbrr...\".into(),\n        };\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[model.clone()]])\n            .into_connection();\n\n        post::Entity::insert(model.into_active_model())\n            .exec(&db)\n            .await?;\n\n        assert_eq!(\n            db.into_transaction_log(),\n            [Transaction::many([Statement::from_sql_and_values(\n                DbBackend::Postgres,\n                r#\"INSERT INTO \"posts\" (\"id_primary\", \"id_secondary\", \"title\", \"text\") VALUES (CAST($1 AS TEXT), CAST($2 AS TEXT), $3, $4) RETURNING CAST(\"id_primary\" AS INTEGER), CAST(\"id_secondary\" AS INTEGER)\"#,\n                [\n                    1.into(),\n                    1001.into(),\n                    \"News wrap up 2022\".into(),\n                    \"brbrbrrrbrbrbrr...\".into(),\n                ]\n            )])]\n        );\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "src/query/join.rs",
    "content": "use crate::{\n    ColumnTrait, EntityTrait, IdenStatic, Iterable, Linked, QueryFilter, QuerySelect, QueryTrait,\n    Related, Select, SelectA, SelectB, SelectThree, SelectTwo, SelectTwoMany, SelectTwoRequired,\n    TopologyChain, TopologyStar, find_linked_recursive, join_tbl_on_condition,\n};\npub use sea_query::JoinType;\nuse sea_query::{Condition, Expr, IntoCondition, IntoIden, SelectExpr};\n\nimpl<E> Select<E>\nwhere\n    E: EntityTrait,\n{\n    /// Left Join with a Related Entity.\n    pub fn left_join<R>(self, _: R) -> Self\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.join_join(JoinType::LeftJoin, E::to(), E::via())\n    }\n\n    /// Right Join with a Related Entity.\n    pub fn right_join<R>(self, _: R) -> Self\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.join_join(JoinType::RightJoin, E::to(), E::via())\n    }\n\n    /// Inner Join with a Related Entity.\n    pub fn inner_join<R>(self, _: R) -> Self\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.join_join(JoinType::InnerJoin, E::to(), E::via())\n    }\n\n    /// Join with an Entity Related to me.\n    pub fn reverse_join<R>(self, _: R) -> Self\n    where\n        R: EntityTrait + Related<E>,\n    {\n        self.join_rev(JoinType::InnerJoin, R::to())\n    }\n\n    /// Left Join with a Related Entity and select both Entity.\n    pub fn find_also<R>(self, _: E, r: R) -> SelectTwo<E, R>\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.left_join(r).select_also(r)\n    }\n\n    /// Left Join with a Related Entity and select both Entity.\n    pub fn find_also_related<R>(self, r: R) -> SelectTwo<E, R>\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.left_join(r).select_also(r)\n    }\n\n    /// Inner Join with a Related Entity and select both Entity.\n    pub fn find_both_related<R>(self, r: R) -> SelectTwoRequired<E, R>\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.inner_join(r).select_two_required(r)\n    }\n\n    /// Left Join with a Related Entity and select the related Entity as a `Vec`\n    pub fn find_with_related<R>(self, r: R) -> SelectTwoMany<E, R>\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        self.left_join(r).select_with(r)\n    }\n\n    /// Left Join with a Linked Entity and select both Entity.\n    pub fn find_also_linked<L, T>(self, l: L) -> SelectTwo<E, T>\n    where\n        L: Linked<FromEntity = E, ToEntity = T>,\n        T: EntityTrait,\n    {\n        SelectTwo::new_without_prepare(self.left_join_linked(l).into_query())\n    }\n\n    /// Left Join with a Linked Entity and select Entity as a `Vec`.\n    pub fn find_with_linked<L, T>(self, l: L) -> SelectTwoMany<E, T>\n    where\n        L: Linked<FromEntity = E, ToEntity = T>,\n        T: EntityTrait,\n    {\n        SelectTwoMany::new_without_prepare(self.left_join_linked(l).into_query())\n    }\n\n    /// Left Join with a Linked Entity.\n    pub fn left_join_linked<L, T>(mut self, l: L) -> Self\n    where\n        L: Linked<FromEntity = E, ToEntity = T>,\n        T: EntityTrait,\n    {\n        for (i, mut rel) in l.link().into_iter().enumerate() {\n            let r = self.linked_index;\n            self.linked_index += 1;\n            let to_tbl = format!(\"r{r}\").into_iden();\n            let from_tbl = if i > 0 {\n                format!(\"r{}\", i - 1).into_iden()\n            } else {\n                rel.from_tbl.sea_orm_table().clone()\n            };\n            let table_ref = rel.to_tbl;\n\n            let mut condition = Condition::all().add(join_tbl_on_condition(\n                from_tbl.clone(),\n                to_tbl.clone(),\n                rel.from_col,\n                rel.to_col,\n            ));\n            if let Some(f) = rel.on_condition.take() {\n                condition = condition.add(f(from_tbl.clone(), to_tbl.clone()));\n            }\n\n            self.query\n                .join_as(JoinType::LeftJoin, table_ref, to_tbl, condition);\n        }\n        self = self.apply_alias(SelectA.as_str());\n        for col in <T::Column as Iterable>::iter() {\n            let alias = format!(\"{}{}\", SelectB.as_str(), col.as_str());\n            let expr = Expr::col((\n                format!(\"r{}\", self.linked_index - 1).into_iden(),\n                col.into_iden(),\n            ));\n            self.query.expr(SelectExpr {\n                expr: col.select_as(expr),\n                alias: Some(alias.into_iden()),\n                window: None,\n            });\n        }\n        self\n    }\n\n    /// Filter by condition on the related Entity. Uses `EXISTS` SQL statement under the hood.\n    /// ```\n    /// # use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::{cake, fruit, filling}};\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .has_related(fruit::Entity, fruit::Column::Name.eq(\"Mango\"))\n    ///         .build(DbBackend::Sqlite)\n    ///         .to_string(),\n    ///     [\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n    ///         r#\"WHERE EXISTS(SELECT 1 FROM \"fruit\"\"#,\n    ///         r#\"WHERE \"fruit\".\"name\" = 'Mango'\"#,\n    ///         r#\"AND \"cake\".\"id\" = \"fruit\".\"cake_id\")\"#,\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .has_related(filling::Entity, filling::Column::Name.eq(\"Marmalade\"))\n    ///         .build(DbBackend::Sqlite)\n    ///         .to_string(),\n    ///     [\n    ///         r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\"\"#,\n    ///         r#\"WHERE EXISTS(SELECT 1 FROM \"filling\"\"#,\n    ///         r#\"INNER JOIN \"cake_filling\" ON \"cake_filling\".\"filling_id\" = \"filling\".\"id\"\"#,\n    ///         r#\"WHERE \"filling\".\"name\" = 'Marmalade'\"#,\n    ///         r#\"AND \"cake\".\"id\" = \"cake_filling\".\"cake_id\")\"#,\n    ///     ]\n    ///     .join(\" \")\n    /// );\n    /// ```\n    pub fn has_related<R, C>(mut self, _: R, condition: C) -> Self\n    where\n        R: EntityTrait,\n        E: Related<R>,\n        C: IntoCondition,\n    {\n        let mut to = None;\n        let mut condition = condition.into_condition();\n        condition = condition.add(if let Some(via) = E::via() {\n            to = Some(E::to());\n            via\n        } else {\n            E::to()\n        });\n        let mut subquery = R::find()\n            .select_only()\n            .expr(Expr::cust(\"1\"))\n            .filter(condition)\n            .into_query();\n        if let Some(to) = to {\n            // join the junction table\n            subquery.inner_join(to.from_tbl.clone(), to);\n        }\n        self.query.cond_where(Expr::exists(subquery));\n        self\n    }\n\n    #[doc(hidden)]\n    /// Recursive self-join with CTE\n    pub fn find_with_linked_recursive<L>(self, l: L) -> Select<E>\n    where\n        L: Linked<FromEntity = E, ToEntity = E>,\n    {\n        find_linked_recursive(self, l.link())\n    }\n}\n\nimpl<E, F> SelectTwo<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    /// Only used by Entity loader\n    #[doc(hidden)]\n    pub fn select_also_fake<R>(self, _: R) -> SelectThree<E, F, R, TopologyStar>\n    where\n        R: EntityTrait,\n    {\n        // select also but without join\n        SelectThree::new_without_prepare(self.into_query())\n    }\n\n    /// Left Join with a Related Entity and select both Entity.\n    pub fn find_also<G, R>(self, _: G, _: R) -> SelectThree<E, F, R, TopologyStar>\n    where\n        R: EntityTrait,\n        G: EntityTrait + Related<R>,\n    {\n        SelectThree::new(\n            self.join_join(JoinType::LeftJoin, G::to(), G::via())\n                .into_query(),\n        )\n    }\n\n    /// Left Join with an Entity Related to the first Entity\n    pub fn find_also_related<R>(self, _: R) -> SelectThree<E, F, R, TopologyStar>\n    where\n        R: EntityTrait,\n        E: Related<R>,\n    {\n        SelectThree::new(\n            self.join_join(JoinType::LeftJoin, E::to(), E::via())\n                .into_query(),\n        )\n    }\n\n    /// Left Join with an Entity Related to the second Entity\n    pub fn and_also_related<R>(self, _: R) -> SelectThree<E, F, R, TopologyChain>\n    where\n        R: EntityTrait,\n        F: Related<R>,\n    {\n        SelectThree::new(\n            self.join_join(JoinType::LeftJoin, F::to(), F::via())\n                .into_query(),\n        )\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::{\n        cake, cake_compact, cake_filling, cake_filling_price, entity_linked, filling, fruit,\n    };\n    use crate::{\n        ColumnTrait, DbBackend, EntityTrait, ModelTrait, QueryFilter, QuerySelect, QueryTrait,\n        RelationTrait,\n    };\n    use pretty_assertions::assert_eq;\n    use sea_query::{ConditionType, Expr, ExprTrait, IntoCondition, JoinType};\n\n    #[test]\n    fn join_1() {\n        assert_eq!(\n            cake::Entity::find()\n                .left_join(fruit::Entity)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_2() {\n        assert_eq!(\n            cake::Entity::find()\n                .inner_join(fruit::Entity)\n                .filter(fruit::Column::Name.contains(\"cherry\"))\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"INNER JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id`\",\n                \"WHERE `fruit`.`name` LIKE \\'%cherry%\\'\"\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_3() {\n        assert_eq!(\n            fruit::Entity::find()\n                .reverse_join(cake::Entity)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\",\n                \"INNER JOIN `cake` ON `cake`.`id` = `fruit`.`cake_id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_4() {\n        use crate::{Related, Select};\n\n        let find_fruit: Select<fruit::Entity> = cake::Entity::find_related();\n        assert_eq!(\n            find_fruit\n                .filter(cake::Column::Id.eq(11))\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\",\n                \"INNER JOIN `cake` ON `cake`.`id` = `fruit`.`cake_id`\",\n                \"WHERE `cake`.`id` = 11\",\n            ]\n            .join(\" \")\n        );\n\n        let find_fruit: Select<fruit::Entity> = cake::Entity::find_related_rev();\n        assert_eq!(\n            find_fruit\n                .filter(cake::Column::Id.eq(11))\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\",\n                \"INNER JOIN `cake` ON `fruit`.`cake_id` = `cake`.`id`\",\n                \"WHERE `cake`.`id` = 11\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_5() {\n        let cake_model = cake::Model {\n            id: 12,\n            name: \"\".to_owned(),\n        };\n\n        assert_eq!(\n            cake_model\n                .find_related(fruit::Entity)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit`\",\n                \"INNER JOIN `cake` ON `cake`.`id` = `fruit`.`cake_id`\",\n                \"WHERE `cake`.`id` = 12\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_6() {\n        assert_eq!(\n            cake::Entity::find()\n                .left_join(filling::Entity)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id`\",\n                \"LEFT JOIN `filling` ON `cake_filling`.`filling_id` = `filling`.`id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_7() {\n        use crate::{Related, Select};\n\n        let find_filling: Select<filling::Entity> = cake::Entity::find_related();\n        assert_eq!(\n            find_filling.build(DbBackend::MySql).to_string(),\n            [\n                \"SELECT `filling`.`id`, `filling`.`name`, `filling`.`vendor_id` FROM `filling`\",\n                \"INNER JOIN `cake_filling` ON `cake_filling`.`filling_id` = `filling`.`id`\",\n                \"INNER JOIN `cake` ON `cake`.`id` = `cake_filling`.`cake_id`\",\n            ]\n            .join(\" \")\n        );\n\n        let find_filling: Select<filling::Entity> = cake::Entity::find_related_rev();\n        assert_eq!(\n            find_filling.build(DbBackend::MySql).to_string(),\n            [\n                \"SELECT `filling`.`id`, `filling`.`name`, `filling`.`vendor_id` FROM `filling`\",\n                \"INNER JOIN `cake_filling` ON `filling`.`id` = `cake_filling`.`filling_id`\",\n                \"INNER JOIN `cake` ON `cake_filling`.`cake_id` = `cake`.`id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_8() {\n        use crate::{Related, Select};\n\n        let find_cake_filling_price: Select<cake_filling_price::Entity> =\n            cake_filling::Entity::find_related();\n        assert_eq!(\n            find_cake_filling_price.build(DbBackend::Postgres).to_string(),\n            [\n                r#\"SELECT \"cake_filling_price\".\"cake_id\", \"cake_filling_price\".\"filling_id\", \"cake_filling_price\".\"price\"\"#,\n                r#\"FROM \"public\".\"cake_filling_price\"\"#,\n                r#\"INNER JOIN \"cake_filling\" ON\"#,\n                r#\"\"cake_filling\".\"cake_id\" = \"cake_filling_price\".\"cake_id\" AND\"#,\n                r#\"\"cake_filling\".\"filling_id\" = \"cake_filling_price\".\"filling_id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_9() {\n        use crate::{Related, Select};\n\n        let find_cake_filling: Select<cake_filling::Entity> =\n            cake_filling_price::Entity::find_related();\n        assert_eq!(\n            find_cake_filling.build(DbBackend::Postgres).to_string(),\n            [\n                r#\"SELECT \"cake_filling\".\"cake_id\", \"cake_filling\".\"filling_id\"\"#,\n                r#\"FROM \"cake_filling\"\"#,\n                r#\"INNER JOIN \"public\".\"cake_filling_price\" ON\"#,\n                r#\"\"cake_filling_price\".\"cake_id\" = \"cake_filling\".\"cake_id\" AND\"#,\n                r#\"\"cake_filling_price\".\"filling_id\" = \"cake_filling\".\"filling_id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_10() {\n        let cake_model = cake::Model {\n            id: 12,\n            name: \"\".to_owned(),\n        };\n\n        assert_eq!(\n            cake_model\n                .find_linked(entity_linked::CakeToFilling)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                r\"SELECT `filling`.`id`, `filling`.`name`, `filling`.`vendor_id`\",\n                r\"FROM `filling`\",\n                r\"INNER JOIN `cake_filling` AS `r0` ON `r0`.`filling_id` = `filling`.`id`\",\n                r\"INNER JOIN `cake` AS `r1` ON `r1`.`id` = `r0`.`cake_id`\",\n                r\"WHERE `r1`.`id` = 12\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_11() {\n        let cake_model = cake::Model {\n            id: 18,\n            name: \"\".to_owned(),\n        };\n\n        assert_eq!(\n            cake_model\n                .find_linked(entity_linked::CakeToFillingVendor)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                r\"SELECT `vendor`.`id`, `vendor`.`name`\",\n                r\"FROM `vendor`\",\n                r\"INNER JOIN `filling` AS `r0` ON `r0`.`vendor_id` = `vendor`.`id`\",\n                r\"INNER JOIN `cake_filling` AS `r1` ON `r1`.`filling_id` = `r0`.`id`\",\n                r\"INNER JOIN `cake` AS `r2` ON `r2`.`id` = `r1`.`cake_id`\",\n                r\"WHERE `r2`.`id` = 18\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_12() {\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CakeToFilling)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                r\"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                r\"`r1`.`id` AS `B_id`, `r1`.`name` AS `B_name`, `r1`.`vendor_id` AS `B_vendor_id`\",\n                r\"FROM `cake`\",\n                r\"LEFT JOIN `cake_filling` AS `r0` ON `cake`.`id` = `r0`.`cake_id`\",\n                r\"LEFT JOIN `filling` AS `r1` ON `r0`.`filling_id` = `r1`.`id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_13() {\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CakeToFillingVendor)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                r\"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                r\"`r2`.`id` AS `B_id`, `r2`.`name` AS `B_name`\",\n                r\"FROM `cake`\",\n                r\"LEFT JOIN `cake_filling` AS `r0` ON `cake`.`id` = `r0`.`cake_id`\",\n                r\"LEFT JOIN `filling` AS `r1` ON `r0`.`filling_id` = `r1`.`id`\",\n                r\"LEFT JOIN `vendor` AS `r2` ON `r1`.`vendor_id` = `r2`.`id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_14() {\n        assert_eq!(\n            cake_compact::Entity::find()\n                .join(JoinType::LeftJoin, cake_compact::Relation::TropicalFruit.def())\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` AND `fruit`.`name` LIKE '%tropical%'\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_15() {\n        let cake_model = cake::Model {\n            id: 18,\n            name: \"\".to_owned(),\n        };\n\n        assert_eq!(\n            cake_model\n                .find_linked(entity_linked::CheeseCakeToFillingVendor)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                r\"SELECT `vendor`.`id`, `vendor`.`name`\",\n                r\"FROM `vendor`\",\n                r\"INNER JOIN `filling` AS `r0` ON `r0`.`vendor_id` = `vendor`.`id`\",\n                r\"INNER JOIN `cake_filling` AS `r1` ON `r1`.`filling_id` = `r0`.`id`\",\n                r\"INNER JOIN `cake` AS `r2` ON `r2`.`id` = `r1`.`cake_id` AND `r2`.`name` LIKE '%cheese%'\",\n                r\"WHERE `r2`.`id` = 18\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_16() {\n        // removed wrong test case\n    }\n\n    #[test]\n    fn join_17() {\n        assert_eq!(\n            cake::Entity::find()\n                .find_also_linked(entity_linked::CheeseCakeToFillingVendor)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                r\"SELECT `cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`,\",\n                r\"`r2`.`id` AS `B_id`, `r2`.`name` AS `B_name`\",\n                r\"FROM `cake`\",\n                r\"LEFT JOIN `cake_filling` AS `r0` ON `cake`.`id` = `r0`.`cake_id` AND `cake`.`name` LIKE '%cheese%'\",\n                r\"LEFT JOIN `filling` AS `r1` ON `r0`.`filling_id` = `r1`.`id`\",\n                r\"LEFT JOIN `vendor` AS `r2` ON `r1`.`vendor_id` = `r2`.`id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_18() {\n        // removed wrong test case\n    }\n\n    #[test]\n    fn join_19() {\n        assert_eq!(\n            cake_compact::Entity::find()\n                .join(JoinType::LeftJoin, cake_compact::Relation::TropicalFruit.def())\n                .join(\n                    JoinType::LeftJoin,\n                    cake_filling::Relation::Cake\n                        .def()\n                        .rev()\n                        .on_condition(|_left, right| {\n                            Expr::col((right, cake_filling::Column::CakeId))\n                                .gt(10)\n                                .into_condition()\n                        })\n                )\n                .join(\n                    JoinType::LeftJoin,\n                    cake_filling::Relation::Filling\n                        .def()\n                        .on_condition(|_left, right| {\n                            Expr::col((right, filling::Column::Name))\n                                .like(\"%lemon%\")\n                                .into_condition()\n                        })\n                )\n                .join(JoinType::LeftJoin, filling::Relation::Vendor.def())\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` AND `fruit`.`name` LIKE '%tropical%'\",\n                \"LEFT JOIN `cake_filling` ON `cake`.`id` = `cake_filling`.`cake_id` AND `cake_filling`.`cake_id` > 10\",\n                \"LEFT JOIN `filling` ON `cake_filling`.`filling_id` = `filling`.`id` AND `filling`.`name` LIKE '%lemon%'\",\n                \"LEFT JOIN `vendor` ON `filling`.`vendor_id` = `vendor`.`id`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_20() {\n        assert_eq!(\n            cake::Entity::find()\n                .column_as(\n                    Expr::col((\"fruit_alias\", fruit::Column::Name)),\n                    \"fruit_name\"\n                )\n                .join_as(\n                    JoinType::LeftJoin,\n                    cake::Relation::Fruit\n                        .def()\n                        .on_condition(|_left, right| {\n                            Expr::col((right, fruit::Column::Name))\n                                .like(\"%tropical%\")\n                                .into_condition()\n                        }),\n                    \"fruit_alias\"\n                )\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name`, `fruit_alias`.`name` AS `fruit_name` FROM `cake`\",\n                \"LEFT JOIN `fruit` AS `fruit_alias` ON `cake`.`id` = `fruit_alias`.`cake_id` AND `fruit_alias`.`name` LIKE '%tropical%'\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_21() {\n        assert_eq!(\n            cake_compact::Entity::find()\n                .column_as(\n                    Expr::col((\"cake_filling_alias\", cake_filling::Column::CakeId)),\n                    \"cake_filling_cake_id\"\n                )\n                .join(JoinType::LeftJoin, cake_compact::Relation::TropicalFruit.def())\n                .join_as_rev(\n                    JoinType::LeftJoin,\n                    cake_filling::Relation::Cake\n                        .def()\n                        .on_condition(|left, _right| {\n                            Expr::col((left, cake_filling::Column::CakeId))\n                                .gt(10)\n                                .into_condition()\n                        }),\n                    \"cake_filling_alias\"\n                )\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name`, `cake_filling_alias`.`cake_id` AS `cake_filling_cake_id` FROM `cake`\",\n                \"LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` AND `fruit`.`name` LIKE '%tropical%'\",\n                \"LEFT JOIN `cake_filling` AS `cake_filling_alias` ON `cake_filling_alias`.`cake_id` = `cake`.`id` AND `cake_filling_alias`.`cake_id` > 10\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_22() {\n        assert_eq!(\n            cake_compact::Entity::find()\n                .column_as(\n                    Expr::col((\"cake_filling_alias\", cake_filling::Column::CakeId)),\n                    \"cake_filling_cake_id\"\n                )\n                .join(JoinType::LeftJoin, cake_compact::Relation::OrTropicalFruit.def())\n                .join_as_rev(\n                    JoinType::LeftJoin,\n                    cake_filling::Relation::Cake\n                        .def()\n                        .condition_type(ConditionType::Any)\n                        .on_condition(|left, _right| {\n                            Expr::col((left, cake_filling::Column::CakeId))\n                                .gt(10)\n                                .into_condition()\n                        }),\n                    \"cake_filling_alias\"\n                )\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name`, `cake_filling_alias`.`cake_id` AS `cake_filling_cake_id` FROM `cake`\",\n                \"LEFT JOIN `fruit` ON `cake`.`id` = `fruit`.`cake_id` OR `fruit`.`name` LIKE '%tropical%'\",\n                \"LEFT JOIN `cake_filling` AS `cake_filling_alias` ON `cake_filling_alias`.`cake_id` = `cake`.`id` OR `cake_filling_alias`.`cake_id` > 10\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_23() {\n        let cake_model = cake::Model {\n            id: 18,\n            name: \"\".to_owned(),\n        };\n\n        assert_eq!(\n            cake_model\n                .find_linked(entity_linked::CakeToCakeViaFilling)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"INNER JOIN `cake_filling` AS `r0` ON `r0`.`cake_id` = `cake`.`id`\",\n                \"INNER JOIN `filling` AS `r1` ON `r1`.`id` = `r0`.`filling_id`\",\n                \"INNER JOIN `cake_filling` AS `r2` ON `r2`.`filling_id` = `r1`.`id`\",\n                \"INNER JOIN `cake` AS `r3` ON `r3`.`id` = `r2`.`cake_id`\",\n                \"WHERE `r3`.`id` = 18\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_24() {\n        let cake_model = cake::Model {\n            id: 12,\n            name: \"\".to_owned(),\n        };\n\n        assert_eq!(\n            cake_model\n                .find_linked_recursive(entity_linked::CakeToCakeViaFilling)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"WITH `cte` AS (SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"INNER JOIN `cake_filling` AS `r0` ON `r0`.`cake_id` = `cake`.`id`\",\n                \"INNER JOIN `filling` AS `r1` ON `r1`.`id` = `r0`.`filling_id`\",\n                \"INNER JOIN `cake_filling` AS `r2` ON `r2`.`filling_id` = `r1`.`id`\",\n                \"INNER JOIN `cake` AS `r3` ON `r3`.`id` = `r2`.`cake_id`\",\n                \"WHERE `r3`.`id` = 12\",\n                \"UNION ALL (SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"INNER JOIN `cake_filling` AS `r0` ON `r0`.`cake_id` = `cake`.`id`\",\n                \"INNER JOIN `filling` AS `r1` ON `r1`.`id` = `r0`.`filling_id`\",\n                \"INNER JOIN `cake_filling` AS `r2` ON `r2`.`filling_id` = `r1`.`id`\",\n                \"INNER JOIN `cte` AS `r3` ON `r3`.`id` = `r2`.`cake_id`))\",\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cte` AS `cake`\",\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn join_25() {\n        assert_eq!(\n            cake::Entity::find()\n                .find_with_linked_recursive(entity_linked::CakeToCakeViaFilling)\n                .build(DbBackend::MySql)\n                .to_string(),\n            [\n                \"WITH `cte` AS (SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"UNION ALL (SELECT `cake`.`id`, `cake`.`name` FROM `cake`\",\n                \"INNER JOIN `cake_filling` AS `r0` ON `r0`.`cake_id` = `cake`.`id`\",\n                \"INNER JOIN `filling` AS `r1` ON `r1`.`id` = `r0`.`filling_id`\",\n                \"INNER JOIN `cake_filling` AS `r2` ON `r2`.`filling_id` = `r1`.`id`\",\n                \"INNER JOIN `cte` AS `r3` ON `r3`.`id` = `r2`.`cake_id`))\",\n                \"SELECT `cake`.`id`, `cake`.`name` FROM `cte` AS `cake`\",\n            ]\n            .join(\" \")\n        );\n    }\n}\n"
  },
  {
    "path": "src/query/json.rs",
    "content": "use crate::{FromQueryResult, QueryResult, error::*};\nuse serde_json::Map;\npub use serde_json::Value as JsonValue;\n\nimpl FromQueryResult for JsonValue {\n    #[allow(unused_variables, unused_mut)]\n    fn from_query_result(res: &QueryResult, pre: &str) -> Result<Self, DbErr> {\n        let mut map = Map::new();\n        #[allow(unused_macros)]\n        macro_rules! try_get_type {\n            ( $type: ty, $col: ident ) => {\n                if let Ok(v) = res.try_get::<Option<$type>>(pre, &$col) {\n                    map.insert($col.to_owned(), json!(v));\n                    continue;\n                }\n            };\n        }\n        match &res.row {\n            #[cfg(feature = \"sqlx-mysql\")]\n            crate::QueryResultRow::SqlxMySql(row) => {\n                use serde_json::json;\n                use sqlx::{Column, MySql, Row, Type};\n                for column in row.columns() {\n                    let col = if !column.name().starts_with(pre) {\n                        continue;\n                    } else {\n                        column.name().replacen(pre, \"\", 1)\n                    };\n                    let col_type = column.type_info();\n                    macro_rules! match_mysql_type {\n                        ( $type: ty ) => {\n                            if <$type as Type<MySql>>::type_info().eq(col_type) {\n                                try_get_type!($type, col)\n                            }\n                        };\n                    }\n                    macro_rules! match_mysql_compatible_type {\n                        ( $type: ty ) => {\n                            if <$type as Type<MySql>>::compatible(col_type) {\n                                try_get_type!($type, col)\n                            }\n                        };\n                    }\n                    match_mysql_type!(bool);\n                    match_mysql_type!(i8);\n                    match_mysql_type!(i16);\n                    match_mysql_type!(i32);\n                    match_mysql_type!(i64);\n                    match_mysql_type!(u8);\n                    match_mysql_type!(u16);\n                    match_mysql_type!(u32);\n                    match_mysql_type!(u64);\n                    match_mysql_type!(f32);\n                    match_mysql_type!(f64);\n                    match_mysql_type!(String);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_mysql_type!(chrono::NaiveDate);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_mysql_type!(chrono::NaiveTime);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_mysql_type!(chrono::NaiveDateTime);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_mysql_type!(chrono::DateTime<chrono::Utc>);\n                    #[cfg(feature = \"with-time\")]\n                    match_mysql_type!(time::Date);\n                    #[cfg(feature = \"with-time\")]\n                    match_mysql_type!(time::Time);\n                    #[cfg(feature = \"with-time\")]\n                    match_mysql_type!(time::PrimitiveDateTime);\n                    #[cfg(feature = \"with-time\")]\n                    match_mysql_type!(time::OffsetDateTime);\n                    #[cfg(feature = \"with-rust_decimal\")]\n                    match_mysql_type!(rust_decimal::Decimal);\n                    match_mysql_compatible_type!(String);\n                    #[cfg(feature = \"with-json\")]\n                    try_get_type!(serde_json::Value, col);\n                    #[cfg(feature = \"with-uuid\")]\n                    try_get_type!(uuid::Uuid, col);\n                    try_get_type!(Vec<u8>, col);\n                }\n                Ok(JsonValue::Object(map))\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            crate::QueryResultRow::SqlxPostgres(row) => {\n                use serde_json::json;\n                use sqlx::{Column, Postgres, Row, Type, postgres::types::Oid};\n\n                for column in row.columns() {\n                    let col = if !column.name().starts_with(pre) {\n                        continue;\n                    } else {\n                        column.name().replacen(pre, \"\", 1)\n                    };\n                    let col_type = column.type_info();\n\n                    macro_rules! match_postgres_type {\n                        ( $type: ty ) => {\n                            match col_type.kind() {\n                                #[cfg(feature = \"postgres-array\")]\n                                sqlx::postgres::PgTypeKind::Array(_) => {\n                                    if <Vec<$type> as Type<Postgres>>::type_info().eq(col_type) {\n                                        try_get_type!(Vec<$type>, col);\n                                    }\n                                }\n                                _ => {\n                                    if <$type as Type<Postgres>>::type_info().eq(col_type) {\n                                        try_get_type!($type, col);\n                                    }\n                                }\n                            }\n                        };\n                    }\n\n                    match_postgres_type!(bool);\n                    match_postgres_type!(i8);\n                    match_postgres_type!(i16);\n                    match_postgres_type!(i32);\n                    match_postgres_type!(i64);\n                    // match_postgres_type!(u8); // unsupported by SQLx Postgres\n                    // match_postgres_type!(u16); // unsupported by SQLx Postgres\n                    // Since 0.6.0, SQLx has dropped direct mapping from PostgreSQL's OID to Rust's `u32`;\n                    // Instead, `u32` was wrapped by a `sqlx::Oid`.\n                    if <Oid as Type<Postgres>>::type_info().eq(col_type) {\n                        try_get_type!(u32, col)\n                    }\n                    // match_postgres_type!(u64); // unsupported by SQLx Postgres\n                    match_postgres_type!(f32);\n                    match_postgres_type!(f64);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_postgres_type!(chrono::NaiveDate);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_postgres_type!(chrono::NaiveTime);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_postgres_type!(chrono::NaiveDateTime);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_postgres_type!(chrono::DateTime<chrono::FixedOffset>);\n                    #[cfg(feature = \"with-time\")]\n                    match_postgres_type!(time::Date);\n                    #[cfg(feature = \"with-time\")]\n                    match_postgres_type!(time::Time);\n                    #[cfg(feature = \"with-time\")]\n                    match_postgres_type!(time::PrimitiveDateTime);\n                    #[cfg(feature = \"with-time\")]\n                    match_postgres_type!(time::OffsetDateTime);\n                    #[cfg(feature = \"with-rust_decimal\")]\n                    match_postgres_type!(rust_decimal::Decimal);\n                    #[cfg(feature = \"with-json\")]\n                    try_get_type!(serde_json::Value, col);\n                    #[cfg(all(feature = \"with-json\", feature = \"postgres-array\"))]\n                    try_get_type!(Vec<serde_json::Value>, col);\n                    try_get_type!(String, col);\n                    #[cfg(feature = \"postgres-array\")]\n                    try_get_type!(Vec<String>, col);\n                    #[cfg(feature = \"postgres-vector\")]\n                    try_get_type!(pgvector::Vector, col);\n                    #[cfg(feature = \"with-uuid\")]\n                    try_get_type!(uuid::Uuid, col);\n                    #[cfg(all(feature = \"with-uuid\", feature = \"postgres-array\"))]\n                    try_get_type!(Vec<uuid::Uuid>, col);\n                    #[cfg(feature = \"with-ipnetwork\")]\n                    try_get_type!(ipnetwork::IpNetwork, col);\n                    #[cfg(all(feature = \"with-ipnetwork\", feature = \"postgres-array\"))]\n                    try_get_type!(Vec<ipnetwork::IpNetwork>, col);\n                    try_get_type!(Vec<u8>, col);\n                }\n                Ok(JsonValue::Object(map))\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            crate::QueryResultRow::SqlxSqlite(row) => {\n                use serde_json::json;\n                use sqlx::{Column, Row, Sqlite, Type};\n                for column in row.columns() {\n                    let col = if !column.name().starts_with(pre) {\n                        continue;\n                    } else {\n                        column.name().replacen(pre, \"\", 1)\n                    };\n                    let col_type = column.type_info();\n                    macro_rules! match_sqlite_type {\n                        ( $type: ty ) => {\n                            if <$type as Type<Sqlite>>::type_info().eq(col_type) {\n                                try_get_type!($type, col)\n                            }\n                        };\n                    }\n                    match_sqlite_type!(bool);\n                    match_sqlite_type!(i8);\n                    match_sqlite_type!(i16);\n                    match_sqlite_type!(i32);\n                    match_sqlite_type!(i64);\n                    match_sqlite_type!(u8);\n                    match_sqlite_type!(u16);\n                    match_sqlite_type!(u32);\n                    // match_sqlite_type!(u64); // unsupported by SQLx Sqlite\n                    match_sqlite_type!(f32);\n                    match_sqlite_type!(f64);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_sqlite_type!(chrono::NaiveDate);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_sqlite_type!(chrono::NaiveTime);\n                    #[cfg(feature = \"with-chrono\")]\n                    match_sqlite_type!(chrono::NaiveDateTime);\n                    #[cfg(feature = \"with-time\")]\n                    match_sqlite_type!(time::Date);\n                    #[cfg(feature = \"with-time\")]\n                    match_sqlite_type!(time::Time);\n                    #[cfg(feature = \"with-time\")]\n                    match_sqlite_type!(time::PrimitiveDateTime);\n                    #[cfg(feature = \"with-time\")]\n                    match_sqlite_type!(time::OffsetDateTime);\n                    try_get_type!(String, col);\n                    #[cfg(feature = \"with-uuid\")]\n                    try_get_type!(uuid::Uuid, col);\n                    try_get_type!(Vec<u8>, col);\n                }\n                Ok(JsonValue::Object(map))\n            }\n            #[cfg(feature = \"rusqlite\")]\n            crate::QueryResultRow::Rusqlite(row) => {\n                use crate::driver::rusqlite::RusqliteOwnedValue;\n                use serde_json::json;\n\n                for (i, column) in row.columns.iter().enumerate() {\n                    let column = if !column.starts_with(pre) {\n                        continue;\n                    } else {\n                        column.replacen(pre, \"\", 1)\n                    };\n                    map.insert(\n                        column,\n                        match &row.values[i] {\n                            RusqliteOwnedValue::Integer(v) => json!(v),\n                            RusqliteOwnedValue::Real(v) => json!(v),\n                            RusqliteOwnedValue::Text(v) => json!(v),\n                            RusqliteOwnedValue::Blob(v) => json!(v),\n                            RusqliteOwnedValue::Null => json!(null),\n                        },\n                    );\n                }\n                Ok(JsonValue::Object(map))\n            }\n            #[cfg(feature = \"mock\")]\n            crate::QueryResultRow::Mock(row) => {\n                for (column, value) in row.clone().into_column_value_tuples() {\n                    let col = if !column.starts_with(pre) {\n                        continue;\n                    } else {\n                        column.replacen(pre, \"\", 1)\n                    };\n                    map.insert(col, sea_query::sea_value_to_json_value(&value));\n                }\n                Ok(JsonValue::Object(map))\n            }\n            #[cfg(feature = \"proxy\")]\n            crate::QueryResultRow::Proxy(row) => {\n                for (column, value) in row.clone().into_column_value_tuples() {\n                    let col = if !column.starts_with(pre) {\n                        continue;\n                    } else {\n                        column.replacen(pre, \"\", 1)\n                    };\n                    map.insert(col, sea_query::sea_value_to_json_value(&value));\n                }\n                Ok(JsonValue::Object(map))\n            }\n            #[allow(unreachable_patterns)]\n            _ => unreachable!(),\n        }\n    }\n}\n\n#[cfg(test)]\n#[cfg(feature = \"mock\")]\nmod tests {\n    use crate::tests_cfg::cake;\n    use crate::{DbBackend, DbErr, MockDatabase, entity::*};\n    use sea_query::Value;\n\n    #[smol_potat::test]\n    async fn to_json_1() -> Result<(), DbErr> {\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[maplit::btreemap! {\n                \"id\" => Into::<Value>::into(128), \"name\" => Into::<Value>::into(\"apple\")\n            }]])\n            .into_connection();\n\n        assert_eq!(\n            cake::Entity::find().into_json().one(&db).await.unwrap(),\n            Some(serde_json::json!({\n                \"id\": 128,\n                \"name\": \"apple\"\n            }))\n        );\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "src/query/loader.rs",
    "content": "use super::get_key_from_model;\nuse crate::{\n    ColumnTrait, Condition, ConnectionTrait, DbBackend, DbErr, EntityTrait, Identity, JoinType,\n    ModelTrait, QueryFilter, QuerySelect, Related, RelatedSelfVia, RelationDef, RelationTrait,\n    RelationType, Select, dynamic, query::column_tuple_in_condition, query_err,\n};\nuse sea_query::{ColumnRef, DynIden, Expr, ExprTrait, IntoColumnRef, TableRef, ValueTuple};\nuse std::{collections::HashMap, str::FromStr};\n\n// TODO: Replace DynIden::inner with a better API that without clone\n\n/// Entity, or a Select<Entity>; to be used as parameters in [`LoaderTrait`]\npub trait EntityOrSelect<E: EntityTrait>: Send {\n    /// If self is Entity, use Entity::find()\n    fn select(self) -> Select<E>;\n}\n\ntype LoaderEntity<T> = <<T as LoaderTrait>::Model as ModelTrait>::Entity;\ntype LoaderModel<T> = <<<T as LoaderTrait>::Model as ModelTrait>::Entity as EntityTrait>::Model;\ntype LoaderRelation<T> =\n    <<<T as LoaderTrait>::Model as ModelTrait>::Entity as EntityTrait>::Relation;\n\n/// This trait implements the Data Loader API\n#[async_trait::async_trait]\npub trait LoaderTrait {\n    /// Source model\n    type Model: ModelTrait;\n\n    /// Used to eager load self_ref relations\n    async fn load_self<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Option<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderModel<Self>: Send + Sync,\n        LoaderRelation<Self>: Send,\n        S: EntityOrSelect<LoaderEntity<Self>>;\n\n    /// Used to eager load self_ref relations in reverse, output is `Vec<Model>` instead of\n    /// `Option<Model>` of `load_self`.\n    async fn load_self_many<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderModel<Self>: Send + Sync,\n        LoaderRelation<Self>: Send,\n        S: EntityOrSelect<LoaderEntity<Self>>;\n\n    /// Used to eager load self_ref + via relations\n    async fn load_self_via<V, C>(\n        &self,\n        via: V,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderModel<Self>: Send + Sync,\n        LoaderEntity<Self>: RelatedSelfVia<V>;\n\n    /// Used to eager load self_ref + via relations, but in reverse\n    async fn load_self_via_rev<V, C>(\n        &self,\n        via: V,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderModel<Self>: Send + Sync,\n        LoaderEntity<Self>: RelatedSelfVia<V>;\n\n    /// Used to eager load has_one relations\n    async fn load_one<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Option<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n\n    /// Used to eager load has_many relations\n    async fn load_many<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n\n    /// Used to eager load many_to_many relations. In SeaORM 2.0 `load_many` already support M-N\n    /// relations so this method is not needed, only kept as legacy.\n    async fn load_many_to_many<R, S, V, C>(\n        &self,\n        stmt: S,\n        via: V,\n        db: &C,\n    ) -> Result<Vec<Vec<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        V: EntityTrait,\n        V::Model: Send + Sync,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n}\n\ntype LoaderExEntity<T> = <<T as LoaderTraitEx>::Model as ModelTrait>::Entity;\ntype LoaderExModel<T> = <<<T as LoaderTraitEx>::Model as ModelTrait>::Entity as EntityTrait>::Model;\ntype LoaderExModelEx<T> =\n    <<<T as LoaderTraitEx>::Model as ModelTrait>::Entity as EntityTrait>::ModelEx;\ntype LoaderExRelation<T> =\n    <<<T as LoaderTraitEx>::Model as ModelTrait>::Entity as EntityTrait>::Relation;\n\n#[doc(hidden)]\n#[async_trait::async_trait]\npub trait LoaderTraitEx {\n    type Model: ModelTrait;\n\n    async fn load_self_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderExRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Option<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderExModel<Self>: Send + Sync,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExRelation<Self>: Send,\n        S: EntityOrSelect<LoaderExEntity<Self>>;\n\n    async fn load_self_many_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderExRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderExModel<Self>: Send + Sync,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExRelation<Self>: Send,\n        S: EntityOrSelect<LoaderExEntity<Self>>;\n\n    async fn load_self_via_ex<V, C>(\n        &self,\n        via: V,\n        is_reverse: bool,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderExModel<Self>: Send + Sync,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExEntity<Self>: RelatedSelfVia<V>;\n\n    async fn load_one_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Option<R::ModelEx>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n\n    async fn load_many_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<R::ModelEx>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n}\n\ntype NestedEntity<T> = <<T as NestedLoaderTrait>::Model as ModelTrait>::Entity;\ntype NestedModel<T> =\n    <<<T as NestedLoaderTrait>::Model as ModelTrait>::Entity as EntityTrait>::Model;\ntype NestedModelEx<T> =\n    <<<T as NestedLoaderTrait>::Model as ModelTrait>::Entity as EntityTrait>::ModelEx;\ntype NestedLoaderRelation<T> =\n    <<<T as NestedLoaderTrait>::Model as ModelTrait>::Entity as EntityTrait>::Relation;\n\n#[doc(hidden)]\n#[async_trait::async_trait]\npub trait NestedLoaderTrait {\n    type Model: ModelTrait;\n\n    async fn load_self_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: NestedLoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<Option<NestedModelEx<Self>>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        NestedModel<Self>: Send + Sync,\n        NestedModelEx<Self>: From<NestedModel<Self>>,\n        NestedLoaderRelation<Self>: Send,\n        S: EntityOrSelect<<<Self as NestedLoaderTrait>::Model as ModelTrait>::Entity>;\n\n    async fn load_self_many_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: NestedLoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<Vec<NestedModelEx<Self>>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        NestedModel<Self>: Send + Sync,\n        NestedModelEx<Self>: From<NestedModel<Self>>,\n        NestedLoaderRelation<Self>: Send,\n        S: EntityOrSelect<<<Self as NestedLoaderTrait>::Model as ModelTrait>::Entity>;\n\n    async fn load_self_via_ex<V, C>(\n        &self,\n        via: V,\n        is_reverse: bool,\n        db: &C,\n    ) -> Result<Vec<Vec<Vec<NestedModelEx<Self>>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        NestedModel<Self>: Send + Sync,\n        NestedModelEx<Self>: From<NestedModel<Self>>,\n        NestedEntity<Self>: RelatedSelfVia<V>;\n\n    async fn load_one_ex<R, S, C>(\n        &self,\n        stmt: S,\n        db: &C,\n    ) -> Result<Vec<Vec<Option<R::ModelEx>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n\n    async fn load_many_ex<R, S, C>(\n        &self,\n        stmt: S,\n        db: &C,\n    ) -> Result<Vec<Vec<Vec<R::ModelEx>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>;\n}\n\nimpl<E> EntityOrSelect<E> for E\nwhere\n    E: EntityTrait,\n{\n    fn select(self) -> Select<E> {\n        E::find().order_by_id_asc()\n    }\n}\n\nimpl<E> EntityOrSelect<E> for Select<E>\nwhere\n    E: EntityTrait,\n{\n    fn select(self) -> Select<E> {\n        self\n    }\n}\n\n#[async_trait::async_trait]\nimpl<M> LoaderTrait for Vec<M>\nwhere\n    M: ModelTrait + Sync,\n{\n    type Model = M;\n\n    async fn load_self<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Option<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderModel<Self>: Send + Sync,\n        LoaderRelation<Self>: Send,\n        S: EntityOrSelect<LoaderEntity<Self>>,\n    {\n        LoaderTrait::load_self(&self.as_slice(), stmt, relation_enum, db).await\n    }\n\n    async fn load_self_many<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderModel<Self>: Send + Sync,\n        LoaderRelation<Self>: Send,\n        S: EntityOrSelect<LoaderEntity<Self>>,\n    {\n        LoaderTrait::load_self_many(&self.as_slice(), stmt, relation_enum, db).await\n    }\n\n    async fn load_self_via<V, C>(\n        &self,\n        via: V,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderModel<Self>: Send + Sync,\n        LoaderEntity<Self>: RelatedSelfVia<V>,\n    {\n        LoaderTrait::load_self_via(&self.as_slice(), via, db).await\n    }\n\n    async fn load_self_via_rev<V, C>(\n        &self,\n        via: V,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderModel<Self>: Send + Sync,\n        LoaderEntity<Self>: RelatedSelfVia<V>,\n    {\n        LoaderTrait::load_self_via_rev(&self.as_slice(), via, db).await\n    }\n\n    async fn load_one<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Option<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        LoaderTrait::load_one(&self.as_slice(), stmt, db).await\n    }\n\n    async fn load_many<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        LoaderTrait::load_many(&self.as_slice(), stmt, db).await\n    }\n\n    async fn load_many_to_many<R, S, V, C>(\n        &self,\n        stmt: S,\n        via: V,\n        db: &C,\n    ) -> Result<Vec<Vec<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        V: EntityTrait,\n        V::Model: Send + Sync,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        LoaderTrait::load_many_to_many(&self.as_slice(), stmt, via, db).await\n    }\n}\n\n#[async_trait::async_trait]\nimpl<M> LoaderTrait for &[M]\nwhere\n    M: ModelTrait + Sync,\n{\n    type Model = M;\n\n    async fn load_self<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Option<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderModel<Self>: Send + Sync,\n        LoaderRelation<Self>: Send,\n        S: EntityOrSelect<LoaderEntity<Self>>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref(&rel_def)?;\n        loader_impl_impl(self.iter(), stmt.select(), rel_def, None, db).await\n    }\n\n    async fn load_self_many<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderModel<Self>: Send + Sync,\n        LoaderRelation<Self>: Send,\n        S: EntityOrSelect<LoaderEntity<Self>>,\n    {\n        let mut rel_def = relation_enum.def();\n        if rel_def.from_tbl != rel_def.to_tbl {\n            return Err(query_err(\"Relation must be self referencing\"));\n        }\n        if !rel_def.is_owner {\n            // flip belongs_to\n            rel_def = rel_def.rev();\n        }\n        loader_impl_impl(self.iter(), stmt.select(), rel_def, None, db).await\n    }\n\n    async fn load_self_via<V, C>(&self, _: V, db: &C) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderModel<Self>: Send + Sync,\n        LoaderEntity<Self>: RelatedSelfVia<V>,\n    {\n        let rel_def = <LoaderEntity<Self> as RelatedSelfVia<V>>::to();\n        let rel_via = <LoaderEntity<Self> as RelatedSelfVia<V>>::via();\n        loader_impl_impl(\n            self.iter(),\n            EntityOrSelect::select(LoaderEntity::<Self>::default()),\n            rel_def,\n            Some(rel_via),\n            db,\n        )\n        .await\n    }\n\n    async fn load_self_via_rev<V, C>(\n        &self,\n        _: V,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderModel<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderModel<Self>: Send + Sync,\n        LoaderEntity<Self>: RelatedSelfVia<V>,\n    {\n        let rel_def = <LoaderEntity<Self> as RelatedSelfVia<V>>::via().rev();\n        let rel_via = <LoaderEntity<Self> as RelatedSelfVia<V>>::to().rev();\n        loader_impl_impl(\n            self.iter(),\n            EntityOrSelect::select(LoaderEntity::<Self>::default()),\n            rel_def,\n            Some(rel_via),\n            db,\n        )\n        .await\n    }\n\n    async fn load_one<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Option<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        let rel_def = <<Self::Model as ModelTrait>::Entity as Related<R>>::to();\n        if rel_def.rel_type != RelationType::HasOne {\n            return Err(query_err(\"Relation is HasMany instead of HasOne\"));\n        }\n        loader_impl(self.iter(), stmt.select(), db).await\n    }\n\n    async fn load_many<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        loader_impl(self.iter(), stmt.select(), db).await\n    }\n\n    async fn load_many_to_many<R, S, V, C>(\n        &self,\n        stmt: S,\n        via: V,\n        db: &C,\n    ) -> Result<Vec<Vec<R::Model>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        V: EntityTrait,\n        V::Model: Send + Sync,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        if let Some(via_rel) = <<Self::Model as ModelTrait>::Entity as Related<R>>::via() {\n            let rel_def = <<Self::Model as ModelTrait>::Entity as Related<R>>::to();\n            if rel_def.rel_type != RelationType::HasOne {\n                return Err(query_err(\"Relation to is not HasOne\"));\n            }\n\n            if !cmp_table_ref(&via_rel.to_tbl, &via.table_ref()) {\n                return Err(query_err(format!(\n                    \"The given via Entity is incorrect: expected: {:?}, given: {:?}\",\n                    via_rel.to_tbl,\n                    via.table_ref()\n                )));\n            }\n\n            if self.is_empty() {\n                return Ok(Vec::new());\n            }\n\n            let pkeys = self\n                .iter()\n                .map(|model| get_key_from_model(&via_rel.from_col, model))\n                .collect::<Result<Vec<_>, _>>()?;\n\n            // Map of M::PK -> Vec<R::PK>\n            let mut keymap: HashMap<ValueTuple, Vec<ValueTuple>> = Default::default();\n\n            let keys: Vec<ValueTuple> = {\n                let condition = prepare_condition::<M>(\n                    &via_rel.to_tbl,\n                    &via_rel.from_col,\n                    &via_rel.to_col,\n                    &pkeys,\n                    db.get_database_backend(),\n                )?;\n                let stmt = V::find().filter(condition);\n                let data = stmt.all(db).await?;\n                for model in data {\n                    let pk = get_key_from_model(&via_rel.to_col, &model)?;\n                    let entry = keymap.entry(pk).or_default();\n\n                    let fk = get_key_from_model(&rel_def.from_col, &model)?;\n                    entry.push(fk);\n                }\n\n                keymap.values().flatten().cloned().collect()\n            };\n\n            let condition = prepare_condition::<V::Model>(\n                &rel_def.to_tbl,\n                &rel_def.from_col,\n                &rel_def.to_col,\n                &keys,\n                db.get_database_backend(),\n            )?;\n\n            let stmt = QueryFilter::filter(stmt.select(), condition);\n\n            let models = stmt.all(db).await?;\n\n            // Map of R::PK -> R::Model\n            let data = models.into_iter().try_fold(\n                HashMap::<ValueTuple, <R as EntityTrait>::Model>::new(),\n                |mut acc, model| {\n                    get_key_from_model(&rel_def.to_col, &model).map(|key| {\n                        acc.insert(key, model);\n\n                        acc\n                    })\n                },\n            )?;\n\n            let result: Vec<Vec<R::Model>> = pkeys\n                .into_iter()\n                .map(|pkey| {\n                    let fkeys = keymap.get(&pkey).cloned().unwrap_or_default();\n\n                    let models: Vec<_> = fkeys\n                        .into_iter()\n                        .filter_map(|fkey| data.get(&fkey).cloned())\n                        .collect();\n\n                    models\n                })\n                .collect();\n\n            Ok(result)\n        } else {\n            return Err(query_err(\"Relation is not ManyToMany\"));\n        }\n    }\n}\n\n#[async_trait::async_trait]\nimpl<M> LoaderTraitEx for &[M]\nwhere\n    M: ModelTrait + Sync,\n{\n    type Model = M;\n\n    async fn load_self_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderExRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Option<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderExModel<Self>: Send + Sync,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExRelation<Self>: Send,\n        S: EntityOrSelect<LoaderExEntity<Self>>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref(&rel_def)?;\n        loader_impl_impl(self.iter(), stmt.select(), rel_def, None, db).await\n    }\n\n    async fn load_self_many_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderExRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderExModel<Self>: Send + Sync,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExRelation<Self>: Send,\n        S: EntityOrSelect<LoaderExEntity<Self>>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref_many(&rel_def)?;\n        loader_impl_impl(self.iter(), stmt.select(), rel_def, None, db).await\n    }\n\n    async fn load_self_via_ex<V, C>(\n        &self,\n        _: V,\n        is_reverse: bool,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderExModel<Self>: Send + Sync,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExEntity<Self>: RelatedSelfVia<V>,\n    {\n        let (rel_def, rel_via) = if !is_reverse {\n            (\n                <LoaderExEntity<Self> as RelatedSelfVia<V>>::to(),\n                <LoaderExEntity<Self> as RelatedSelfVia<V>>::via(),\n            )\n        } else {\n            (\n                <LoaderEntity<Self> as RelatedSelfVia<V>>::via().rev(),\n                <LoaderEntity<Self> as RelatedSelfVia<V>>::to().rev(),\n            )\n        };\n        loader_impl_impl(\n            self.iter(),\n            EntityOrSelect::select(LoaderExEntity::<Self>::default()),\n            rel_def,\n            Some(rel_via),\n            db,\n        )\n        .await\n    }\n\n    async fn load_one_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Option<R::ModelEx>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        let rel_def = <<Self::Model as ModelTrait>::Entity as Related<R>>::to();\n        if rel_def.rel_type != RelationType::HasOne {\n            return Err(query_err(\"Relation is HasMany instead of HasOne\"));\n        }\n        loader_impl(self.iter(), stmt.select(), db).await\n    }\n\n    async fn load_many_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<R::ModelEx>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        loader_impl(self.iter(), stmt.select(), db).await\n    }\n}\n\n#[async_trait::async_trait]\nimpl<M> LoaderTraitEx for &[Option<M>]\nwhere\n    M: ModelTrait + Sync,\n{\n    type Model = M;\n\n    async fn load_self_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderExRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Option<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderExModel<Self>: Send + Sync,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExRelation<Self>: Send,\n        S: EntityOrSelect<LoaderExEntity<Self>>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref(&rel_def)?;\n        let items: Vec<Option<_>> = loader_impl_impl(\n            self.iter().filter_map(|o| o.as_ref()),\n            stmt.select(),\n            rel_def,\n            None,\n            db,\n        )\n        .await?;\n        Ok(assemble_options(self, items))\n    }\n\n    async fn load_self_many_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: LoaderExRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        LoaderExModel<Self>: Send + Sync,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExRelation<Self>: Send,\n        S: EntityOrSelect<LoaderExEntity<Self>>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref_many(&rel_def)?;\n        let items: Vec<Vec<_>> = loader_impl_impl(\n            self.iter().filter_map(|o| o.as_ref()),\n            stmt.select(),\n            rel_def,\n            None,\n            db,\n        )\n        .await?;\n        Ok(assemble_options(self, items))\n    }\n\n    async fn load_self_via_ex<V, C>(\n        &self,\n        _: V,\n        is_reverse: bool,\n        db: &C,\n    ) -> Result<Vec<Vec<LoaderExModelEx<Self>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        LoaderExModel<Self>: Send + Sync,\n        LoaderExModelEx<Self>: From<LoaderExModel<Self>>,\n        LoaderExEntity<Self>: RelatedSelfVia<V>,\n    {\n        let (rel_def, rel_via) = if !is_reverse {\n            (\n                <LoaderExEntity<Self> as RelatedSelfVia<V>>::to(),\n                <LoaderExEntity<Self> as RelatedSelfVia<V>>::via(),\n            )\n        } else {\n            (\n                <LoaderExEntity<Self> as RelatedSelfVia<V>>::via().rev(),\n                <LoaderExEntity<Self> as RelatedSelfVia<V>>::to().rev(),\n            )\n        };\n        let items: Vec<Vec<_>> = loader_impl_impl(\n            self.iter().filter_map(|o| o.as_ref()),\n            EntityOrSelect::select(LoaderExEntity::<Self>::default()),\n            rel_def,\n            Some(rel_via),\n            db,\n        )\n        .await?;\n        Ok(assemble_options(self, items))\n    }\n\n    async fn load_one_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Option<R::ModelEx>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        let rel_def = <<Self::Model as ModelTrait>::Entity as Related<R>>::to();\n        if rel_def.rel_type != RelationType::HasOne {\n            return Err(query_err(\"Relation is HasMany instead of HasOne\"));\n        }\n        let items: Vec<Option<R::ModelEx>> =\n            loader_impl(self.iter().filter_map(|o| o.as_ref()), stmt.select(), db).await?;\n        Ok(assemble_options(self, items))\n    }\n\n    async fn load_many_ex<R, S, C>(&self, stmt: S, db: &C) -> Result<Vec<Vec<R::ModelEx>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        let items: Vec<Vec<R::ModelEx>> =\n            loader_impl(self.iter().filter_map(|o| o.as_ref()), stmt.select(), db).await?;\n        Ok(assemble_options(self, items))\n    }\n}\n\n#[async_trait::async_trait]\nimpl<M> NestedLoaderTrait for &[Vec<M>]\nwhere\n    M: ModelTrait + Sync,\n{\n    type Model = M;\n\n    async fn load_self_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: NestedLoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<Option<NestedModelEx<Self>>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        NestedModel<Self>: Send + Sync,\n        NestedModelEx<Self>: From<NestedModel<Self>>,\n        NestedLoaderRelation<Self>: Send,\n        S: EntityOrSelect<<<Self as NestedLoaderTrait>::Model as ModelTrait>::Entity>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref(&rel_def)?;\n        let items: Vec<Option<_>> =\n            loader_impl_impl(self.iter().flatten(), stmt.select(), rel_def, None, db).await?;\n        Ok(assemble_vectors(self, items))\n    }\n\n    async fn load_self_many_ex<S, C>(\n        &self,\n        stmt: S,\n        relation_enum: NestedLoaderRelation<Self>,\n        db: &C,\n    ) -> Result<Vec<Vec<Vec<NestedModelEx<Self>>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        NestedModel<Self>: Send + Sync,\n        NestedModelEx<Self>: From<NestedModel<Self>>,\n        NestedLoaderRelation<Self>: Send,\n        S: EntityOrSelect<<<Self as NestedLoaderTrait>::Model as ModelTrait>::Entity>,\n    {\n        let rel_def = relation_enum.def();\n        check_self_ref_many(&rel_def)?;\n        let items: Vec<Vec<_>> =\n            loader_impl_impl(self.iter().flatten(), stmt.select(), rel_def, None, db).await?;\n        Ok(assemble_vectors(self, items))\n    }\n\n    async fn load_self_via_ex<V, C>(\n        &self,\n        _: V,\n        is_reverse: bool,\n        db: &C,\n    ) -> Result<Vec<Vec<Vec<NestedModelEx<Self>>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        V: EntityTrait,\n        NestedModel<Self>: Send + Sync,\n        NestedModelEx<Self>: From<NestedModel<Self>>,\n        NestedEntity<Self>: RelatedSelfVia<V>,\n    {\n        let (rel_def, rel_via) = if !is_reverse {\n            (\n                <NestedEntity<Self> as RelatedSelfVia<V>>::to(),\n                <NestedEntity<Self> as RelatedSelfVia<V>>::via(),\n            )\n        } else {\n            (\n                <NestedEntity<Self> as RelatedSelfVia<V>>::via().rev(),\n                <NestedEntity<Self> as RelatedSelfVia<V>>::to().rev(),\n            )\n        };\n        let items: Vec<Vec<_>> = loader_impl_impl(\n            self.iter().flatten(),\n            EntityOrSelect::select(NestedEntity::<Self>::default()),\n            rel_def,\n            Some(rel_via),\n            db,\n        )\n        .await?;\n        Ok(assemble_vectors(self, items))\n    }\n\n    async fn load_one_ex<R, S, C>(\n        &self,\n        stmt: S,\n        db: &C,\n    ) -> Result<Vec<Vec<Option<R::ModelEx>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        let rel_def = <<Self::Model as ModelTrait>::Entity as Related<R>>::to();\n        if rel_def.rel_type != RelationType::HasOne {\n            return Err(query_err(\"Relation is HasMany instead of HasOne\"));\n        }\n        let items: Vec<Option<R::ModelEx>> =\n            loader_impl(self.iter().flatten(), stmt.select(), db).await?;\n        Ok(assemble_vectors(self, items))\n    }\n\n    async fn load_many_ex<R, S, C>(\n        &self,\n        stmt: S,\n        db: &C,\n    ) -> Result<Vec<Vec<Vec<R::ModelEx>>>, DbErr>\n    where\n        C: ConnectionTrait,\n        R: EntityTrait,\n        R::Model: Send + Sync,\n        S: EntityOrSelect<R>,\n        R::ModelEx: From<R::Model>,\n        <Self::Model as ModelTrait>::Entity: Related<R>,\n    {\n        let items: Vec<Vec<R::ModelEx>> =\n            loader_impl(self.iter().flatten(), stmt.select(), db).await?;\n        Ok(assemble_vectors(self, items))\n    }\n}\n\nfn assemble_options<I, T: Default>(input: &[Option<I>], items: Vec<T>) -> Vec<T> {\n    let mut items = items.into_iter();\n    let mut output = Vec::new();\n    for input in input.iter() {\n        if input.is_some() {\n            output.push(items.next().unwrap_or_default());\n        } else {\n            output.push(T::default());\n        }\n    }\n    output\n}\n\nfn assemble_vectors<I, T: Default>(input: &[Vec<I>], items: Vec<T>) -> Vec<Vec<T>> {\n    let mut items = items.into_iter();\n\n    let mut output = Vec::new();\n\n    for input in input.iter() {\n        output.push(Vec::new());\n\n        for _inner in input.iter() {\n            output\n                .last_mut()\n                .expect(\"Pushed above\")\n                .push(items.next().unwrap_or_default());\n        }\n    }\n\n    output\n}\n\ntrait Container: Default + Clone {\n    type Item;\n    fn add(&mut self, item: Self::Item);\n}\n\nimpl<T: Clone> Container for Vec<T> {\n    type Item = T;\n    fn add(&mut self, item: Self::Item) {\n        self.push(item);\n    }\n}\n\nimpl<T: Clone> Container for Option<T> {\n    type Item = T;\n    fn add(&mut self, item: Self::Item) {\n        self.replace(item);\n    }\n}\n\nasync fn loader_impl<'a, Model, Iter, R, C, T, Output>(\n    items: Iter,\n    stmt: Select<R>,\n    db: &C,\n) -> Result<Vec<T>, DbErr>\nwhere\n    Model: ModelTrait + Sync + 'a,\n    Iter: Iterator<Item = &'a Model> + 'a,\n    C: ConnectionTrait,\n    R: EntityTrait,\n    R::Model: Send + Sync,\n    Model::Entity: Related<R>,\n    Output: From<R::Model>,\n    T: Container<Item = Output>,\n{\n    loader_impl_impl(\n        items,\n        stmt,\n        <Model::Entity as Related<R>>::to(),\n        <Model::Entity as Related<R>>::via(),\n        db,\n    )\n    .await\n}\n\n// All variants monomorphizes to this implementation, which is a constant number of variants\n// per Entity, permutating on different shapes, e.g. Vec<Model>, Option<ModelEx>\nasync fn loader_impl_impl<'a, Model, Iter, R, C, T, Output>(\n    items: Iter,\n    stmt: Select<R>,\n    rel_def: RelationDef,\n    via_def: Option<RelationDef>,\n    db: &C,\n) -> Result<Vec<T>, DbErr>\nwhere\n    Model: ModelTrait + Sync + 'a,\n    Iter: Iterator<Item = &'a Model> + 'a,\n    C: ConnectionTrait,\n    R: EntityTrait,\n    R::Model: Send + Sync,\n    Output: From<R::Model>,\n    T: Container<Item = Output>,\n{\n    let (keys, hashmap) = if let Some(via_def) = via_def {\n        let keys = items\n            .map(|model| get_key_from_model(&via_def.from_col, model))\n            .collect::<Result<Vec<_>, _>>()?;\n\n        if keys.is_empty() {\n            return Ok(Vec::new());\n        }\n\n        let condition = prepare_condition::<Model>(\n            &via_def.to_tbl,\n            &via_def.from_col,\n            &via_def.to_col,\n            &keys,\n            db.get_database_backend(),\n        )?;\n\n        let stmt = QueryFilter::filter(stmt.join_rev(JoinType::InnerJoin, rel_def), condition);\n\n        // The idea is to do a SelectTwo with join, then extract key via a dynamic model\n        // i.e. select (baker + cake_baker) and extract cake_id from result rows\n        // SELECT \"baker\".\"id\", \"baker\".\"name\", \"baker\".\"contact_details\", \"baker\".\"bakery_id\",\n        //     \"cakes_bakers\".\"cake_id\" <- extra select\n        // FROM \"baker\" <- target\n        // INNER JOIN \"cakes_bakers\" <- junction\n        //     ON \"cakes_bakers\".\"baker_id\" = \"baker\".\"id\" <- relation\n        // WHERE \"cakes_bakers\".\"cake_id\" IN (..)\n\n        let data = stmt\n            .select_also_dyn_model(\n                via_def.to_tbl.sea_orm_table().clone(),\n                dynamic::ModelType {\n                    // we uses the left Model's type but the right Model's field\n                    fields: extract_col_type::<Model>(&via_def.from_col, &via_def.to_col)?,\n                },\n            )\n            .all(db)\n            .await?;\n\n        let mut hashmap: HashMap<ValueTuple, T> =\n            keys.iter()\n                .fold(HashMap::new(), |mut acc, key: &ValueTuple| {\n                    acc.insert(key.clone(), T::default());\n                    acc\n                });\n\n        for (item, key) in data {\n            let key = dyn_model_to_key(key)?;\n\n            let vec = hashmap.get_mut(&key).ok_or_else(|| {\n                DbErr::RecordNotFound(format!(\"Loader: failed to find model for {key:?}\"))\n            })?;\n\n            vec.add(item.into());\n        }\n\n        (keys, hashmap)\n    } else {\n        let keys = items\n            .map(|model| get_key_from_model(&rel_def.from_col, model))\n            .collect::<Result<Vec<_>, _>>()?;\n\n        if keys.is_empty() {\n            return Ok(Vec::new());\n        }\n\n        let condition = prepare_condition::<Model>(\n            &rel_def.to_tbl,\n            &rel_def.from_col,\n            &rel_def.to_col,\n            &keys,\n            db.get_database_backend(),\n        )?;\n\n        let stmt = QueryFilter::filter(stmt, condition);\n\n        let data = stmt.all(db).await?;\n\n        let mut hashmap: HashMap<ValueTuple, T> = Default::default();\n\n        for item in data {\n            let key = get_key_from_model(&rel_def.to_col, &item)?;\n            let holder = hashmap.entry(key).or_default();\n            holder.add(item.into());\n        }\n\n        (keys, hashmap)\n    };\n\n    let result: Vec<T> = keys\n        .iter()\n        .map(|key: &ValueTuple| hashmap.get(key).cloned().unwrap_or_default())\n        .collect();\n\n    Ok(result)\n}\n\nfn cmp_table_ref(left: &TableRef, right: &TableRef) -> bool {\n    left == right\n}\n\nfn extract_col_type<Model>(\n    left: &Identity,\n    right: &Identity,\n) -> Result<Vec<dynamic::FieldType>, DbErr>\nwhere\n    Model: ModelTrait,\n{\n    use itertools::Itertools;\n\n    if left.arity() != right.arity() {\n        return Err(DbErr::Type(format!(\n            \"Identity mismatch: left: {} != right: {}\",\n            left.arity(),\n            right.arity()\n        )));\n    }\n\n    let vec = left\n        .iter()\n        .zip_eq(right.iter())\n        .map(|(l, r)| {\n            let col_a =\n                <<<Model as ModelTrait>::Entity as EntityTrait>::Column as FromStr>::from_str(\n                    &l.inner(),\n                )\n                .map_err(|_| DbErr::Type(format!(\"Failed at mapping '{l}'\")))?;\n            Ok(dynamic::FieldType::new(\n                r.clone(),\n                Model::get_value_type(col_a),\n            ))\n        })\n        .collect::<Result<Vec<_>, DbErr>>()?;\n\n    Ok(vec)\n}\n\n#[allow(clippy::unwrap_used)]\nfn dyn_model_to_key(dyn_model: dynamic::Model) -> Result<ValueTuple, DbErr> {\n    Ok(match dyn_model.fields.len() {\n        0 => return Err(DbErr::Type(\"Identity zero?\".into())),\n        1 => ValueTuple::One(dyn_model.fields.into_iter().next().unwrap().value),\n        2 => {\n            let mut iter = dyn_model.fields.into_iter();\n            ValueTuple::Two(iter.next().unwrap().value, iter.next().unwrap().value)\n        }\n        3 => {\n            let mut iter = dyn_model.fields.into_iter();\n            ValueTuple::Three(\n                iter.next().unwrap().value,\n                iter.next().unwrap().value,\n                iter.next().unwrap().value,\n            )\n        }\n        _ => ValueTuple::Many(dyn_model.fields.into_iter().map(|v| v.value).collect()),\n    })\n}\n\nfn arity_mismatch(expected: usize, actual: &ValueTuple) -> DbErr {\n    DbErr::Type(format!(\n        \"Loader: arity mismatch: expected {expected}, got {} in {actual:?}\",\n        actual.arity()\n    ))\n}\n\nfn prepare_condition<Model>(\n    table: &TableRef,\n    from: &Identity,\n    to: &Identity,\n    keys: &[ValueTuple],\n    db_backend: DbBackend,\n) -> Result<Condition, DbErr>\nwhere\n    Model: ModelTrait,\n{\n    if matches!(db_backend, DbBackend::Postgres) {\n        prepare_condition_with_save_as::<Model>(table, from, to, keys)\n    } else {\n        column_tuple_in_condition(table, to, keys, db_backend)\n    }\n}\n\nfn prepare_condition_with_save_as<Model>(\n    table: &TableRef,\n    from: &Identity,\n    to: &Identity,\n    keys: &[ValueTuple],\n) -> Result<Condition, DbErr>\nwhere\n    Model: ModelTrait,\n{\n    use itertools::Itertools;\n\n    let keys = keys.iter().unique();\n    let (from_cols, to_cols) = resolve_column_pairs::<Model>(table, from, to)?;\n\n    if from_cols.is_empty() || to_cols.is_empty() {\n        return Err(DbErr::Type(format!(\n            \"Loader: resolved zero columns for identities {from:?} -> {to:?}\"\n        )));\n    }\n\n    let arity = from_cols.len();\n\n    let value_tuples = keys\n        .map(|key| {\n            let key_arity = key.arity();\n            if arity != key_arity {\n                return Err(arity_mismatch(arity, key));\n            }\n\n            // For Postgres, we need to use `AS` to cast the value to the correct type\n            Ok(apply_save_as::<Model>(&from_cols, key.clone()))\n        })\n        .collect::<Result<Vec<_>, DbErr>>()?;\n\n    // Build `(c1, c2, ...) IN ((v11, v12, ...), (v21, v22, ...), ...)`\n    let expr = Expr::tuple(create_table_columns(table, to)).is_in(value_tuples);\n\n    Ok(expr.into())\n}\n\ntype ModelColumn<M> = <<M as ModelTrait>::Entity as EntityTrait>::Column;\n\ntype ColumnPairs<M> = (Vec<ModelColumn<M>>, Vec<ColumnRef>);\n\nfn resolve_column_pairs<Model>(\n    table: &TableRef,\n    from: &Identity,\n    to: &Identity,\n) -> Result<ColumnPairs<Model>, DbErr>\nwhere\n    Model: ModelTrait,\n    ModelColumn<Model>: ColumnTrait,\n{\n    let from_columns = parse_identity_columns::<Model>(from)?;\n    let to_columns = column_refs_from_identity(table, to);\n\n    if from_columns.len() != to_columns.len() {\n        return Err(DbErr::Type(format!(\n            \"Loader: identity column count mismatch between {from:?} and {to:?}\"\n        )));\n    }\n\n    Ok((from_columns, to_columns))\n}\n\nfn check_self_ref(rel_def: &RelationDef) -> Result<(), DbErr> {\n    if rel_def.from_tbl != rel_def.to_tbl {\n        return Err(query_err(\"Relation must be self referencing\"));\n    }\n    if rel_def.is_owner {\n        return Err(query_err(\"Relation must be belongs_to\"));\n    }\n    Ok(())\n}\n\nfn check_self_ref_many(rel_def: &RelationDef) -> Result<(), DbErr> {\n    if rel_def.from_tbl != rel_def.to_tbl {\n        return Err(query_err(\"Relation must be self referencing\"));\n    }\n    if !rel_def.is_owner {\n        return Err(query_err(\"Relation must not be belongs_to\"));\n    }\n    Ok(())\n}\n\nfn column_refs_from_identity(table: &TableRef, identity: &Identity) -> Vec<ColumnRef> {\n    identity\n        .iter()\n        .map(|col| table_column(table, col))\n        .collect()\n}\n\nfn parse_identity_columns<Model>(identity: &Identity) -> Result<Vec<ModelColumn<Model>>, DbErr>\nwhere\n    Model: ModelTrait,\n{\n    identity\n        .iter()\n        .map(|from_col| try_conv_ident_to_column::<Model>(from_col))\n        .collect()\n}\n\nfn try_conv_ident_to_column<Model>(ident: &DynIden) -> Result<ModelColumn<Model>, DbErr>\nwhere\n    Model: ModelTrait,\n{\n    let column_name = ident.inner();\n    ModelColumn::<Model>::from_str(&column_name)\n        .map_err(|_| DbErr::Type(format!(\"Failed at mapping '{column_name}' to column\")))\n}\n\nfn table_column(tbl: &TableRef, col: &DynIden) -> ColumnRef {\n    (tbl.sea_orm_table().to_owned(), col.clone()).into_column_ref()\n}\n\n/// Create a vector of `Expr::col` from the table and identity, e.g. [Expr::col((table, col1)), Expr::col((table, col2)), ...]\nfn create_table_columns(table: &TableRef, cols: &Identity) -> Vec<Expr> {\n    cols.iter()\n        .map(|col| table_column(table, col))\n        .map(Expr::col)\n        .collect()\n}\n\n/// Apply `save_as` to each value in the tuple, e.g. `(Cast(val1 as type1), Cast(val2 as type2), ...)`\nfn apply_save_as<M: ModelTrait>(cols: &[ModelColumn<M>], values: ValueTuple) -> Expr {\n    let values_expr_iter = values.into_iter().map(Expr::val);\n\n    let tuple_exprs: Vec<_> = cols\n        .iter()\n        .zip(values_expr_iter)\n        .map(|(model_column, value)| model_column.save_as(value))\n        .collect();\n\n    Expr::tuple(tuple_exprs)\n}\n\n#[cfg(test)]\nmod tests {\n    fn cake_model(id: i32) -> sea_orm::tests_cfg::cake::Model {\n        let name = match id {\n            1 => \"apple cake\",\n            2 => \"orange cake\",\n            3 => \"fruit cake\",\n            4 => \"chocolate cake\",\n            _ => \"\",\n        }\n        .to_string();\n        sea_orm::tests_cfg::cake::Model { id, name }\n    }\n\n    fn fruit_model(id: i32, cake_id: Option<i32>) -> sea_orm::tests_cfg::fruit::Model {\n        let name = match id {\n            1 => \"apple\",\n            2 => \"orange\",\n            3 => \"grape\",\n            4 => \"strawberry\",\n            _ => \"\",\n        }\n        .to_string();\n        sea_orm::tests_cfg::fruit::Model { id, name, cake_id }\n    }\n\n    fn filling_model(id: i32) -> sea_orm::tests_cfg::filling::Model {\n        let name = match id {\n            1 => \"apple juice\",\n            2 => \"orange jam\",\n            3 => \"chocolate crust\",\n            4 => \"strawberry jam\",\n            _ => \"\",\n        }\n        .to_string();\n        sea_orm::tests_cfg::filling::Model {\n            id,\n            name,\n            vendor_id: Some(1),\n            ignored_attr: 0,\n        }\n    }\n\n    fn cake_filling_model(\n        cake_id: i32,\n        filling_id: i32,\n    ) -> sea_orm::tests_cfg::cake_filling::Model {\n        sea_orm::tests_cfg::cake_filling::Model {\n            cake_id,\n            filling_id,\n        }\n    }\n\n    #[tokio::test]\n    async fn test_load_one() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_model(1), cake_model(2)]])\n            .into_connection();\n\n        let fruits = vec![fruit_model(1, Some(1))];\n\n        let cakes = fruits\n            .load_one(cake::Entity::find(), &db)\n            .await\n            .expect(\"Should return something\");\n\n        assert_eq!(cakes, [Some(cake_model(1))]);\n    }\n\n    #[tokio::test]\n    async fn test_load_one_same_cake() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_model(1), cake_model(2)]])\n            .into_connection();\n\n        let fruits = vec![fruit_model(1, Some(1)), fruit_model(2, Some(1))];\n\n        let cakes = fruits\n            .load_one(cake::Entity::find(), &db)\n            .await\n            .expect(\"Should return something\");\n\n        assert_eq!(cakes, [Some(cake_model(1)), Some(cake_model(1))]);\n    }\n\n    #[tokio::test]\n    async fn test_load_one_empty() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_model(1), cake_model(2)]])\n            .into_connection();\n\n        let fruits: Vec<fruit::Model> = vec![];\n\n        let cakes = fruits\n            .load_one(cake::Entity::find(), &db)\n            .await\n            .expect(\"Should return something\");\n\n        assert_eq!(cakes, []);\n    }\n\n    #[tokio::test]\n    async fn test_load_many() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[fruit_model(1, Some(1))]])\n            .into_connection();\n\n        let cakes = vec![cake_model(1), cake_model(2)];\n\n        let fruits = cakes\n            .load_many(fruit::Entity::find(), &db)\n            .await\n            .expect(\"Should return something\");\n\n        assert_eq!(fruits, [vec![fruit_model(1, Some(1))], vec![]]);\n    }\n\n    #[tokio::test]\n    async fn test_load_many_same_fruit() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[fruit_model(1, Some(1)), fruit_model(2, Some(1))]])\n            .into_connection();\n\n        let cakes = vec![cake_model(1), cake_model(2)];\n\n        let fruits = cakes\n            .load_many(fruit::Entity::find(), &db)\n            .await\n            .expect(\"Should return something\");\n\n        assert_eq!(\n            fruits,\n            [\n                vec![fruit_model(1, Some(1)), fruit_model(2, Some(1))],\n                vec![]\n            ]\n        );\n    }\n\n    #[tokio::test]\n    async fn test_load_many_empty() {\n        use sea_orm::{DbBackend, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres).into_connection();\n\n        let cakes: Vec<cake::Model> = vec![];\n\n        let fruits = cakes\n            .load_many(fruit::Entity::find(), &db)\n            .await\n            .expect(\"Should return something\");\n\n        let empty_vec: Vec<Vec<fruit::Model>> = vec![];\n\n        assert_eq!(fruits, empty_vec);\n    }\n\n    #[tokio::test]\n    async fn test_load_many_to_many_base() {\n        use sea_orm::{DbBackend, IntoMockRow, LoaderTrait, MockDatabase, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([\n                [cake_filling_model(1, 1).into_mock_row()],\n                [filling_model(1).into_mock_row()],\n            ])\n            .into_connection();\n\n        let cakes = vec![cake_model(1)];\n\n        let fillings = cakes\n            .load_many_to_many(Filling, CakeFilling, &db)\n            .await\n            .expect(\"Should return something\");\n\n        assert_eq!(fillings, vec![vec![filling_model(1)]]);\n    }\n\n    #[tokio::test]\n    async fn test_load_many_to_many_complex() {\n        use sea_orm::{DbBackend, IntoMockRow, LoaderTrait, MockDatabase, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([\n                [\n                    cake_filling_model(1, 1).into_mock_row(),\n                    cake_filling_model(1, 2).into_mock_row(),\n                    cake_filling_model(1, 3).into_mock_row(),\n                    cake_filling_model(2, 1).into_mock_row(),\n                    cake_filling_model(2, 2).into_mock_row(),\n                ],\n                [\n                    filling_model(1).into_mock_row(),\n                    filling_model(2).into_mock_row(),\n                    filling_model(3).into_mock_row(),\n                    filling_model(4).into_mock_row(),\n                    filling_model(5).into_mock_row(),\n                ],\n            ])\n            .into_connection();\n\n        let cakes = vec![cake_model(1), cake_model(2), cake_model(3)];\n\n        let fillings = cakes\n            .load_many_to_many(Filling, CakeFilling, &db)\n            .await\n            .expect(\"Should return something\");\n\n        assert_eq!(\n            fillings,\n            vec![\n                vec![filling_model(1), filling_model(2), filling_model(3)],\n                vec![filling_model(1), filling_model(2)],\n                vec![],\n            ]\n        );\n    }\n\n    #[tokio::test]\n    async fn test_load_many_to_many_empty() {\n        use sea_orm::{DbBackend, IntoMockRow, LoaderTrait, MockDatabase, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([\n                [cake_filling_model(1, 1).into_mock_row()],\n                [filling_model(1).into_mock_row()],\n            ])\n            .into_connection();\n\n        let cakes: Vec<cake::Model> = vec![];\n\n        let fillings = cakes\n            .load_many_to_many(Filling, CakeFilling, &db)\n            .await\n            .expect(\"Should return something\");\n\n        let empty_vec: Vec<Vec<filling::Model>> = vec![];\n\n        assert_eq!(fillings, empty_vec);\n    }\n\n    #[tokio::test]\n    async fn test_load_one_duplicate_keys() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[cake_model(1), cake_model(2)]])\n            .into_connection();\n\n        let fruits = vec![\n            fruit_model(1, Some(1)),\n            fruit_model(2, Some(1)),\n            fruit_model(3, Some(1)),\n            fruit_model(4, Some(1)),\n        ];\n\n        let cakes = fruits\n            .load_one(cake::Entity::find(), &db)\n            .await\n            .expect(\"Should return something\");\n\n        assert_eq!(cakes.len(), 4);\n        for cake in &cakes {\n            assert_eq!(cake, &Some(cake_model(1)));\n        }\n        let logs = db.into_transaction_log();\n        let sql = format!(\"{:?}\", logs[0]);\n\n        let values_count = sql.matches(\"$1\").count();\n        assert_eq!(values_count, 1, \"Duplicate values were not removed\");\n    }\n\n    #[tokio::test]\n    async fn test_load_many_duplicate_keys() {\n        use sea_orm::{DbBackend, LoaderTrait, MockDatabase, entity::prelude::*, tests_cfg::*};\n\n        let db = MockDatabase::new(DbBackend::Postgres)\n            .append_query_results([[\n                fruit_model(1, Some(1)),\n                fruit_model(2, Some(1)),\n                fruit_model(3, Some(2)),\n            ]])\n            .into_connection();\n\n        let cakes = vec![cake_model(1), cake_model(1), cake_model(2), cake_model(2)];\n\n        let fruits = cakes\n            .load_many(fruit::Entity::find(), &db)\n            .await\n            .expect(\"Should return something\");\n\n        assert_eq!(fruits.len(), 4);\n\n        let logs = db.into_transaction_log();\n        let sql = format!(\"{:?}\", logs[0]);\n\n        let values_count = sql.matches(\"$1\").count() + sql.matches(\"$2\").count();\n        assert_eq!(values_count, 2, \"Duplicate values were not removed\");\n    }\n\n    #[test]\n    fn test_assemble_vectors() {\n        use super::assemble_vectors;\n\n        assert_eq!(\n            assemble_vectors(&[vec![1], vec![], vec![2, 3], vec![]], vec![11, 22, 33]),\n            [vec![11], vec![], vec![22, 33], vec![]]\n        );\n    }\n}\n"
  },
  {
    "path": "src/query/mod.rs",
    "content": "pub(crate) mod combine;\nmod debug;\nmod delete;\nmod helper;\nmod insert;\nmod join;\n#[cfg(feature = \"with-json\")]\nmod json;\nmod loader;\nmod select;\nmod traits;\nmod update;\nmod util;\n\npub use combine::{SelectA, SelectB, SelectC};\npub use debug::*;\npub use delete::*;\npub use helper::*;\npub use insert::*;\n#[cfg(feature = \"with-json\")]\npub use json::*;\npub use loader::*;\npub use select::*;\npub use traits::*;\npub use update::*;\npub(crate) use util::*;\n\npub use crate::{\n    ConnectionTrait, CursorTrait, InsertResult, PaginatorTrait, SelectExt, Statement, StreamTrait,\n    TransactionTrait, UpdateResult, Value, Values,\n};\npub use sea_query::ExprTrait;\n"
  },
  {
    "path": "src/query/select.rs",
    "content": "use crate::{\n    ColumnTrait, EntityTrait, Iterable, Order, PrimaryKeyToColumn, QueryFilter, QueryOrder,\n    QuerySelect, QueryTrait,\n};\nuse core::fmt::Debug;\nuse core::marker::PhantomData;\nuse sea_query::{FunctionCall, IntoColumnRef, SelectStatement, SimpleExpr};\n\n/// Defines a structure to perform select operations\n#[derive(Clone, Debug)]\npub struct Select<E>\nwhere\n    E: EntityTrait,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<E>,\n    pub(crate) linked_index: usize,\n}\n\n/// Defines a structure to perform a SELECT operation on two Models, with the second Model being optional\n#[derive(Clone, Debug)]\npub struct SelectTwo<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F)>,\n}\n\n/// Defines a structure to perform a SELECT operation on many Models\n#[derive(Clone, Debug)]\npub struct SelectTwoMany<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F)>,\n}\n\n/// Defines a structure to perform a SELECT operation on two Models\n#[derive(Clone, Debug)]\npub struct SelectTwoRequired<E, F>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F)>,\n}\n\n/// Topology of multi-joins\npub trait Topology {}\n\n/// A star topology\n#[derive(Debug, Clone)]\npub struct TopologyStar;\n\n/// A chain topology\n#[derive(Debug, Clone)]\npub struct TopologyChain;\n\nimpl Topology for TopologyStar {}\nimpl Topology for TopologyChain {}\n\n/// Perform a SELECT operation on three Models\n#[derive(Clone, Debug)]\npub struct SelectThree<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F, G, TOP)>,\n}\n\n/// Perform a SELECT operation on three Models with results consolidated\n#[derive(Clone, Debug)]\npub struct SelectThreeMany<E, F, G, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F, G, TOP)>,\n}\n\n/// Perform a SELECT operation on 4 Models\n#[derive(Clone, Debug)]\npub struct SelectFour<E, F, G, H, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F, G, H, TOP)>,\n}\n\n/// Perform a SELECT operation on 5 Models\n#[derive(Clone, Debug)]\npub struct SelectFive<E, F, G, H, I, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F, G, H, I, TOP)>,\n}\n\n/// Perform a SELECT operation on 6 Models\n#[derive(Clone, Debug)]\npub struct SelectSix<E, F, G, H, I, J, TOP>\nwhere\n    E: EntityTrait,\n    F: EntityTrait,\n    G: EntityTrait,\n    H: EntityTrait,\n    I: EntityTrait,\n    J: EntityTrait,\n    TOP: Topology,\n{\n    pub(crate) query: SelectStatement,\n    pub(crate) entity: PhantomData<(E, F, G, H, I, J, TOP)>,\n}\n\n/// Performs a conversion to [SimpleExpr]\npub trait IntoSimpleExpr {\n    /// Method to perform the conversion\n    fn into_simple_expr(self) -> SimpleExpr;\n}\n\n/// Extending [IntoSimpleExpr] to support casting ActiveEnum as TEXT in select expression\npub trait ColumnAsExpr: IntoSimpleExpr {\n    /// Casting ActiveEnum as TEXT in select expression,\n    /// otherwise same as [IntoSimpleExpr::into_simple_expr]\n    fn into_column_as_expr(self) -> SimpleExpr;\n}\n\nmacro_rules! impl_query_trait {\n    ( $trait: ident ) => {\n        impl<E> $trait for Select<E>\n        where\n            E: EntityTrait,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n\n        impl<E, F> $trait for SelectTwo<E, F>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n\n        impl<E, F> $trait for SelectTwoMany<E, F>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n\n        impl<E, F> $trait for SelectTwoRequired<E, F>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n        {\n            type QueryStatement = SelectStatement;\n\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n        }\n    };\n}\n\nimpl_query_trait!(QuerySelect);\nimpl_query_trait!(QueryFilter);\nimpl_query_trait!(QueryOrder);\n\nimpl<C> ColumnAsExpr for C\nwhere\n    C: ColumnTrait,\n{\n    fn into_column_as_expr(self) -> SimpleExpr {\n        self.select_as(self.as_column_ref().into_column_ref().into())\n    }\n}\n\nimpl ColumnAsExpr for SimpleExpr {\n    fn into_column_as_expr(self) -> SimpleExpr {\n        self.into_simple_expr()\n    }\n}\n\nimpl<C> IntoSimpleExpr for C\nwhere\n    C: ColumnTrait,\n{\n    fn into_simple_expr(self) -> SimpleExpr {\n        SimpleExpr::Column(self.as_column_ref().into_column_ref())\n    }\n}\n\nimpl IntoSimpleExpr for SimpleExpr {\n    fn into_simple_expr(self) -> SimpleExpr {\n        self\n    }\n}\n\nimpl IntoSimpleExpr for FunctionCall {\n    fn into_simple_expr(self) -> SimpleExpr {\n        SimpleExpr::FunctionCall(self)\n    }\n}\n\nimpl<E> Select<E>\nwhere\n    E: EntityTrait,\n{\n    pub(crate) fn new() -> Self {\n        Self {\n            query: SelectStatement::new(),\n            entity: PhantomData,\n            linked_index: 0,\n        }\n        .prepare_select()\n        .prepare_from()\n    }\n\n    fn prepare_select(mut self) -> Self {\n        self.query.exprs(self.column_list());\n        self\n    }\n\n    fn column_list(&self) -> Vec<SimpleExpr> {\n        E::Column::iter()\n            .map(|col| col.select_as(col.into_expr()))\n            .collect()\n    }\n\n    fn prepare_from(mut self) -> Self {\n        self.query.from(E::default().table_ref());\n        self\n    }\n\n    /// Apply order by primary key to the query statement\n    pub fn order_by_id_asc(self) -> Self {\n        self.order_by_id(Order::Asc)\n    }\n\n    /// Apply order by primary key to the query statement\n    pub fn order_by_id_desc(self) -> Self {\n        self.order_by_id(Order::Desc)\n    }\n\n    /// Apply order by primary key to the query statement\n    pub fn order_by_id(mut self, order: Order) -> Self {\n        for key in E::PrimaryKey::iter() {\n            let col = key.into_column();\n            self.query\n                .order_by_expr(col.into_simple_expr(), order.clone());\n        }\n        self\n    }\n}\n\nimpl<E> QueryTrait for Select<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = SelectStatement;\n    fn query(&mut self) -> &mut SelectStatement {\n        &mut self.query\n    }\n    fn as_query(&self) -> &SelectStatement {\n        &self.query\n    }\n    fn into_query(self) -> SelectStatement {\n        self.query\n    }\n}\n\nmacro_rules! select_two {\n    ( $selector: ident ) => {\n        impl<E, F> QueryTrait for $selector<E, F>\n        where\n            E: EntityTrait,\n            F: EntityTrait,\n        {\n            type QueryStatement = SelectStatement;\n            fn query(&mut self) -> &mut SelectStatement {\n                &mut self.query\n            }\n            fn as_query(&self) -> &SelectStatement {\n                &self.query\n            }\n            fn into_query(self) -> SelectStatement {\n                self.query\n            }\n        }\n    };\n}\n\nselect_two!(SelectTwo);\nselect_two!(SelectTwoMany);\nselect_two!(SelectTwoRequired);\n"
  },
  {
    "path": "src/query/traits.rs",
    "content": "use crate::{DbBackend, Statement, StatementBuilder};\n\n/// A Trait for any type performing queries on a Model or ActiveModel\npub trait QueryTrait {\n    /// Constrain the QueryStatement to [StatementBuilder] trait\n    type QueryStatement: StatementBuilder;\n\n    /// Get a mutable ref to the query builder\n    fn query(&mut self) -> &mut Self::QueryStatement;\n\n    /// Get an immutable ref to the query builder\n    fn as_query(&self) -> &Self::QueryStatement;\n\n    /// Take ownership of the query builder\n    fn into_query(self) -> Self::QueryStatement;\n\n    /// Build the query as [`Statement`]\n    fn build(&self, db_backend: DbBackend) -> Statement {\n        StatementBuilder::build(self.as_query(), &db_backend)\n    }\n\n    /// Apply an operation on the [QueryTrait::QueryStatement] if the given `Option<T>` is `Some(_)`\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     cake::Entity::find()\n    ///         .apply_if(Some(3), |query, v| { query.filter(cake::Column::Id.eq(v)) })\n    ///         .apply_if(Some(100), QuerySelect::limit)\n    ///         .apply_if(None, QuerySelect::offset::<Option<u64>>) // no-op\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"SELECT \"cake\".\"id\", \"cake\".\"name\" FROM \"cake\" WHERE \"cake\".\"id\" = 3 LIMIT 100\"#\n    /// );\n    /// ```\n    fn apply_if<T, F>(self, val: Option<T>, if_some: F) -> Self\n    where\n        Self: Sized,\n        F: FnOnce(Self, T) -> Self,\n    {\n        if let Some(val) = val {\n            if_some(self, val)\n        } else {\n            self\n        }\n    }\n}\n"
  },
  {
    "path": "src/query/update.rs",
    "content": "use crate::{\n    ActiveModelTrait, ActiveValue, ColumnTrait, DbErr, EntityTrait, Iterable, PrimaryKeyToColumn,\n    QueryFilter, QueryTrait,\n};\nuse core::marker::PhantomData;\nuse sea_query::{Expr, IntoIden, SimpleExpr, UpdateStatement};\n\n/// Defines a structure to perform UPDATE query operations on a ActiveModel\n#[derive(Clone, Debug)]\npub struct Update;\n\n/// A request to update an [`ActiveModel`](ActiveModelTrait).\n///\n/// The primary key must be set.\n/// Otherwise, it's impossible to generate the SQL condition and find the record.\n/// In that case, [`exec`][Self::exec] will return an error and not send any queries to the database.\n///\n/// If you want to use [`QueryTrait`] and access the generated SQL query,\n/// you need to convert into [`ValidatedUpdateOne`] first.\n#[derive(Clone, Debug)]\npub struct UpdateOne<A: ActiveModelTrait>(pub(crate) Result<ValidatedUpdateOne<A>, DbErr>);\n\n/// A validated [`UpdateOne`] request, where the primary key is set\n/// and it's possible to generate the right SQL condition.\n#[derive(Clone, Debug)]\npub struct ValidatedUpdateOne<A: ActiveModelTrait> {\n    pub(crate) query: UpdateStatement,\n    pub(crate) model: A,\n}\n\nimpl<A: ActiveModelTrait> TryFrom<UpdateOne<A>> for ValidatedUpdateOne<A> {\n    type Error = DbErr;\n\n    fn try_from(value: UpdateOne<A>) -> Result<Self, Self::Error> {\n        value.0\n    }\n}\n\nimpl<A: ActiveModelTrait> UpdateOne<A> {\n    /// Check whether the primary key is set and we can proceed with the operation.\n    pub fn validate(self) -> Result<ValidatedUpdateOne<A>, DbErr> {\n        self.try_into()\n    }\n}\n\n/// Defines an UPDATE operation on multiple ActiveModels\n#[derive(Clone, Debug)]\npub struct UpdateMany<E>\nwhere\n    E: EntityTrait,\n{\n    pub(crate) query: UpdateStatement,\n    pub(crate) entity: PhantomData<E>,\n}\n\nimpl Update {\n    /// Update one ActiveModel\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, tests_cfg::cake};\n    ///\n    /// assert_eq!(\n    ///     Update::one(cake::ActiveModel {\n    ///         id: ActiveValue::set(1),\n    ///         name: ActiveValue::set(\"Apple Pie\".to_owned()),\n    ///     })\n    ///     .validate()\n    ///     .unwrap()\n    ///     .build(DbBackend::Postgres)\n    ///     .to_string(),\n    ///     r#\"UPDATE \"cake\" SET \"name\" = 'Apple Pie' WHERE \"cake\".\"id\" = 1\"#,\n    /// );\n    /// ```\n    //\n    // (non-doc comment for maintainers)\n    // Ideally, we would make this method fallible instead of stashing and delaying the error.\n    // But that's a bigger breaking change.\n    pub fn one<E, A>(model: A) -> UpdateOne<A>\n    where\n        E: EntityTrait,\n        A: ActiveModelTrait<Entity = E>,\n    {\n        let mut myself = ValidatedUpdateOne {\n            query: UpdateStatement::new()\n                .table(A::Entity::default().table_ref())\n                .to_owned(),\n            model,\n        };\n        // Build the SQL condition from the primary key columns.\n        for key in <A::Entity as EntityTrait>::PrimaryKey::iter() {\n            let col = key.into_column();\n            match myself.model.get(col) {\n                ActiveValue::Set(value) | ActiveValue::Unchanged(value) => {\n                    myself = myself.filter(col.eq(value));\n                }\n                ActiveValue::NotSet => {\n                    return UpdateOne(Err(DbErr::PrimaryKeyNotSet { ctx: \"UpdateOne\" }));\n                }\n            }\n        }\n        // Set the values to update (from the other columns).\n        for col in <A::Entity as EntityTrait>::Column::iter() {\n            if <A::Entity as EntityTrait>::PrimaryKey::from_column(col).is_some() {\n                continue;\n            }\n            match myself.model.get(col) {\n                ActiveValue::Set(value) => {\n                    let expr = col.save_as(Expr::val(value));\n                    myself.query.value(col, expr);\n                }\n                ActiveValue::Unchanged(_) | ActiveValue::NotSet => {}\n            }\n        }\n        UpdateOne(Ok(myself))\n    }\n\n    /// Update many ActiveModel\n    ///\n    /// ```\n    /// use sea_orm::{DbBackend, entity::*, query::*, sea_query::Expr, tests_cfg::fruit};\n    ///\n    /// assert_eq!(\n    ///     Update::many(fruit::Entity)\n    ///         .col_expr(fruit::Column::Name, Expr::value(\"Golden Apple\"))\n    ///         .filter(fruit::Column::Name.contains(\"Apple\"))\n    ///         .build(DbBackend::Postgres)\n    ///         .to_string(),\n    ///     r#\"UPDATE \"fruit\" SET \"name\" = 'Golden Apple' WHERE \"fruit\".\"name\" LIKE '%Apple%'\"#,\n    /// );\n    /// ```\n    pub fn many<E>(entity: E) -> UpdateMany<E>\n    where\n        E: EntityTrait,\n    {\n        UpdateMany {\n            query: UpdateStatement::new().table(entity.table_ref()).to_owned(),\n            entity: PhantomData,\n        }\n    }\n}\n\nimpl<A> QueryFilter for ValidatedUpdateOne<A>\nwhere\n    A: ActiveModelTrait,\n{\n    type QueryStatement = UpdateStatement;\n\n    fn query(&mut self) -> &mut UpdateStatement {\n        &mut self.query\n    }\n}\n\nimpl<E> QueryFilter for UpdateMany<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = UpdateStatement;\n\n    fn query(&mut self) -> &mut UpdateStatement {\n        &mut self.query\n    }\n}\n\nimpl<A> QueryTrait for ValidatedUpdateOne<A>\nwhere\n    A: ActiveModelTrait,\n{\n    type QueryStatement = UpdateStatement;\n\n    fn query(&mut self) -> &mut UpdateStatement {\n        &mut self.query\n    }\n\n    fn as_query(&self) -> &UpdateStatement {\n        &self.query\n    }\n\n    fn into_query(self) -> UpdateStatement {\n        self.query\n    }\n}\n\nimpl<E> QueryTrait for UpdateMany<E>\nwhere\n    E: EntityTrait,\n{\n    type QueryStatement = UpdateStatement;\n\n    fn query(&mut self) -> &mut UpdateStatement {\n        &mut self.query\n    }\n\n    fn as_query(&self) -> &UpdateStatement {\n        &self.query\n    }\n\n    fn into_query(self) -> UpdateStatement {\n        self.query\n    }\n}\n\nimpl<E> UpdateMany<E>\nwhere\n    E: EntityTrait,\n{\n    /// Add the models to update to Self\n    pub fn set<A>(mut self, model: A) -> Self\n    where\n        A: ActiveModelTrait<Entity = E>,\n    {\n        for col in E::Column::iter() {\n            match model.get(col) {\n                ActiveValue::Set(value) => {\n                    let expr = col.save_as(Expr::val(value));\n                    self.query.value(col, expr);\n                }\n                ActiveValue::Unchanged(_) | ActiveValue::NotSet => {}\n            }\n        }\n        self\n    }\n\n    /// Creates a [SimpleExpr] from a column\n    pub fn col_expr<T>(mut self, col: T, expr: SimpleExpr) -> Self\n    where\n        T: IntoIden,\n    {\n        self.query.value(col, expr);\n        self\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::{cake, fruit, lunch_set, sea_orm_active_enums::Tea};\n    use crate::{DbBackend, entity::*, query::*};\n    use sea_query::{Expr, Value};\n\n    #[test]\n    fn update_1() {\n        assert_eq!(\n            Update::one(cake::ActiveModel {\n                id: ActiveValue::set(1),\n                name: ActiveValue::set(\"Apple Pie\".to_owned()),\n            })\n            .validate()\n            .unwrap()\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"UPDATE \"cake\" SET \"name\" = 'Apple Pie' WHERE \"cake\".\"id\" = 1\"#,\n        );\n    }\n\n    #[test]\n    fn update_2() {\n        assert_eq!(\n            Update::one(fruit::ActiveModel {\n                id: ActiveValue::set(1),\n                name: ActiveValue::set(\"Orange\".to_owned()),\n                cake_id: ActiveValue::not_set(),\n            })\n            .validate()\n            .unwrap()\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"UPDATE \"fruit\" SET \"name\" = 'Orange' WHERE \"fruit\".\"id\" = 1\"#,\n        );\n    }\n\n    #[test]\n    fn update_3() {\n        assert_eq!(\n            Update::one(fruit::ActiveModel {\n                id: ActiveValue::set(2),\n                name: ActiveValue::unchanged(\"Apple\".to_owned()),\n                cake_id: ActiveValue::set(Some(3)),\n            })\n            .validate()\n            .unwrap()\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"UPDATE \"fruit\" SET \"cake_id\" = 3 WHERE \"fruit\".\"id\" = 2\"#,\n        );\n    }\n\n    #[test]\n    fn update_4() {\n        assert_eq!(\n            Update::many(fruit::Entity)\n                .col_expr(fruit::Column::CakeId, Expr::value(Value::Int(None)))\n                .filter(fruit::Column::Id.eq(2))\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"UPDATE \"fruit\" SET \"cake_id\" = NULL WHERE \"fruit\".\"id\" = 2\"#,\n        );\n    }\n\n    #[test]\n    fn update_5() {\n        assert_eq!(\n            Update::many(fruit::Entity)\n                .set(fruit::ActiveModel {\n                    name: ActiveValue::set(\"Apple\".to_owned()),\n                    cake_id: ActiveValue::set(Some(3)),\n                    ..Default::default()\n                })\n                .filter(fruit::Column::Id.eq(2))\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"UPDATE \"fruit\" SET \"name\" = 'Apple', \"cake_id\" = 3 WHERE \"fruit\".\"id\" = 2\"#,\n        );\n    }\n\n    #[test]\n    fn update_6() {\n        assert_eq!(\n            Update::many(fruit::Entity)\n                .set(fruit::ActiveModel {\n                    id: ActiveValue::set(3),\n                    ..Default::default()\n                })\n                .filter(fruit::Column::Id.eq(2))\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"UPDATE \"fruit\" SET \"id\" = 3 WHERE \"fruit\".\"id\" = 2\"#,\n        );\n    }\n\n    #[test]\n    fn update_7() {\n        assert_eq!(\n            Update::many(lunch_set::Entity)\n                .set(lunch_set::ActiveModel {\n                    tea: Set(Tea::EverydayTea),\n                    ..Default::default()\n                })\n                .filter(lunch_set::Column::Tea.eq(Tea::BreakfastTea))\n                .build(DbBackend::Postgres)\n                .to_string(),\n            r#\"UPDATE \"lunch_set\" SET \"tea\" = CAST('EverydayTea' AS \"tea\") WHERE \"lunch_set\".\"tea\" = (CAST('BreakfastTea' AS \"tea\"))\"#,\n        );\n    }\n\n    #[test]\n    fn update_8() {\n        assert_eq!(\n            Update::one(lunch_set::ActiveModel {\n                id: Unchanged(1),\n                tea: Set(Tea::EverydayTea),\n                ..Default::default()\n            })\n            .validate()\n            .unwrap()\n            .build(DbBackend::Postgres)\n            .to_string(),\n            r#\"UPDATE \"lunch_set\" SET \"tea\" = CAST('EverydayTea' AS \"tea\") WHERE \"lunch_set\".\"id\" = 1\"#,\n        );\n    }\n}\n"
  },
  {
    "path": "src/query/util.rs",
    "content": "use crate::{\n    ActiveModelTrait, ColumnTrait, Condition, DbBackend, DbErr, EntityTrait, ExprTrait, IdenStatic,\n    Identity, ModelTrait, Value,\n};\nuse sea_query::{ColumnRef, DynIden, Expr, IntoColumnRef, TableRef, ValueTuple};\nuse std::str::FromStr;\n\n#[derive(Default)]\npub struct ValueTupleBuilder(Option<ValueTuple>);\n\nimpl ValueTupleBuilder {\n    pub fn push(&mut self, value: Value) {\n        match self.0.take() {\n            None => {\n                self.0 = Some(ValueTuple::One(value));\n            }\n            Some(ValueTuple::One(a)) => {\n                self.0 = Some(ValueTuple::Two(a, value));\n            }\n            Some(ValueTuple::Two(a, b)) => {\n                self.0 = Some(ValueTuple::Three(a, b, value));\n            }\n            Some(ValueTuple::Three(a, b, c)) => {\n                self.0 = Some(ValueTuple::Many(vec![a, b, c, value]));\n            }\n            Some(ValueTuple::Many(mut items)) => {\n                items.push(value);\n                self.0 = Some(ValueTuple::Many(items));\n            }\n        }\n    }\n\n    pub fn into_inner(self) -> Option<ValueTuple> {\n        self.0\n    }\n}\n\npub fn get_key_from_model<Model>(columns: &Identity, model: &Model) -> Result<ValueTuple, DbErr>\nwhere\n    Model: ModelTrait,\n{\n    let mut values = ValueTupleBuilder::default();\n\n    for col in columns.iter() {\n        let col_name = col.inner();\n        let column = <<Model::Entity as EntityTrait>::Column as FromStr>::from_str(&col_name)\n            .map_err(|_| DbErr::Type(format!(\"Failed at mapping '{col_name}' to column\")))?;\n        values.push(model.get(column));\n    }\n\n    match values.into_inner() {\n        Some(values) => Ok(values),\n        None => Err(DbErr::Type(\"Identity zero?\".into())),\n    }\n}\n\npub fn get_key_from_active_model<ActiveModel>(\n    columns: &Identity,\n    model: &ActiveModel,\n) -> Result<ValueTuple, DbErr>\nwhere\n    ActiveModel: ActiveModelTrait,\n{\n    let mut values = ValueTupleBuilder::default();\n\n    for col in columns.iter() {\n        let col_name = col.inner();\n        let column = <<ActiveModel::Entity as EntityTrait>::Column as FromStr>::from_str(&col_name)\n            .map_err(|_| DbErr::Type(format!(\"Failed at mapping '{col_name}' to column\")))?;\n        values.push(match model.get(column).into_value() {\n            Some(value) => value,\n            None => {\n                return Err(DbErr::AttrNotSet(format!(\n                    \"{}.{}\",\n                    <ActiveModel::Entity as Default>::default().as_str(),\n                    col_name\n                )));\n            }\n        });\n    }\n\n    match values.into_inner() {\n        Some(values) => Ok(values),\n        None => Err(DbErr::Type(\"Identity zero?\".into())),\n    }\n}\n\npub fn set_key_on_active_model<ActiveModel>(\n    columns: &Identity,\n    model: &mut ActiveModel,\n    values: ValueTuple,\n) -> Result<(), DbErr>\nwhere\n    ActiveModel: ActiveModelTrait,\n{\n    if values.arity() != columns.arity() {\n        return Err(DbErr::Type(format!(\n            \"Arity mismatch: {} != {}\",\n            values.arity(),\n            columns.arity(),\n        )));\n    }\n\n    for (column, value) in columns.iter().zip(values) {\n        let col_name = column.inner();\n        let column = <<ActiveModel::Entity as EntityTrait>::Column as FromStr>::from_str(&col_name)\n            .map_err(|_| DbErr::Type(format!(\"Failed at mapping '{col_name}' to column\")))?;\n        model.set_if_not_equals(column, value);\n    }\n\n    Ok(())\n}\n\n/// Set null on the key columns. Return true if succeeded, false if column is not nullable.\npub fn clear_key_on_active_model<ActiveModel>(\n    columns: &Identity,\n    model: &mut ActiveModel,\n) -> Result<bool, DbErr>\nwhere\n    ActiveModel: ActiveModelTrait,\n{\n    for col in columns.iter() {\n        let col_name = col.inner();\n        let column = <<ActiveModel::Entity as EntityTrait>::Column as FromStr>::from_str(&col_name)\n            .map_err(|_| DbErr::Type(format!(\"Failed at mapping '{col_name}' to column\")))?;\n        if !column.def().is_null() {\n            return Ok(false);\n        }\n        model.set(\n            column,\n            match model.get(column).into_value() {\n                Some(value) => value.as_null(),\n                None => {\n                    return Err(DbErr::AttrNotSet(format!(\n                        \"{}.{}\",\n                        <ActiveModel::Entity as Default>::default().as_str(),\n                        col_name\n                    )));\n                }\n            },\n        );\n    }\n\n    Ok(true)\n}\n\n/// Constructs a `WHERE (c1, c2, ...) IN ((v11, v12, ...), (v21, v22, ...), ...)` expression.\n/// Degenerates to `WHERE col IN (v1, v2, ...)` when arity = 1.\npub fn column_tuple_in_condition(\n    table: &TableRef,\n    to: &Identity,\n    keys: &[ValueTuple],\n    backend: DbBackend,\n) -> Result<Condition, DbErr> {\n    use itertools::Itertools;\n\n    let arity = to.arity();\n    let keys = keys.iter().unique();\n\n    if arity == 1 {\n        let values = keys\n            .map(|key| match key {\n                ValueTuple::One(v) => Ok(Expr::val(v.to_owned())),\n                _ => Err(arity_mismatch(arity, key)),\n            })\n            .collect::<Result<Vec<_>, DbErr>>()?;\n\n        let expr = Expr::col(table_column(\n            table,\n            to.iter().next().expect(\"Checked above\"),\n        ))\n        .is_in(values);\n\n        Ok(expr.into())\n    } else if cfg!(feature = \"sqlite-no-row-value-before-3_15\")\n        && matches!(backend, DbBackend::Sqlite)\n    {\n        // SQLite supports row value expressions since 3.15.0\n        // https://www.sqlite.org/releaselog/3_15_0.html\n\n        let table_columns = create_table_columns(table, to);\n\n        let mut outer = Condition::any();\n\n        for key in keys {\n            let key_arity = key.arity();\n            if arity != key_arity {\n                return Err(arity_mismatch(arity, key));\n            }\n\n            let table_columns = table_columns.iter().cloned();\n            let values = key.clone().into_iter().map(Expr::val);\n\n            let inner = table_columns\n                .zip(values)\n                .fold(Condition::all(), |cond, (column, value)| {\n                    cond.add(column.eq(value))\n                });\n\n            // Build `(c1 = v11 AND c2 = v12) OR (c1 = v21 AND c2 = v22) ...`\n            outer = outer.add(inner);\n        }\n\n        Ok(outer)\n    } else {\n        let table_columns = create_table_columns(table, to);\n\n        // A vector of tuples of values, e.g. [(v11, v12, ...), (v21, v22, ...), ...]\n        let value_tuples = keys\n            .map(|key| {\n                let key_arity = key.arity();\n                if arity != key_arity {\n                    return Err(arity_mismatch(arity, key));\n                }\n\n                let tuple_exprs = key.clone().into_iter().map(Expr::val);\n\n                Ok(Expr::tuple(tuple_exprs))\n            })\n            .collect::<Result<Vec<_>, DbErr>>()?;\n\n        // Build `(c1, c2, ...) IN ((v11, v12, ...), (v21, v22, ...), ...)`\n        let expr = Expr::tuple(table_columns).is_in(value_tuples);\n\n        Ok(expr.into())\n    }\n}\n\nfn arity_mismatch(expected: usize, actual: &ValueTuple) -> DbErr {\n    DbErr::Type(format!(\n        \"Loader: arity mismatch: expected {expected}, got {} in {actual:?}\",\n        actual.arity()\n    ))\n}\n\nfn table_column(tbl: &TableRef, col: &DynIden) -> ColumnRef {\n    (tbl.sea_orm_table().to_owned(), col.clone()).into_column_ref()\n}\n\n/// Create a vector of `Expr::col` from the table and identity, e.g. [Expr::col((table, col1)), Expr::col((table, col2)), ...]\nfn create_table_columns(table: &TableRef, cols: &Identity) -> Vec<Expr> {\n    cols.iter()\n        .map(|col| table_column(table, col))\n        .map(Expr::col)\n        .collect()\n}\n"
  },
  {
    "path": "src/rbac/context.rs",
    "content": "use super::{\n    AccessType, RbacError, RbacUserId,\n    entity::{\n        permission::{self, ActiveModel as Permission, PermissionId},\n        resource::{self, ActiveModel as Resource, ResourceId},\n        role::{self, ActiveModel as Role, RoleId},\n        role_hierarchy::{self, ActiveModel as RoleHierarchy},\n        role_permission::{self, ActiveModel as RolePermission},\n        user_override::{self, ActiveModel as UserOverride},\n        user_role::{self, ActiveModel as UserRole},\n    },\n};\nuse crate::{\n    AccessMode, EntityTrait, IsolationLevel, Set, TransactionSession, TransactionTrait,\n    error::DbErr, sea_query::OnConflict,\n};\nuse std::collections::HashMap;\n\n/// Helper class for manipulation of RBAC tables\n#[derive(Debug)]\npub struct RbacContext {\n    tables: HashMap<String, ResourceId>,\n    permissions: HashMap<String, PermissionId>,\n    roles: HashMap<String, RoleId>,\n}\n\n#[derive(Debug)]\npub struct RbacAddRoleHierarchy {\n    pub super_role: &'static str,\n    pub role: &'static str,\n}\n\n#[derive(Debug)]\npub struct RbacAddUserOverride {\n    pub user_id: i64,\n    pub table: &'static str,\n    pub action: &'static str,\n    pub grant: bool,\n}\n\nimpl RbacContext {\n    /// Load context from database connection\n    pub async fn load<C: TransactionTrait>(db: &C) -> Result<Self, DbErr> {\n        // ensure snapshot is consistent across all tables\n        let txn = &db\n            .begin_with_config(\n                Some(IsolationLevel::ReadCommitted),\n                Some(AccessMode::ReadOnly),\n            )\n            .await?;\n\n        let tables = resource::Entity::find()\n            .all(txn)\n            .await?\n            .into_iter()\n            .map(|t| (t.table, t.id))\n            .collect();\n\n        let permissions = permission::Entity::find()\n            .all(txn)\n            .await?\n            .into_iter()\n            .map(|p| (p.action, p.id))\n            .collect();\n\n        let roles = role::Entity::find()\n            .all(txn)\n            .await?\n            .into_iter()\n            .map(|r| (r.role, r.id))\n            .collect();\n\n        Ok(Self {\n            tables,\n            permissions,\n            roles,\n        })\n    }\n\n    /// Add multiple tables as resources\n    pub async fn add_tables<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        tables: &[&'static str],\n    ) -> Result<(), DbErr> {\n        let txn = db.begin().await?;\n\n        for table_name in tables {\n            if let Some(table_id) = resource::Entity::insert(Resource {\n                table: Set(table_name.to_string()),\n                ..Default::default()\n            })\n            .on_conflict_do_nothing()\n            .exec(&txn)\n            .await?\n            .last_insert_id()?\n            {\n                self.tables.insert(table_name.to_string(), table_id);\n            }\n        }\n\n        txn.commit().await\n    }\n\n    /// Add CRUD actions\n    pub async fn add_crud_permissions<C: TransactionTrait>(&mut self, db: &C) -> Result<(), DbErr> {\n        let txn = db.begin().await?;\n\n        for action in [\n            AccessType::Select,\n            AccessType::Insert,\n            AccessType::Update,\n            AccessType::Delete,\n        ] {\n            if let Some(permission_id) = permission::Entity::insert(Permission {\n                action: Set(action.as_str().to_owned()),\n                ..Default::default()\n            })\n            .on_conflict_do_nothing()\n            .exec(&txn)\n            .await?\n            .last_insert_id()?\n            {\n                self.permissions\n                    .insert(action.as_str().to_owned(), permission_id);\n            }\n        }\n\n        txn.commit().await\n    }\n\n    /// Add multiple roles\n    pub async fn add_roles<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        roles: &[&'static str],\n    ) -> Result<(), DbErr> {\n        let txn = db.begin().await?;\n\n        for role in roles {\n            if let Some(role_id) = role::Entity::insert(Role {\n                role: Set(role.to_string()),\n                ..Default::default()\n            })\n            .on_conflict_do_nothing()\n            .exec(&txn)\n            .await?\n            .last_insert_id()?\n            {\n                self.roles.insert(role.to_string(), role_id);\n            }\n        }\n\n        txn.commit().await\n    }\n\n    pub fn get_role(&self, role: &'static str) -> Result<&RoleId, DbErr> {\n        self.roles\n            .get(role)\n            .ok_or_else(|| DbErr::RbacError(RbacError::RoleNotFound(role.to_string()).to_string()))\n    }\n\n    /// Add permissions to roles. Will take cartesian product of tables and actions.\n    pub async fn add_role_permissions<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        role: &'static str,\n        actions: &[&'static str],\n        tables: &[&'static str],\n    ) -> Result<(), DbErr> {\n        self.update_role_permissions(db, role, actions, tables, true)\n            .await\n    }\n\n    /// Remove permissions from roles. Will take cartesian product of tables and actions.\n    pub async fn remove_role_permissions<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        role: &'static str,\n        actions: &[&'static str],\n        tables: &[&'static str],\n    ) -> Result<(), DbErr> {\n        self.update_role_permissions(db, role, actions, tables, false)\n            .await\n    }\n\n    async fn update_role_permissions<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        role: &'static str,\n        actions: &[&'static str],\n        tables: &[&'static str],\n        grant: bool,\n    ) -> Result<(), DbErr> {\n        let txn = db.begin().await?;\n\n        for table_name in tables {\n            for action in actions {\n                let model = RolePermission {\n                    role_id: Set(*self.roles.get(role).ok_or_else(|| {\n                        DbErr::RbacError(RbacError::RoleNotFound(role.to_string()).to_string())\n                    })?),\n                    permission_id: Set(*self.permissions.get(*action).ok_or_else(|| {\n                        DbErr::RbacError(\n                            RbacError::PermissionNotFound(action.to_string()).to_string(),\n                        )\n                    })?),\n                    resource_id: Set(*self.tables.get(*table_name).ok_or_else(|| {\n                        DbErr::RbacError(\n                            RbacError::ResourceNotFound(table_name.to_string()).to_string(),\n                        )\n                    })?),\n                };\n                if grant {\n                    role_permission::Entity::insert(model)\n                        .on_conflict_do_nothing()\n                        .exec(&txn)\n                        .await?;\n                } else {\n                    role_permission::Entity::delete(model).exec(&txn).await?;\n                }\n            }\n        }\n\n        txn.commit().await\n    }\n\n    pub async fn add_user_override<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        rows: &[RbacAddUserOverride],\n    ) -> Result<(), DbErr> {\n        let txn = db.begin().await?;\n\n        for RbacAddUserOverride {\n            user_id,\n            table,\n            action,\n            grant,\n        } in rows\n        {\n            user_override::Entity::insert(UserOverride {\n                user_id: Set(RbacUserId(*user_id)),\n                permission_id: Set(*self.permissions.get(*action).ok_or_else(|| {\n                    DbErr::RbacError(RbacError::PermissionNotFound(action.to_string()).to_string())\n                })?),\n                resource_id: Set(*self.tables.get(*table).ok_or_else(|| {\n                    DbErr::RbacError(RbacError::ResourceNotFound(table.to_string()).to_string())\n                })?),\n                grant: Set(*grant),\n            })\n            .on_conflict(\n                OnConflict::columns([\n                    user_override::Column::UserId,\n                    user_override::Column::PermissionId,\n                    user_override::Column::ResourceId,\n                ])\n                .update_column(user_override::Column::Grant)\n                .to_owned(),\n            )\n            .try_insert()\n            .exec(&txn)\n            .await?;\n        }\n\n        txn.commit().await\n    }\n\n    pub async fn add_role_hierarchy<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        rows: &[RbacAddRoleHierarchy],\n    ) -> Result<(), DbErr> {\n        let txn = db.begin().await?;\n\n        for RbacAddRoleHierarchy { super_role, role } in rows {\n            role_hierarchy::Entity::insert(RoleHierarchy {\n                super_role_id: Set(*self.roles.get(*super_role).ok_or_else(|| {\n                    DbErr::RbacError(RbacError::RoleNotFound(super_role.to_string()).to_string())\n                })?),\n                role_id: Set(*self.roles.get(*role).ok_or_else(|| {\n                    DbErr::RbacError(RbacError::RoleNotFound(role.to_string()).to_string())\n                })?),\n            })\n            .on_conflict_do_nothing()\n            .exec(&txn)\n            .await?;\n        }\n\n        txn.commit().await\n    }\n\n    /// Assign role to users. Note that each user can only have 1 role,\n    /// so this assignment replaces current role.\n    /// `rows: (UserId, role)`\n    pub async fn assign_user_role<C: TransactionTrait>(\n        &mut self,\n        db: &C,\n        rows: &[(i64, &'static str)],\n    ) -> Result<(), DbErr> {\n        let txn = db.begin().await?;\n\n        for (user_id, role) in rows {\n            user_role::Entity::insert(UserRole {\n                user_id: Set(RbacUserId(*user_id)),\n                role_id: Set(*self.roles.get(*role).ok_or_else(|| {\n                    DbErr::RbacError(RbacError::RoleNotFound(role.to_string()).to_string())\n                })?),\n            })\n            .on_conflict(\n                OnConflict::column(user_role::Column::UserId)\n                    .update_column(user_role::Column::RoleId)\n                    .to_owned(),\n            )\n            .try_insert()\n            .exec(&txn)\n            .await?;\n        }\n\n        txn.commit().await\n    }\n}\n"
  },
  {
    "path": "src/rbac/engine/loader.rs",
    "content": "use super::super::entity::{\n    permission::Entity as Permission, resource::Entity as Resource, role::Entity as Role,\n    role_hierarchy::Entity as RoleHierarchy, role_permission::Entity as RolePermission,\n    user_override::Entity as UserOverride, user_role::Entity as UserRole,\n};\nuse super::{RbacEngine, RbacSnapshot};\nuse crate::{AccessMode, DbConn, DbErr, EntityTrait, IsolationLevel, TransactionTrait};\n\nimpl RbacEngine {\n    pub async fn load_from(db: &DbConn) -> Result<Self, DbErr> {\n        // ensure snapshot is consistent across all tables\n        let txn = &db\n            .begin_with_config(\n                Some(IsolationLevel::ReadCommitted),\n                Some(AccessMode::ReadOnly),\n            )\n            .await?;\n\n        let resources = Resource::find().all(txn).await?;\n        let permissions = Permission::find().all(txn).await?;\n        let roles = Role::find().all(txn).await?;\n        let user_roles = UserRole::find().all(txn).await?;\n        let role_permissions = RolePermission::find().all(txn).await?;\n        let user_overrides = UserOverride::find().all(txn).await?;\n        let role_hierarchy = RoleHierarchy::find().all(txn).await?;\n\n        let snapshot = RbacSnapshot {\n            resources,\n            permissions,\n            roles,\n            user_roles,\n            role_permissions,\n            user_overrides,\n            role_hierarchy,\n        };\n\n        Ok(Self::from_snapshot(snapshot))\n    }\n}\n"
  },
  {
    "path": "src/rbac/engine/mod.rs",
    "content": "use super::entity::{\n    permission::{Model as Permission, PermissionId},\n    resource::{Model as Resource, ResourceId},\n    role::{Model as Role, RoleId},\n    role_hierarchy::Model as RoleHierarchy,\n    role_permission::Model as RolePermission,\n    user::UserId,\n    user_override::Model as UserOverride,\n    user_role::Model as UserRole,\n};\nuse super::{Error, WILDCARD};\n\nmod loader;\nmod permission_request;\nmod resource_request;\nmod role_hierarchy_impl;\nmod snapshot;\n\npub use permission_request::*;\npub use resource_request::*;\nuse role_hierarchy_impl::*;\npub use snapshot::*;\n\nuse std::collections::{HashMap, HashSet};\n\npub struct RbacEngine {\n    resources: HashMap<ResourceRequest, Resource>,\n    permissions: HashMap<PermissionRequest, Permission>,\n    wildcard_resources: HashMap<ResourceId, Resource>,\n    wildcard_permissions: HashMap<PermissionId, Permission>,\n    roles: HashMap<RoleId, Role>,\n    user_roles: HashMap<UserId, RoleId>,\n    role_permissions: HashMap<RoleId, HashSet<(PermissionId, ResourceId)>>,\n    user_overrides: HashMap<UserId, Vec<UserOverride>>,\n    role_hierarchy: HashMap<RoleId, Vec<RoleId>>, // Role -> ChildRole\n}\n\nimpl std::fmt::Debug for RbacEngine {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"RbacEngine\")\n    }\n}\n\n#[derive(Debug, PartialEq, Eq)]\npub struct RbacUserRolePermissions {\n    pub role: Role,\n    pub resource_permissions: RbacPermissionsByResources,\n}\n\npub type RbacRolesAndRanks = Vec<(Role, u32)>;\n\npub type RbacRoleHierarchyList = Vec<RoleHierarchy>;\n\npub type RbacResourcesAndPermissions = (Vec<Resource>, Vec<Permission>);\n\npub type RbacPermissionsByResources = Vec<(Resource, Vec<Permission>)>;\n\nimpl RbacEngine {\n    pub fn from_snapshot(\n        RbacSnapshot {\n            resources: resources_rows,\n            permissions: permissions_rows,\n            roles: roles_rows,\n            user_roles: user_roles_rows,\n            role_permissions: role_permissions_rows,\n            user_overrides: user_overrides_rows,\n            role_hierarchy: role_hierarchy_rows,\n        }: RbacSnapshot,\n    ) -> Self {\n        let mut resources: HashMap<ResourceRequest, Resource> = Default::default();\n        let mut wildcard_resources = HashMap::new();\n        for resource in resources_rows {\n            if resource.schema.as_deref() == Some(WILDCARD) || resource.table == WILDCARD {\n                wildcard_resources.insert(resource.id, resource);\n            } else {\n                resources.insert(resource.clone().into(), resource);\n            }\n        }\n\n        let mut permissions: HashMap<PermissionRequest, Permission> = Default::default();\n        let mut wildcard_permissions = HashMap::new();\n        for permission in permissions_rows {\n            if permission.action == WILDCARD {\n                wildcard_permissions.insert(permission.id, permission);\n            } else {\n                permissions.insert(permission.clone().into(), permission);\n            }\n        }\n\n        let roles: HashMap<RoleId, Role> = roles_rows.into_iter().map(|r| (r.id, r)).collect();\n\n        let mut user_roles: HashMap<UserId, RoleId> = Default::default();\n        for user_role in user_roles_rows {\n            user_roles.insert(user_role.user_id, user_role.role_id);\n        }\n\n        let mut role_permissions: HashMap<RoleId, HashSet<(PermissionId, ResourceId)>> =\n            Default::default();\n        for rp in role_permissions_rows {\n            let set = role_permissions.entry(rp.role_id).or_default();\n            set.insert((rp.permission_id, rp.resource_id));\n        }\n\n        let mut user_overrides: HashMap<UserId, Vec<UserOverride>> = Default::default();\n        for user_override in user_overrides_rows {\n            user_overrides\n                .entry(user_override.user_id)\n                .or_default()\n                .push(user_override);\n        }\n\n        let mut role_hierarchy: HashMap<RoleId, Vec<RoleId>> = Default::default();\n        for rh in role_hierarchy_rows {\n            role_hierarchy\n                .entry(rh.super_role_id)\n                .or_default()\n                .push(rh.role_id);\n        }\n\n        RbacEngine {\n            resources,\n            permissions,\n            wildcard_resources,\n            wildcard_permissions,\n            roles,\n            user_roles,\n            role_permissions,\n            user_overrides,\n            role_hierarchy,\n        }\n    }\n\n    /// get user's role and walk the hierarchy, returning all assigned roles\n    fn get_user_role_ids(&self, user_id: &UserId) -> Result<HashSet<RoleId>, Error> {\n        if let Some(role) = self.user_roles.get(&user_id) {\n            let mut user_roles = HashSet::new();\n            for role in enumerate_role(*role, &self.role_hierarchy) {\n                if !self.roles.contains_key(&role) {\n                    return Err(Error::RoleNotFound(format!(\"{role:?}\")));\n                }\n                user_roles.insert(role);\n            }\n            Ok(user_roles)\n        } else {\n            Err(Error::UserNotFound(format!(\"{user_id:?}\")))\n        }\n    }\n\n    pub fn get_roles_and_ranks(&self) -> Result<RbacRolesAndRanks, Error> {\n        let mut all_roles = Vec::new();\n        for role_id in self.roles.keys() {\n            all_roles.push((\n                self.roles\n                    .get(role_id)\n                    .cloned()\n                    .ok_or_else(|| Error::RoleNotFound(format!(\"{role_id:?}\")))?,\n                enumerate_role(*role_id, &self.role_hierarchy).len() as u32,\n            ));\n        }\n        // descending rank but ascending role\n        all_roles.sort_by_key(|r| (-(r.1 as i64), r.0.id));\n        Ok(all_roles)\n    }\n\n    pub fn get_user_role_permissions(\n        &self,\n        user_id: UserId,\n    ) -> Result<RbacUserRolePermissions, Error> {\n        let mut user_roles: Vec<RoleId> = self.get_user_role_ids(&user_id)?.into_iter().collect();\n        user_roles.sort();\n\n        let mut role_permissions: HashSet<(PermissionId, ResourceId)> = Default::default();\n\n        for role_id in user_roles {\n            if let Some(items) = self.role_permissions.get(&role_id) {\n                role_permissions.extend(items.into_iter());\n            }\n        }\n\n        if let Some(user_overrides) = self.user_overrides.get(&user_id) {\n            for over in user_overrides {\n                let role_permission = (over.permission_id, over.resource_id);\n                if role_permissions.contains(&role_permission) {\n                    if !over.grant {\n                        role_permissions.remove(&role_permission);\n                    }\n                } else if over.grant {\n                    role_permissions.insert(role_permission);\n                }\n            }\n        }\n\n        Ok(RbacUserRolePermissions {\n            role: self\n                .roles\n                .get(&self.user_roles.get(&user_id).expect(\"Checked above\"))\n                .expect(\"Checked above\")\n                .to_owned(),\n            resource_permissions: self.group_permissions_by_resources(\n                role_permissions.into_iter().map(|(p, r)| (r, p)),\n            )?,\n        })\n    }\n\n    pub fn list_resources_and_permissions(&self) -> RbacResourcesAndPermissions {\n        (\n            self.resources\n                .values()\n                .chain(self.wildcard_resources.values())\n                .cloned()\n                .collect(),\n            self.permissions\n                .values()\n                .chain(self.wildcard_permissions.values())\n                .cloned()\n                .collect(),\n        )\n    }\n\n    pub fn list_role_hierarchy_edges(&self, role_id: RoleId) -> Vec<RoleHierarchy> {\n        list_role_hierarchy_edges(role_id, &self.role_hierarchy)\n    }\n\n    fn group_permissions_by_resources(\n        &self,\n        items: impl Iterator<Item = (ResourceId, PermissionId)>,\n    ) -> Result<RbacPermissionsByResources, Error> {\n        let mut map: HashMap<ResourceId, (Resource, Vec<Permission>)> = Default::default();\n\n        for item in items {\n            let permission = if let Some(p) = self.wildcard_permissions.get(&item.1) {\n                p\n            } else {\n                self.permissions\n                    .values()\n                    .find(|p| p.id == item.1)\n                    .ok_or_else(|| Error::PermissionNotFound(format!(\"{:?}\", item.1)))?\n            };\n\n            let resource = if let Some(r) = self.wildcard_resources.get(&item.0) {\n                r\n            } else {\n                self.resources\n                    .values()\n                    .find(|r| r.id == item.0)\n                    .ok_or_else(|| Error::ResourceNotFound(format!(\"{:?}\", item.0)))?\n            };\n\n            map.entry(item.0)\n                .or_insert_with(|| (resource.to_owned(), Default::default()))\n                .1\n                .push(permission.to_owned());\n        }\n\n        let mut vec: Vec<_> = map.into_values().collect();\n        vec.sort_by_key(|r| r.0.id);\n        vec.iter_mut().for_each(|r| r.1.sort_by_key(|p| p.id));\n        Ok(vec)\n    }\n\n    pub fn list_role_permissions_by_resources(\n        &self,\n        role_id: RoleId,\n    ) -> Result<RbacPermissionsByResources, Error> {\n        self.group_permissions_by_resources(\n            self.role_permissions\n                .get(&role_id)\n                .ok_or_else(|| Error::RoleNotFound(format!(\"{role_id:?}\")))?\n                .iter()\n                .map(|(p, r)| (*r, *p)),\n        )\n    }\n\n    pub fn user_can<P, R>(&self, user_id: UserId, permission: P, resource: R) -> Result<bool, Error>\n    where\n        P: Into<PermissionRequest>,\n        R: Into<ResourceRequest>,\n    {\n        let resource = resource.into();\n        let permission = permission.into();\n        let resource = self.resources.get(&resource);\n        let permission = self.permissions.get(&permission);\n\n        // get user roles and flatten hierarchy\n        let user_roles = self.get_user_role_ids(&user_id)?;\n\n        if let (Some(permission), Some(resource)) = (permission, resource) {\n            if let Some(user_overrides) = self.user_overrides.get(&user_id) {\n                for user_override in user_overrides {\n                    if user_override.permission_id == permission.id\n                        && user_override.resource_id == resource.id\n                    {\n                        return Ok(user_override.grant);\n                    }\n                }\n            }\n        }\n\n        for role_id in user_roles {\n            if let Some(role_permissions) = self.role_permissions.get(&role_id) {\n                if let (Some(permission), Some(resource)) = (permission, resource) {\n                    if role_permissions.contains(&(permission.id, resource.id)) {\n                        return Ok(true);\n                    }\n                }\n                for (permission_id, resource_id) in role_permissions {\n                    let is_wildcard_permission =\n                        self.is_wildcard_permission(*permission_id, permission);\n                    let is_wildcard_resource = self.is_wildcard_resource(*resource_id, resource);\n                    if let Some(resource) = &resource {\n                        if resource_id == &resource.id && is_wildcard_permission {\n                            return Ok(true);\n                        }\n                    }\n                    if let Some(permission) = &permission {\n                        if permission_id == &permission.id && is_wildcard_resource {\n                            return Ok(true);\n                        }\n                    }\n                    if is_wildcard_permission && is_wildcard_resource {\n                        return Ok(true);\n                    }\n                }\n            }\n        }\n\n        if resource.is_none() {\n            return Err(Error::ResourceNotFound(format!(\"{resource:?}\")));\n        }\n\n        if permission.is_none() {\n            return Err(Error::PermissionNotFound(format!(\"{permission:?}\")));\n        }\n\n        Ok(false)\n    }\n\n    fn is_wildcard_resource(&self, id: ResourceId, target: Option<&Resource>) -> bool {\n        if let Some(resource) = self.wildcard_resources.get(&id) {\n            if let Some(target) = target {\n                let schema_match = resource.schema.is_none()\n                    || resource.schema.as_ref().unwrap() == WILDCARD\n                    || resource.schema == target.schema;\n                let table_match = resource.table == WILDCARD || resource.table == target.table;\n                schema_match && table_match\n            } else {\n                (resource.schema.is_none() || resource.schema.as_ref().unwrap() == WILDCARD)\n                    && resource.table == WILDCARD\n            }\n        } else {\n            false\n        }\n    }\n\n    fn is_wildcard_permission(&self, id: PermissionId, _: Option<&Permission>) -> bool {\n        if let Some(permission) = self.wildcard_permissions.get(&id) {\n            return permission.action == WILDCARD;\n        }\n        false\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[allow(non_snake_case)]\n    fn Object(r: &str) -> Table<'_> {\n        Table(r)\n    }\n\n    fn resource(table: &str) -> Resource {\n        Resource {\n            id: ResourceId(0),\n            schema: None,\n            table: table.to_owned(),\n        }\n    }\n\n    fn permission(action: &str) -> Permission {\n        Permission {\n            id: PermissionId(0),\n            action: action.to_owned(),\n        }\n    }\n\n    fn role(role: &str) -> Role {\n        Role {\n            id: RoleId(0),\n            role: role.to_owned(),\n        }\n    }\n\n    fn seed_1() -> RbacSnapshot {\n        let mut snapshot = RbacSnapshot::default();\n        snapshot.set_resources(vec![\n            resource(\"book\"),\n            resource(\"paper\"),\n            resource(\"pen\"),\n            resource(\"*\"),\n        ]);\n        snapshot.set_permissions(vec![\n            permission(\"browse\"),  // read\n            permission(\"buy\"),     // create\n            permission(\"replace\"), // update\n            permission(\"dispose\"), // delete\n            permission(\"*\"),       // anything\n        ]);\n        snapshot.set_roles(vec![\n            role(\"admin\"),\n            role(\"manager\"),\n            role(\"clerk\"),\n            role(\"auditor\"),\n        ]);\n        snapshot.set_user_role(UserId(1), \"admin\");\n        snapshot.set_user_role(UserId(2), \"manager\");\n        snapshot.set_user_role(UserId(3), \"clerk\");\n        snapshot.set_user_role(UserId(4), \"auditor\");\n        snapshot.set_user_role(UserId(5), \"clerk\");\n\n        snapshot.add_role_hierarchy(\"manager\", \"admin\");\n        snapshot.add_role_hierarchy(\"clerk\", \"manager\");\n        snapshot.add_role_hierarchy(\"auditor\", \"admin\");\n\n        snapshot.add_role_permission(\"clerk\", Action(\"browse\"), Object(\"pen\"));\n        snapshot.add_role_permission(\"clerk\", Action(\"browse\"), Object(\"paper\"));\n        snapshot.add_role_permission(\"clerk\", Action(\"dispose\"), Object(\"paper\"));\n\n        snapshot.add_role_permission(\"manager\", Action(\"browse\"), Object(\"book\"));\n        snapshot.add_role_permission(\"manager\", Action(\"buy\"), Object(\"book\"));\n        snapshot.add_role_permission(\"manager\", Action(\"dispose\"), Object(\"book\"));\n        snapshot.add_role_permission(\"manager\", Action(\"replace\"), Object(\"paper\"));\n\n        snapshot.add_role_permission(\"auditor\", Action(\"browse\"), Object(\"*\"));\n\n        snapshot.add_user_override(UserId(5), Action(\"buy\"), Object(\"pen\"), true);\n        snapshot.add_user_override(UserId(5), Action(\"dispose\"), Object(\"paper\"), false);\n\n        snapshot.add_role_permission(\"admin\", Action(\"*\"), Object(\"*\"));\n\n        snapshot\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_rbac_engine_basic() {\n        let admin = UserId(1);\n        let manager = UserId(2);\n        let clerk = UserId(3);\n        let auditor = UserId(4);\n        let designer = UserId(5);\n\n        let engine = RbacEngine::from_snapshot(seed_1());\n\n        // anyone can use pen and paper\n        for item in [\"pen\", \"paper\"] {\n            assert!(engine.user_can(clerk, Action(\"browse\"), Object(item)).unwrap());\n            assert!(engine.user_can(manager, Action(\"browse\"), Object(item)).unwrap());\n            assert!(engine.user_can(admin, Action(\"browse\"), Object(item)).unwrap());\n            // auditor can browse anything\n            assert!(engine.user_can(auditor, Action(\"browse\"), Object(item)).unwrap());\n        }\n\n        // anyone can dispose paper except auditor and designer\n        for user in [clerk, manager, admin] {\n            assert!(engine.user_can(user, Action(\"dispose\"), Object(\"paper\")).unwrap());\n        }\n        for user in [designer, auditor] {\n            assert!(!engine.user_can(user, Action(\"dispose\"), Object(\"paper\")).unwrap());\n        }\n\n        // clerk cannot browse books\n        for user in [clerk, designer] {\n            assert!(!engine.user_can(user, Action(\"browse\"), Object(\"book\")).unwrap());\n        }\n\n        for user in [admin, manager] {\n            assert!(engine.user_can(user, Action(\"browse\"), Object(\"book\")).unwrap());\n            assert!(engine.user_can(user, Action(\"buy\"), Object(\"book\")).unwrap());\n            assert!(engine.user_can(user, Action(\"dispose\"), Object(\"book\")).unwrap());\n        }\n\n        // auditor cannot alter things\n        for action in [\"buy\", \"replace\", \"dispose\"] {\n            for item in [\"book\", \"paper\", \"pen\"] {\n                assert!(!engine.user_can(auditor, Action(action), Object(item)).unwrap());\n            }\n        }\n\n        // manager cannot replace books, but admin can\n        assert!(!engine.user_can(manager, Action(\"replace\"), Object(\"book\")).unwrap());\n        assert!(engine.user_can(admin, Action(\"replace\"), Object(\"book\")).unwrap());\n\n        // manager can replace paper\n        assert!(!engine.user_can(clerk, Action(\"replace\"), Object(\"paper\")).unwrap());\n        assert!(!engine.user_can(designer, Action(\"replace\"), Object(\"paper\")).unwrap());\n        assert!(engine.user_can(manager, Action(\"replace\"), Object(\"paper\")).unwrap());\n        assert!(engine.user_can(admin, Action(\"replace\"), Object(\"paper\")).unwrap());\n\n        // only admin can buy paper\n        for user in [clerk, manager, designer] {\n            assert!(!engine.user_can(user, Action(\"buy\"), Object(\"paper\")).unwrap());\n        }\n        assert!(engine.user_can(admin, Action(\"buy\"), Object(\"paper\")).unwrap());\n\n        // designer has an exception can buy pen\n        for user in [designer, admin] {\n            assert!(engine.user_can(user, Action(\"buy\"), Object(\"pen\")).unwrap());\n        }\n        for user in [clerk, manager] {\n            assert!(!engine.user_can(user, Action(\"buy\"), Object(\"pen\")).unwrap());\n        }\n\n        // only admin can replace / dispose pen\n        for action in [\"replace\", \"dispose\"] {\n            assert!(engine.user_can(admin, Action(action), Object(\"pen\")).unwrap());\n        }\n\n        // unknown action / object; admin has wildcard\n        assert!(engine.user_can(admin, Action(\"?\"), Object(\"?\")).is_ok());\n        assert!(engine.user_can(manager, Action(\"?\"), Object(\"?\")).is_err());\n        assert!(engine.user_can(clerk, Action(\"?\"), Object(\"?\")).is_err());\n\n        assert_eq!(engine.get_user_role_permissions(clerk).unwrap(), RbacUserRolePermissions {\n            role: Role {\n                id: RoleId(3),\n                role: \"clerk\".to_owned(),\n            },\n            resource_permissions: vec![\n                (\n                    Resource { id: ResourceId(2), schema: None, table: \"paper\".to_owned() },\n                    vec![\n                        Permission { id: PermissionId(1), action: \"browse\".to_owned() },\n                        Permission { id: PermissionId(4), action: \"dispose\".to_owned() },\n                    ]\n                ),\n                (\n                    Resource { id: ResourceId(3), schema: None, table: \"pen\".to_owned() },\n                    vec![Permission { id: PermissionId(1), action: \"browse\".to_owned() }]\n                ),\n            ],\n        });\n\n        assert_eq!(engine.get_user_role_permissions(designer).unwrap(), RbacUserRolePermissions {\n            role: Role {\n                id: RoleId(3),\n                role: \"clerk\".to_owned(),\n            },\n            resource_permissions: vec![\n                (\n                    Resource { id: ResourceId(2), schema: None, table: \"paper\".to_owned() },\n                    vec![Permission { id: PermissionId(1), action: \"browse\".to_owned() }]\n                ),\n                (\n                    Resource { id: ResourceId(3), schema: None, table: \"pen\".to_owned() },\n                    vec![\n                        Permission { id: PermissionId(1), action: \"browse\".to_owned() },\n                        Permission { id: PermissionId(2), action: \"buy\".to_owned() },\n                    ]\n                ),\n            ],\n        });\n\n        assert_eq!(engine.get_roles_and_ranks().unwrap(), vec![\n            (Role { id: RoleId(1), role: \"admin\".to_owned()   }, 4), // <- manager | auditor\n            (Role { id: RoleId(2), role: \"manager\".to_owned() }, 2), // <- clerk\n            (Role { id: RoleId(3), role: \"clerk\".to_owned()   }, 1), //\n            (Role { id: RoleId(4), role: \"auditor\".to_owned() }, 1), //\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(1)), vec![\n            RoleHierarchy { super_role_id: RoleId(1), role_id: RoleId(2) },\n            RoleHierarchy { super_role_id: RoleId(1), role_id: RoleId(4) },\n            RoleHierarchy { super_role_id: RoleId(2), role_id: RoleId(3) },\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(2)), vec![\n            RoleHierarchy { super_role_id: RoleId(2), role_id: RoleId(3) },\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(3)), vec![]);\n\n        assert_eq!(engine.list_role_permissions_by_resources(RoleId(2)).unwrap(), vec![\n            (Resource { id: ResourceId(1), schema: None, table: \"book\".into() }, vec![\n                Permission { id: PermissionId(1), action: \"browse\".into() },\n                Permission { id: PermissionId(2), action: \"buy\".into() },\n                Permission { id: PermissionId(4), action: \"dispose\".into() },\n            ]),\n            (Resource { id: ResourceId(2), schema: None, table: \"paper\".into() }, vec![\n                Permission { id: PermissionId(3), action: \"replace\".into() },\n            ]),\n        ]);\n\n        assert_eq!(engine.list_role_permissions_by_resources(RoleId(4)).unwrap(), vec![\n            (Resource { id: ResourceId(4), schema: None, table: \"*\".into() }, vec![\n                Permission { id: PermissionId(1), action: \"browse\".into() },\n            ]),\n        ]);\n    }\n\n    #[rustfmt::skip]\n    fn seed_2() -> RbacSnapshot {\n        fn resource(schema: &str, table: &str) -> Resource {\n            Resource {\n                id: ResourceId(0),\n                schema: Some(schema.to_owned()),\n                table: table.to_owned(),\n            }\n        }\n\n        let mut snapshot = RbacSnapshot::default();\n        snapshot.set_resources(vec![\n            resource(\"departmentA\", \"book\"),\n            resource(\"departmentB\", \"book\"),\n            resource(\"departmentB\", \"CD\"),\n            resource(\"*\", \"book\"),\n            resource(\"departmentB\", \"*\"),\n            resource(\"*\", \"*\"),\n        ]);\n        snapshot.set_permissions(vec![\n            permission(\"browse\"),\n        ]);\n        snapshot.set_roles(vec![\n            role(\"silver\"),\n            role(\"gold\"),\n            role(\"platinum\"),\n            role(\"reader\"),\n            role(\"admin\"),\n        ]);\n        snapshot.set_user_role(UserId(1), \"silver\");\n        snapshot.set_user_role(UserId(2), \"gold\");\n        snapshot.set_user_role(UserId(3), \"platinum\");\n        snapshot.set_user_role(UserId(4), \"reader\");\n        snapshot.set_user_role(UserId(5), \"admin\");\n\n        snapshot.add_role_permission(\"silver\", Action(\"browse\"), SchemaTable(\"departmentA\", \"book\"));\n        snapshot.add_role_permission(\"gold\", Action(\"browse\"), SchemaTable(\"departmentB\", \"book\"));\n        snapshot.add_role_permission(\"platinum\", Action(\"browse\"), SchemaTable(\"departmentA\", \"book\"));\n        snapshot.add_role_permission(\"platinum\", Action(\"browse\"), SchemaTable(\"departmentB\", \"*\"));\n\n        snapshot.add_role_permission(\"reader\", Action(\"browse\"), SchemaTable(\"*\", \"book\"));\n\n        snapshot.add_role_permission(\"admin\", Action(\"browse\"), SchemaTable(\"*\", \"*\"));\n\n        snapshot\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    fn test_rbac_engine_wildcard() {\n        let silver = UserId(1);\n        let gold = UserId(2);\n        let platinum = UserId(3);\n        let reader = UserId(4);\n        let admin = UserId(5);\n\n        let engine = RbacEngine::from_snapshot(seed_2());\n\n        assert!(engine.user_can(silver, Action(\"browse\"), SchemaTable(\"departmentA\", \"book\")).unwrap());\n        assert!(!engine.user_can(silver, Action(\"browse\"), SchemaTable(\"departmentB\", \"book\")).unwrap());\n        assert!(!engine.user_can(silver, Action(\"browse\"), SchemaTable(\"departmentB\", \"CD\")).unwrap());\n\n        assert!(!engine.user_can(gold, Action(\"browse\"), SchemaTable(\"departmentA\", \"book\")).unwrap());\n        assert!(engine.user_can(gold, Action(\"browse\"), SchemaTable(\"departmentB\", \"book\")).unwrap());\n        assert!(!engine.user_can(gold, Action(\"browse\"), SchemaTable(\"departmentB\", \"CD\")).unwrap());\n\n        assert!(engine.user_can(platinum, Action(\"browse\"), SchemaTable(\"departmentA\", \"book\")).unwrap());\n        assert!(engine.user_can(platinum, Action(\"browse\"), SchemaTable(\"departmentB\", \"book\")).unwrap());\n        assert!(engine.user_can(platinum, Action(\"browse\"), SchemaTable(\"departmentB\", \"CD\")).unwrap());\n\n        assert!(engine.user_can(reader, Action(\"browse\"), SchemaTable(\"departmentA\", \"book\")).unwrap());\n        assert!(engine.user_can(reader, Action(\"browse\"), SchemaTable(\"departmentB\", \"book\")).unwrap());\n        assert!(!engine.user_can(reader, Action(\"browse\"), SchemaTable(\"departmentB\", \"CD\")).unwrap());\n\n        assert!(engine.user_can(admin, Action(\"browse\"), SchemaTable(\"departmentA\", \"book\")).unwrap());\n        assert!(engine.user_can(admin, Action(\"browse\"), SchemaTable(\"departmentB\", \"book\")).unwrap());\n        assert!(engine.user_can(admin, Action(\"browse\"), SchemaTable(\"departmentB\", \"CD\")).unwrap());\n    }\n\n    #[rustfmt::skip]\n    fn seed_3() -> RbacSnapshot {\n        let mut snapshot = RbacSnapshot::default();\n        snapshot.set_resources(vec![\n            resource(\"book\"),\n            resource(\"CD\"),\n            resource(\"magazine\"),\n        ]);\n        snapshot.set_permissions(vec![\n            permission(\"browse\"),\n        ]);\n        snapshot.set_roles(vec![\n            role(\"A\"),\n            role(\"B\"),\n            role(\"C\"),\n            role(\"A+B\"),\n            role(\"A+C\"),\n            role(\"A+B+C\"),\n            role(\"(A+B)+C\"),\n        ]);\n        snapshot.set_user_role(UserId(1), \"A\");\n        snapshot.set_user_role(UserId(2), \"B\");\n        snapshot.set_user_role(UserId(3), \"C\");\n        snapshot.set_user_role(UserId(4), \"A+B\");\n        snapshot.set_user_role(UserId(5), \"A+C\");\n        snapshot.set_user_role(UserId(6), \"A+B+C\");\n        snapshot.set_user_role(UserId(7), \"(A+B)+C\");\n\n        snapshot.add_role_permission(\"A\", Action(\"browse\"), Object(\"book\"));\n        snapshot.add_role_permission(\"B\", Action(\"browse\"), Object(\"CD\"));\n        snapshot.add_role_permission(\"C\", Action(\"browse\"), Object(\"magazine\"));\n\n        snapshot.add_role_hierarchy(\"A\", \"A+B\");\n        snapshot.add_role_hierarchy(\"B\", \"A+B\");\n\n        snapshot.add_role_hierarchy(\"A\", \"A+C\");\n        snapshot.add_role_hierarchy(\"C\", \"A+C\");\n\n        snapshot.add_role_hierarchy(\"A\", \"A+B+C\");\n        snapshot.add_role_hierarchy(\"B\", \"A+B+C\");\n        snapshot.add_role_hierarchy(\"C\", \"A+B+C\");\n\n        snapshot.add_role_hierarchy(\"A+B\", \"(A+B)+C\");\n        snapshot.add_role_hierarchy(\"C\", \"(A+B)+C\");\n\n        snapshot\n    }\n\n    #[test]\n    #[rustfmt::skip]\n    #[allow(non_snake_case)]\n    fn test_rbac_engine_hierarchy() {\n        let A = UserId(1);\n        let B = UserId(2);\n        let C = UserId(3);\n        let A_B = UserId(4);\n        let A_C = UserId(5);\n        let A_B_C = UserId(6);\n        let A_B_C_ = UserId(7);\n\n        let engine = RbacEngine::from_snapshot(seed_3());\n\n        assert!(engine.user_can(A, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(!engine.user_can(A, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(!engine.user_can(A, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert!(!engine.user_can(B, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(engine.user_can(B, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(!engine.user_can(B, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert!(!engine.user_can(C, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(!engine.user_can(C, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(engine.user_can(C, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert!(engine.user_can(A_B, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(engine.user_can(A_B, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(!engine.user_can(A_B, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert!(engine.user_can(A_C, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(!engine.user_can(A_C, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(engine.user_can(A_C, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert!(engine.user_can(A_B_C, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(engine.user_can(A_B_C, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(engine.user_can(A_B_C, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert!(engine.user_can(A_B_C_, Action(\"browse\"), Object(\"book\")).unwrap());\n        assert!(engine.user_can(A_B_C_, Action(\"browse\"), Object(\"CD\")).unwrap());\n        assert!(engine.user_can(A_B_C_, Action(\"browse\"), Object(\"magazine\")).unwrap());\n\n        assert_eq!(engine.get_roles_and_ranks().unwrap(), vec![\n            (Role { id: RoleId(7), role: \"(A+B)+C\".into() }, 5),\n            (Role { id: RoleId(6), role: \"A+B+C\".into() }, 4),\n            (Role { id: RoleId(4), role: \"A+B\".into() }, 3),\n            (Role { id: RoleId(5), role: \"A+C\".into() }, 3),\n            (Role { id: RoleId(1), role: \"A\".into() }, 1),\n            (Role { id: RoleId(2), role: \"B\".into() }, 1),\n            (Role { id: RoleId(3), role: \"C\".into() }, 1),\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(1)), vec![]);\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(2)), vec![]);\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(3)), vec![]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(4)), vec![\n            RoleHierarchy { super_role_id: RoleId(4), role_id: RoleId(1) },\n            RoleHierarchy { super_role_id: RoleId(4), role_id: RoleId(2) },\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(5)), vec![\n            RoleHierarchy { super_role_id: RoleId(5), role_id: RoleId(1) },\n            RoleHierarchy { super_role_id: RoleId(5), role_id: RoleId(3) },\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(6)), vec![\n            RoleHierarchy { super_role_id: RoleId(6), role_id: RoleId(1) },\n            RoleHierarchy { super_role_id: RoleId(6), role_id: RoleId(2) },\n            RoleHierarchy { super_role_id: RoleId(6), role_id: RoleId(3) },\n        ]);\n\n        assert_eq!(engine.list_role_hierarchy_edges(RoleId(7)), vec![\n            RoleHierarchy { super_role_id: RoleId(7), role_id: RoleId(4) },\n            RoleHierarchy { super_role_id: RoleId(7), role_id: RoleId(3) },\n            RoleHierarchy { super_role_id: RoleId(4), role_id: RoleId(1) },\n            RoleHierarchy { super_role_id: RoleId(4), role_id: RoleId(2) },\n        ]);\n    }\n\n    #[test]\n    fn test_unrestricted() {\n        let engine = RbacEngine::from_snapshot(RbacSnapshot::danger_unrestricted());\n        assert!(\n            engine\n                .user_can(UserId(0), Action(\"browse\"), Object(\"book\"))\n                .unwrap()\n        );\n        assert_eq!(\n            engine.get_user_role_permissions(UserId(0)).unwrap(),\n            RbacUserRolePermissions {\n                role: Role {\n                    id: RoleId(1),\n                    role: \"unrestricted\".to_owned(),\n                },\n                resource_permissions: vec![(\n                    Resource {\n                        id: ResourceId(1),\n                        schema: None,\n                        table: \"*\".to_owned(),\n                    },\n                    vec![Permission {\n                        id: PermissionId(1),\n                        action: \"*\".to_owned(),\n                    }]\n                ),],\n            }\n        );\n    }\n}\n"
  },
  {
    "path": "src/rbac/engine/permission_request.rs",
    "content": "use crate::rbac::entity::permission::Model as Permission;\n\n#[derive(Debug)]\npub struct Action<'a>(pub &'a str);\n\n#[derive(Debug, Clone, PartialEq, Eq, Hash)]\npub struct PermissionRequest {\n    pub action: String,\n}\n\nimpl<'a> From<Action<'a>> for PermissionRequest {\n    fn from(action: Action<'a>) -> PermissionRequest {\n        PermissionRequest {\n            action: action.0.to_owned(),\n        }\n    }\n}\n\nimpl From<Permission> for PermissionRequest {\n    fn from(permission: Permission) -> Self {\n        Self {\n            action: permission.action,\n        }\n    }\n}\n"
  },
  {
    "path": "src/rbac/engine/resource_request.rs",
    "content": "use crate::rbac::entity::resource::Model as Resource;\n\n#[derive(Debug)]\npub struct Table<'a>(pub &'a str);\n\n#[derive(Debug)]\npub struct SchemaTable<'a, 'b>(pub &'a str, pub &'b str);\n\n#[derive(Debug, Clone, PartialEq, Eq, Hash)]\npub struct ResourceRequest {\n    pub schema: Option<String>,\n    pub table: String,\n}\n\nimpl<'a> From<Table<'a>> for ResourceRequest {\n    fn from(table: Table<'a>) -> ResourceRequest {\n        ResourceRequest {\n            schema: None,\n            table: table.0.to_owned(),\n        }\n    }\n}\n\nimpl<'a, 'b> From<SchemaTable<'a, 'b>> for ResourceRequest {\n    fn from(schema_table: SchemaTable<'a, 'b>) -> ResourceRequest {\n        ResourceRequest {\n            schema: Some(schema_table.0.to_owned()),\n            table: schema_table.1.to_owned(),\n        }\n    }\n}\n\nimpl From<Resource> for ResourceRequest {\n    fn from(resource: Resource) -> Self {\n        Self {\n            schema: resource.schema,\n            table: resource.table,\n        }\n    }\n}\n\nimpl std::fmt::Display for ResourceRequest {\n    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n        write!(\n            f,\n            \"{}{}{}\",\n            if let Some(schema) = &self.schema {\n                schema\n            } else {\n                \"\"\n            },\n            if self.schema.is_some() { \".\" } else { \"\" },\n            self.table\n        )\n    }\n}\n"
  },
  {
    "path": "src/rbac/engine/role_hierarchy_impl.rs",
    "content": "use super::{RoleHierarchy, RoleId};\nuse std::collections::{HashMap, HashSet, VecDeque};\n\n/// Role -> [ChildRole]\npub type RoleHierarchyMap = HashMap<RoleId, Vec<RoleId>>;\n\n/// walk the hierarchy tree and enumerate all the children roles given a role.\n/// this is a non-recursive tree walk impl.\npub fn enumerate_role(role: RoleId, role_hierarchy: &RoleHierarchyMap) -> Vec<RoleId> {\n    let mut roles = Vec::new();\n    let mut queue = VecDeque::new();\n    let mut seen = HashSet::new();\n\n    queue.push_back(role);\n    seen.insert(role);\n\n    while let Some(role) = queue.pop_front() {\n        roles.push(role);\n        if let Some(children) = role_hierarchy.get(&role) {\n            for child in children {\n                if !seen.contains(child) {\n                    queue.push_back(*child);\n                }\n            }\n        }\n    }\n\n    roles\n}\n\n/// walk the hierarchy tree and enumerate all the children roles given a role.\n/// return the edges instead.\npub fn list_role_hierarchy_edges(\n    role: RoleId,\n    role_hierarchy: &RoleHierarchyMap,\n) -> Vec<RoleHierarchy> {\n    let mut edges = Vec::new();\n    let mut roles = Vec::new();\n    let mut queue = VecDeque::new();\n    let mut seen = HashSet::new();\n\n    queue.push_back(role);\n    seen.insert(role);\n\n    while let Some(role) = queue.pop_front() {\n        roles.push(role);\n        if let Some(children) = role_hierarchy.get(&role) {\n            for child in children {\n                if !seen.contains(child) {\n                    queue.push_back(*child);\n                }\n                edges.push(RoleHierarchy {\n                    super_role_id: role,\n                    role_id: *child,\n                });\n            }\n        }\n    }\n\n    edges\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n\n    #[test]\n    fn test_enumerate_role() {\n        let role_hierarchy = [\n            (RoleId(1), vec![RoleId(2)]),\n            (RoleId(2), vec![RoleId(3), RoleId(4)]),\n            (RoleId(4), vec![RoleId(5)]),\n            (RoleId(6), vec![]),\n        ]\n        .into_iter()\n        .collect();\n\n        assert_eq!(\n            enumerate_role(RoleId(1), &role_hierarchy),\n            [RoleId(1), RoleId(2), RoleId(3), RoleId(4), RoleId(5)]\n        );\n        assert_eq!(\n            enumerate_role(RoleId(2), &role_hierarchy),\n            [RoleId(2), RoleId(3), RoleId(4), RoleId(5)]\n        );\n        assert_eq!(enumerate_role(RoleId(3), &role_hierarchy), [RoleId(3)]);\n        assert_eq!(\n            enumerate_role(RoleId(4), &role_hierarchy),\n            [RoleId(4), RoleId(5)]\n        );\n        assert_eq!(enumerate_role(RoleId(5), &role_hierarchy), [RoleId(5)]);\n        assert_eq!(enumerate_role(RoleId(6), &role_hierarchy), [RoleId(6)]);\n        assert_eq!(enumerate_role(RoleId(7), &role_hierarchy), [RoleId(7)]);\n    }\n\n    #[test]\n    fn test_enumerate_role_cyclic() {\n        let role_hierarchy = [\n            (RoleId(1), vec![RoleId(2)]),\n            (RoleId(2), vec![RoleId(3)]),\n            (RoleId(3), vec![RoleId(1), RoleId(4)]),\n        ]\n        .into_iter()\n        .collect();\n\n        assert_eq!(\n            enumerate_role(RoleId(1), &role_hierarchy),\n            [RoleId(1), RoleId(2), RoleId(3), RoleId(4)]\n        );\n        assert_eq!(\n            enumerate_role(RoleId(2), &role_hierarchy),\n            [RoleId(2), RoleId(3), RoleId(1), RoleId(4)]\n        );\n        assert_eq!(\n            enumerate_role(RoleId(3), &role_hierarchy),\n            [RoleId(3), RoleId(1), RoleId(4), RoleId(2)]\n        );\n        assert_eq!(enumerate_role(RoleId(4), &role_hierarchy), [RoleId(4)]);\n    }\n}\n"
  },
  {
    "path": "src/rbac/engine/snapshot.rs",
    "content": "use super::*;\n\n#[derive(Debug, Default)]\npub struct RbacSnapshot {\n    pub(super) resources: Vec<Resource>,\n    pub(super) permissions: Vec<Permission>,\n    pub(super) roles: Vec<Role>,\n    pub(super) user_roles: Vec<UserRole>,\n    pub(super) role_permissions: Vec<RolePermission>,\n    pub(super) user_overrides: Vec<UserOverride>,\n    pub(super) role_hierarchy: Vec<RoleHierarchy>,\n}\n\nimpl RbacSnapshot {\n    /// Create an unrestricted system where `UserId(0)` can perform any action on any resource.\n    /// This is intended to be an escape hatch to bypass RBAC restrictions.\n    /// Use at your own risk.\n    pub fn danger_unrestricted() -> Self {\n        let mut snapshot = Self::default();\n\n        snapshot.set_resources(vec![Resource {\n            id: ResourceId(0),\n            schema: None,\n            table: WILDCARD.to_owned(),\n        }]);\n        snapshot.set_permissions(vec![Permission {\n            id: PermissionId(0),\n            action: WILDCARD.to_owned(),\n        }]);\n        snapshot.set_roles(vec![Role {\n            id: RoleId(0),\n            role: \"unrestricted\".to_owned(),\n        }]);\n        snapshot.set_user_role(UserId(0), \"unrestricted\");\n        snapshot.add_role_permission(\"unrestricted\", Action(\"*\"), Table(\"*\"));\n\n        snapshot\n    }\n\n    pub(super) fn set_resources(&mut self, mut resources: Vec<Resource>) {\n        for (i, r) in resources.iter_mut().enumerate() {\n            r.id = ResourceId(i as i64 + 1);\n        }\n        self.resources = resources;\n    }\n\n    pub(super) fn set_permissions(&mut self, mut permissions: Vec<Permission>) {\n        for (i, r) in permissions.iter_mut().enumerate() {\n            r.id = PermissionId(i as i64 + 1);\n        }\n        self.permissions = permissions;\n    }\n\n    pub(super) fn set_roles(&mut self, mut roles: Vec<Role>) {\n        for (i, r) in roles.iter_mut().enumerate() {\n            r.id = RoleId(i as i64 + 1);\n        }\n        self.roles = roles;\n    }\n\n    pub(super) fn set_user_role(&mut self, user_id: UserId, role: &str) {\n        self.user_roles.push(UserRole {\n            user_id,\n            role_id: self.find_role(role),\n        });\n    }\n\n    pub(super) fn add_role_permission<P, R>(&mut self, role: &str, permission: P, resource: R)\n    where\n        P: Into<PermissionRequest>,\n        R: Into<ResourceRequest>,\n    {\n        let permission = permission.into();\n        let resource = resource.into();\n        let role_id = self.find_role(role);\n        self.role_permissions.push(RolePermission {\n            role_id,\n            permission_id: self.find_permission(&permission),\n            resource_id: self.find_resource(&resource),\n        });\n    }\n\n    #[cfg(test)]\n    pub(super) fn add_user_override<P, R>(\n        &mut self,\n        user_id: UserId,\n        permission: P,\n        resource: R,\n        grant: bool,\n    ) where\n        P: Into<PermissionRequest>,\n        R: Into<ResourceRequest>,\n    {\n        let permission = permission.into();\n        let resource = resource.into();\n        self.user_overrides.push(UserOverride {\n            user_id,\n            permission_id: self.find_permission(&permission),\n            resource_id: self.find_resource(&resource),\n            grant,\n        });\n    }\n\n    #[cfg(test)]\n    pub(super) fn add_role_hierarchy(&mut self, role: &str, super_role: &str) {\n        self.role_hierarchy.push(RoleHierarchy {\n            role_id: self.find_role(role),\n            super_role_id: self.find_role(super_role),\n        })\n    }\n\n    pub(super) fn find_role(&self, role: &str) -> RoleId {\n        self.roles.iter().find(|r| r.role == role).unwrap().id\n    }\n\n    pub(super) fn find_permission(&self, permission: &PermissionRequest) -> PermissionId {\n        self.permissions\n            .iter()\n            .find(|r| r.action == permission.action)\n            .unwrap()\n            .id\n    }\n\n    pub(super) fn find_resource(&self, resource: &ResourceRequest) -> ResourceId {\n        self.resources\n            .iter()\n            .find(|r| r.schema == resource.schema && r.table == resource.table)\n            .unwrap()\n            .id\n    }\n}\n"
  },
  {
    "path": "src/rbac/entity/mod.rs",
    "content": "pub mod permission;\npub mod resource;\npub mod role;\npub mod role_hierarchy;\npub mod role_permission;\npub mod user;\npub mod user_override;\npub mod user_role;\n"
  },
  {
    "path": "src/rbac/entity/permission.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::DeriveValueType;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_permission\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: PermissionId,\n    #[sea_orm(unique)]\n    pub action: String,\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, DeriveValueType)]\npub struct PermissionId(pub i64);\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/rbac/entity/resource.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::DeriveValueType;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_resource\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: ResourceId,\n    #[sea_orm(unique_group = \"1\")]\n    pub schema: Option<String>,\n    #[sea_orm(unique_group = \"1\")]\n    pub table: String,\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, DeriveValueType)]\npub struct ResourceId(pub i64);\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/rbac/entity/role.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::DeriveValueType;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_role\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: RoleId,\n    #[sea_orm(unique)]\n    pub role: String,\n}\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, DeriveValueType)]\npub struct RoleId(pub i64);\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/rbac/entity/role_hierarchy.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\nuse super::role::RoleId;\n\n#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_role_hierarchy\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub super_role_id: RoleId,\n    #[sea_orm(primary_key)]\n    pub role_id: RoleId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::role::Entity\",\n        from = \"Column::RoleId\",\n        to = \"super::role::Column::Id\"\n    )]\n    Role,\n    #[sea_orm(\n        belongs_to = \"super::role::Entity\",\n        from = \"Column::SuperRoleId\",\n        to = \"super::role::Column::Id\"\n    )]\n    SuperRole,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/rbac/entity/role_permission.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\nuse super::{permission::PermissionId, resource::ResourceId, role::RoleId};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_role_permission\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub role_id: RoleId,\n    #[sea_orm(primary_key)]\n    pub permission_id: PermissionId,\n    #[sea_orm(primary_key)]\n    pub resource_id: ResourceId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::role::Entity\",\n        from = \"Column::RoleId\",\n        to = \"super::role::Column::Id\"\n    )]\n    Role,\n    #[sea_orm(\n        belongs_to = \"super::permission::Entity\",\n        from = \"Column::PermissionId\",\n        to = \"super::permission::Column::Id\"\n    )]\n    Permission,\n    #[sea_orm(\n        belongs_to = \"super::resource::Entity\",\n        from = \"Column::ResourceId\",\n        to = \"super::resource::Column::Id\"\n    )]\n    Resource,\n}\n\nimpl Related<super::role::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Role.def()\n    }\n}\n\nimpl Related<super::permission::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Permission.def()\n    }\n}\n\nimpl Related<super::resource::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Resource.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/rbac/entity/user.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::DeriveValueType;\n\n#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, DeriveValueType)]\npub struct UserId(pub i64);\n"
  },
  {
    "path": "src/rbac/entity/user_override.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\nuse super::{permission::PermissionId, resource::ResourceId, user::UserId};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_user_override\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub user_id: UserId,\n    #[sea_orm(primary_key)]\n    pub permission_id: PermissionId,\n    #[sea_orm(primary_key)]\n    pub resource_id: ResourceId,\n    /// true to allow, false to deny\n    pub grant: bool,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::permission::Entity\",\n        from = \"Column::PermissionId\",\n        to = \"super::permission::Column::Id\"\n    )]\n    Permission,\n    #[sea_orm(\n        belongs_to = \"super::resource::Entity\",\n        from = \"Column::ResourceId\",\n        to = \"super::resource::Column::Id\"\n    )]\n    Resource,\n}\n\nimpl Related<super::permission::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Permission.def()\n    }\n}\n\nimpl Related<super::resource::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Resource.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/rbac/entity/user_role.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\nuse super::{role::RoleId, user::UserId};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"sea_orm_user_role\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub user_id: UserId,\n    pub role_id: RoleId,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::role::Entity\",\n        from = \"Column::RoleId\",\n        to = \"super::role::Column::Id\"\n    )]\n    Role,\n}\n\nimpl Related<super::role::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Role.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/rbac/error.rs",
    "content": "use thiserror::Error;\n\n/// An error from unsuccessful database operations\n#[derive(Error, Debug, Clone, PartialEq, Eq)]\npub enum Error {\n    /// Resource not found\n    #[error(\"Resource Not Found: {0}\")]\n    ResourceNotFound(String),\n    /// Permission not found\n    #[error(\"Permission Not Found: {0}\")]\n    PermissionNotFound(String),\n    /// Role not found\n    #[error(\"Role Not Found: {0}\")]\n    RoleNotFound(String),\n    /// User not found\n    #[error(\"User Not Found: {0}\")]\n    UserNotFound(String),\n}\n"
  },
  {
    "path": "src/rbac/mod.rs",
    "content": "#![allow(missing_docs)]\n\nmod engine;\npub use engine::*;\n\npub mod entity;\npub use entity::user::UserId as RbacUserId;\n\npub mod context;\npub use context::*;\n\nmod error;\npub use error::Error as RbacError;\nuse error::*;\n\npub mod schema;\n\n/// This could be used to denote any permission or any resources.\npub const WILDCARD: &str = \"*\";\n\npub use sea_query::audit::{AccessType, SchemaOper};\n"
  },
  {
    "path": "src/rbac/schema.rs",
    "content": "use super::entity;\nuse crate::{ConnectionTrait, DbErr, EntityTrait, ExecResult, RelationDef, Schema};\n\n#[derive(Debug, Default)]\npub struct RbacCreateTablesParams {\n    pub user_override_relation: Option<RelationDef>,\n    pub user_role_relation: Option<RelationDef>,\n}\n\n/// Create RBAC tables, will currently fail if any of them already exsits\npub async fn create_tables<C: ConnectionTrait>(\n    db: &C,\n    RbacCreateTablesParams {\n        user_override_relation,\n        user_role_relation,\n    }: RbacCreateTablesParams,\n) -> Result<(), DbErr> {\n    create_table(db, entity::permission::Entity, None).await?;\n    create_table(db, entity::resource::Entity, None).await?;\n    create_table(db, entity::role::Entity, None).await?;\n    create_table(db, entity::role_hierarchy::Entity, None).await?;\n    create_table(db, entity::role_permission::Entity, None).await?;\n    create_table(db, entity::user_override::Entity, user_override_relation).await?;\n    create_table(db, entity::user_role::Entity, user_role_relation).await?;\n\n    Ok(())\n}\n\n/// All tables associated with RBAC, created by SeaORM\npub fn all_tables() -> Vec<&'static str> {\n    use crate::EntityName;\n\n    vec![\n        entity::permission::Entity.table_name(),\n        entity::resource::Entity.table_name(),\n        entity::role::Entity.table_name(),\n        entity::role_hierarchy::Entity.table_name(),\n        entity::role_permission::Entity.table_name(),\n        entity::user_override::Entity.table_name(),\n        entity::user_role::Entity.table_name(),\n    ]\n}\n\nasync fn create_table<C, E>(\n    db: &C,\n    entity: E,\n    rel: Option<RelationDef>,\n) -> Result<ExecResult, DbErr>\nwhere\n    C: ConnectionTrait,\n    E: EntityTrait,\n{\n    let backend = db.get_database_backend();\n    let schema = Schema::new(backend);\n\n    let mut stmt = schema.create_table_from_entity(entity);\n    if let Some(rel) = rel {\n        stmt.foreign_key(&mut rel.into());\n    }\n    let res = db.execute(&stmt).await?;\n\n    for stmt in schema.create_index_from_entity(entity) {\n        db.execute(&stmt).await?;\n    }\n\n    Ok(res)\n}\n"
  },
  {
    "path": "src/schema/builder.rs",
    "content": "use super::{Schema, TopologicalSort};\nuse crate::{ConnectionTrait, DbBackend, DbErr, EntityTrait, Statement};\nuse sea_query::{\n    ForeignKeyCreateStatement, Index, IndexCreateStatement, IntoIden, TableAlterStatement,\n    TableCreateStatement, TableName, TableRef, extension::postgres::TypeCreateStatement,\n};\n\n/// A schema builder that can take a registry of Entities and synchronize it with database.\npub struct SchemaBuilder {\n    helper: Schema,\n    entities: Vec<EntitySchemaInfo>,\n}\n\n/// Schema info for Entity. Can be used to re-create schema in database.\npub struct EntitySchemaInfo {\n    table: TableCreateStatement,\n    enums: Vec<TypeCreateStatement>,\n    indexes: Vec<IndexCreateStatement>,\n}\n\nimpl std::fmt::Debug for SchemaBuilder {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"SchemaBuilder {{\")?;\n        write!(f, \" entities: [\")?;\n        for (i, entity) in self.entities.iter().enumerate() {\n            if i > 0 {\n                write!(f, \", \")?;\n            }\n            entity.debug_print(f, &self.helper.backend)?;\n        }\n        write!(f, \" ]\")?;\n        write!(f, \" }}\")\n    }\n}\n\nimpl std::fmt::Debug for EntitySchemaInfo {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        self.debug_print(f, &DbBackend::Sqlite)\n    }\n}\n\nimpl SchemaBuilder {\n    /// Creates a new schema builder\n    pub fn new(schema: Schema) -> Self {\n        Self {\n            helper: schema,\n            entities: Default::default(),\n        }\n    }\n\n    /// Register an entity to this schema\n    pub fn register<E: EntityTrait>(mut self, entity: E) -> Self {\n        let entity = EntitySchemaInfo::new(entity, &self.helper);\n        if !self\n            .entities\n            .iter()\n            .any(|e| e.table.get_table_name() == entity.table.get_table_name())\n        {\n            self.entities.push(entity);\n        }\n        self\n    }\n\n    #[cfg(feature = \"entity-registry\")]\n    pub(crate) fn helper(&self) -> &Schema {\n        &self.helper\n    }\n\n    #[cfg(feature = \"entity-registry\")]\n    pub(crate) fn register_entity(&mut self, entity: EntitySchemaInfo) {\n        self.entities.push(entity);\n    }\n\n    /// Synchronize the schema with database, will create missing tables, columns, unique keys, and foreign keys.\n    /// This operation is addition only, will not drop any table / columns.\n    #[cfg(feature = \"schema-sync\")]\n    #[cfg_attr(docsrs, doc(cfg(feature = \"schema-sync\")))]\n    pub async fn sync<C>(self, db: &C) -> Result<(), DbErr>\n    where\n        C: ConnectionTrait + sea_schema::Connection,\n    {\n        let _existing = match db.get_database_backend() {\n            #[cfg(feature = \"sqlx-mysql\")]\n            DbBackend::MySql => {\n                use sea_schema::{mysql::discovery::SchemaDiscovery, probe::SchemaProbe};\n\n                let current_schema: String = db\n                    .query_one(\n                        sea_query::SelectStatement::new()\n                            .expr(sea_schema::mysql::MySql::get_current_schema()),\n                    )\n                    .await?\n                    .ok_or_else(|| DbErr::RecordNotFound(\"Can't get current schema\".into()))?\n                    .try_get_by_index(0)?;\n                let schema_discovery = SchemaDiscovery::new_no_exec(&current_schema);\n\n                let schema = schema_discovery\n                    .discover_with(db)\n                    .await\n                    .map_err(|err| DbErr::Query(crate::RuntimeErr::SqlxError(err.into())))?;\n\n                DiscoveredSchema {\n                    tables: schema.tables.iter().map(|table| table.write()).collect(),\n                    enums: vec![],\n                }\n            }\n            #[cfg(feature = \"sqlx-postgres\")]\n            DbBackend::Postgres => {\n                use sea_schema::{postgres::discovery::SchemaDiscovery, probe::SchemaProbe};\n\n                let current_schema: String = db\n                    .query_one(\n                        sea_query::SelectStatement::new()\n                            .expr(sea_schema::postgres::Postgres::get_current_schema()),\n                    )\n                    .await?\n                    .ok_or_else(|| DbErr::RecordNotFound(\"Can't get current schema\".into()))?\n                    .try_get_by_index(0)?;\n                let schema_discovery = SchemaDiscovery::new_no_exec(&current_schema);\n\n                let schema = schema_discovery\n                    .discover_with(db)\n                    .await\n                    .map_err(|err| DbErr::Query(crate::RuntimeErr::SqlxError(err.into())))?;\n\n                DiscoveredSchema {\n                    tables: schema.tables.iter().map(|table| table.write()).collect(),\n                    enums: schema.enums.iter().map(|def| def.write()).collect(),\n                }\n            }\n            #[cfg(feature = \"sqlx-sqlite\")]\n            DbBackend::Sqlite => {\n                use sea_schema::sqlite::{SqliteDiscoveryError, discovery::SchemaDiscovery};\n                let schema = SchemaDiscovery::discover_with(db)\n                    .await\n                    .map_err(|err| {\n                        DbErr::Query(match err {\n                            SqliteDiscoveryError::SqlxError(err) => {\n                                crate::RuntimeErr::SqlxError(err.into())\n                            }\n                            _ => crate::RuntimeErr::Internal(format!(\"{err:?}\")),\n                        })\n                    })?\n                    .merge_indexes_into_table();\n                DiscoveredSchema {\n                    tables: schema.tables.iter().map(|table| table.write()).collect(),\n                    enums: vec![],\n                }\n            }\n            #[cfg(feature = \"rusqlite\")]\n            DbBackend::Sqlite => {\n                use sea_schema::sqlite::{SqliteDiscoveryError, discovery::SchemaDiscovery};\n                let schema = SchemaDiscovery::discover_with(db)\n                    .map_err(|err| {\n                        DbErr::Query(match err {\n                            SqliteDiscoveryError::RusqliteError(err) => {\n                                crate::RuntimeErr::Rusqlite(err.into())\n                            }\n                            _ => crate::RuntimeErr::Internal(format!(\"{err:?}\")),\n                        })\n                    })?\n                    .merge_indexes_into_table();\n                DiscoveredSchema {\n                    tables: schema.tables.iter().map(|table| table.write()).collect(),\n                    enums: vec![],\n                }\n            }\n            #[allow(unreachable_patterns)]\n            other => {\n                return Err(DbErr::BackendNotSupported {\n                    db: other.as_str(),\n                    ctx: \"SchemaBuilder::sync\",\n                });\n            }\n        };\n\n        #[allow(unreachable_code)]\n        let mut created_enums: Vec<Statement> = Default::default();\n\n        #[allow(unreachable_code)]\n        for table_name in self.sorted_tables() {\n            if let Some(entity) = self\n                .entities\n                .iter()\n                .find(|entity| table_name == get_table_name(entity.table.get_table_name()))\n            {\n                entity.sync(db, &_existing, &mut created_enums).await?;\n            }\n        }\n\n        Ok(())\n    }\n\n    /// Apply this schema to a database, will create all registered tables, columns, unique keys, and foreign keys.\n    /// Will fail if any table already exists. Use [`sync`] if you want an incremental version that can perform schema diff.\n    pub async fn apply<C: ConnectionTrait>(self, db: &C) -> Result<(), DbErr> {\n        let mut created_enums: Vec<Statement> = Default::default();\n\n        for table_name in self.sorted_tables() {\n            if let Some(entity) = self\n                .entities\n                .iter()\n                .find(|entity| table_name == get_table_name(entity.table.get_table_name()))\n            {\n                entity.apply(db, &mut created_enums).await?;\n            }\n        }\n\n        Ok(())\n    }\n\n    fn sorted_tables(&self) -> Vec<TableName> {\n        let mut sorter = TopologicalSort::<TableName>::new();\n\n        for entity in self.entities.iter() {\n            let table_name = get_table_name(entity.table.get_table_name());\n            sorter.insert(table_name);\n        }\n        for entity in self.entities.iter() {\n            let self_table = get_table_name(entity.table.get_table_name());\n            for fk in entity.table.get_foreign_key_create_stmts().iter() {\n                let fk = fk.get_foreign_key();\n                let ref_table = get_table_name(fk.get_ref_table());\n                if self_table != ref_table {\n                    // self cycle is okay\n                    sorter.add_dependency(ref_table, self_table.clone());\n                }\n            }\n        }\n        let mut sorted = Vec::new();\n        while let Some(i) = sorter.pop() {\n            sorted.push(i);\n        }\n        if sorted.len() != self.entities.len() {\n            // push leftover tables\n            for entity in self.entities.iter() {\n                let table_name = get_table_name(entity.table.get_table_name());\n                if !sorted.contains(&table_name) {\n                    sorted.push(table_name);\n                }\n            }\n        }\n\n        sorted\n    }\n}\n\nstruct DiscoveredSchema {\n    tables: Vec<TableCreateStatement>,\n    enums: Vec<TypeCreateStatement>,\n}\n\nimpl EntitySchemaInfo {\n    /// Creates a EntitySchemaInfo object given a generic Entity.\n    pub fn new<E: EntityTrait>(entity: E, helper: &Schema) -> Self {\n        Self {\n            table: helper.create_table_from_entity(entity),\n            enums: helper.create_enum_from_entity(entity),\n            indexes: helper.create_index_from_entity(entity),\n        }\n    }\n\n    async fn apply<C: ConnectionTrait>(\n        &self,\n        db: &C,\n        created_enums: &mut Vec<Statement>,\n    ) -> Result<(), DbErr> {\n        for stmt in self.enums.iter() {\n            let new_stmt = db.get_database_backend().build(stmt);\n            if !created_enums.iter().any(|s| s == &new_stmt) {\n                db.execute(stmt).await?;\n                created_enums.push(new_stmt);\n            }\n        }\n        db.execute(&self.table).await?;\n        for stmt in self.indexes.iter() {\n            db.execute(stmt).await?;\n        }\n        Ok(())\n    }\n\n    // better to always compile this function\n    #[allow(dead_code)]\n    async fn sync<C: ConnectionTrait>(\n        &self,\n        db: &C,\n        existing: &DiscoveredSchema,\n        created_enums: &mut Vec<Statement>,\n    ) -> Result<(), DbErr> {\n        let db_backend = db.get_database_backend();\n\n        // create enum before creating table\n        for stmt in self.enums.iter() {\n            let mut has_enum = false;\n            let new_stmt = db_backend.build(stmt);\n            for existing_enum in &existing.enums {\n                if db_backend.build(existing_enum) == new_stmt {\n                    has_enum = true;\n                    // TODO add enum variants\n                    break;\n                }\n            }\n            if !has_enum && !created_enums.iter().any(|s| s == &new_stmt) {\n                db.execute(stmt).await?;\n                created_enums.push(new_stmt);\n            }\n        }\n        let table_name = get_table_name(self.table.get_table_name());\n        let mut existing_table = None;\n        for tbl in &existing.tables {\n            if get_table_name(tbl.get_table_name()) == table_name {\n                existing_table = Some(tbl);\n                break;\n            }\n        }\n        if let Some(existing_table) = existing_table {\n            for column_def in self.table.get_columns() {\n                let mut column_exists = false;\n                for existing_column in existing_table.get_columns() {\n                    if column_def.get_column_name() == existing_column.get_column_name() {\n                        column_exists = true;\n                        break;\n                    }\n                }\n                if !column_exists {\n                    let mut renamed_from = \"\";\n                    if let Some(comment) = &column_def.get_column_spec().comment {\n                        if let Some((_, suffix)) = comment.rsplit_once(\"renamed_from \\\"\") {\n                            if let Some((prefix, _)) = suffix.split_once('\"') {\n                                renamed_from = prefix;\n                            }\n                        }\n                    }\n                    if renamed_from.is_empty() {\n                        db.execute(\n                            TableAlterStatement::new()\n                                .table(self.table.get_table_name().expect(\"Checked above\").clone())\n                                .add_column(column_def.to_owned()),\n                        )\n                        .await?;\n                    } else {\n                        db.execute(\n                            TableAlterStatement::new()\n                                .table(self.table.get_table_name().expect(\"Checked above\").clone())\n                                .rename_column(\n                                    renamed_from.to_owned(),\n                                    column_def.get_column_name(),\n                                ),\n                        )\n                        .await?;\n                    }\n                }\n            }\n            if db.get_database_backend() != DbBackend::Sqlite {\n                for foreign_key in self.table.get_foreign_key_create_stmts().iter() {\n                    let mut key_exists = false;\n                    for existing_key in existing_table.get_foreign_key_create_stmts().iter() {\n                        if compare_foreign_key(foreign_key, existing_key) {\n                            key_exists = true;\n                            break;\n                        }\n                    }\n                    if !key_exists {\n                        db.execute(foreign_key).await?;\n                    }\n                }\n            }\n        } else {\n            db.execute(&self.table).await?;\n        }\n        for stmt in self.indexes.iter() {\n            let mut has_index = false;\n            if let Some(existing_table) = existing_table {\n                for existing_index in existing_table.get_indexes() {\n                    if existing_index.get_index_spec().get_column_names()\n                        == stmt.get_index_spec().get_column_names()\n                    {\n                        has_index = true;\n                        break;\n                    }\n                }\n            }\n            if !has_index {\n                // shall we do alter table add constraint for unique index?\n                let mut stmt = stmt.clone();\n                stmt.if_not_exists();\n                db.execute(&stmt).await?;\n            }\n        }\n        if let Some(existing_table) = existing_table {\n            // For columns with a column-level UNIQUE constraint (#[sea_orm(unique)]) that\n            // already exist in the table but do not yet have a unique index, create one.\n            for column_def in self.table.get_columns() {\n                if column_def.get_column_spec().unique {\n                    let col_name = column_def.get_column_name();\n                    let col_exists = existing_table\n                        .get_columns()\n                        .iter()\n                        .any(|c| c.get_column_name() == col_name);\n                    if !col_exists {\n                        // Column is being added in this sync pass; the ALTER TABLE ADD COLUMN\n                        // will include the UNIQUE inline, so no separate index needed.\n                        continue;\n                    }\n                    let already_unique = existing_table.get_indexes().iter().any(|idx| {\n                        if !idx.is_unique_key() {\n                            return false;\n                        }\n                        let cols = idx.get_index_spec().get_column_names();\n                        cols.len() == 1 && cols[0] == col_name\n                    });\n                    if !already_unique {\n                        let table_name =\n                            self.table.get_table_name().expect(\"table must have a name\");\n                        let tbl_str = table_name.sea_orm_table().to_string();\n                        let table_ref = table_name.clone();\n                        db.execute(\n                            Index::create()\n                                .name(format!(\"idx-{tbl_str}-{col_name}\"))\n                                .table(table_ref)\n                                .col(col_name.into_iden())\n                                .unique()\n                                .if_not_exists(),\n                        )\n                        .await?;\n                    }\n                }\n            }\n        }\n        if let Some(existing_table) = existing_table {\n            // find all unique keys from existing table\n            // if it no longer exist in new schema, drop it\n            for existing_index in existing_table.get_indexes() {\n                if existing_index.is_unique_key() {\n                    let mut has_index = false;\n                    for stmt in self.indexes.iter() {\n                        if existing_index.get_index_spec().get_column_names()\n                            == stmt.get_index_spec().get_column_names()\n                        {\n                            has_index = true;\n                            break;\n                        }\n                    }\n                    // Also check if the unique index corresponds to a column-level UNIQUE\n                    // constraint (from #[sea_orm(unique)]). These are embedded in the CREATE\n                    // TABLE column definition and not tracked in self.indexes, so we must not\n                    // try to drop them during sync.\n                    if !has_index {\n                        let index_cols = existing_index.get_index_spec().get_column_names();\n                        if index_cols.len() == 1 {\n                            for column_def in self.table.get_columns() {\n                                if column_def.get_column_name() == index_cols[0]\n                                    && column_def.get_column_spec().unique\n                                {\n                                    has_index = true;\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                    if !has_index {\n                        if let Some(drop_existing) = existing_index\n                            .get_index_spec()\n                            .get_name()\n                            .map(|s| s.to_owned())\n                        {\n                            if db_backend == DbBackend::Postgres {\n                                // On PostgreSQL, unique indexes created via column-level UNIQUE\n                                // (e.g. ADD COLUMN ... UNIQUE) are backed by a named constraint.\n                                // DROP INDEX fails on constraint-owned indexes; use\n                                // ALTER TABLE ... DROP CONSTRAINT instead.\n                                db.execute(\n                                    TableAlterStatement::new()\n                                        .table(\n                                            self.table\n                                                .get_table_name()\n                                                .expect(\"Checked above\")\n                                                .clone(),\n                                        )\n                                        .drop_constraint(drop_existing),\n                                )\n                                .await?;\n                            } else {\n                                db.execute(sea_query::Index::drop().name(drop_existing))\n                                    .await?;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        Ok(())\n    }\n\n    fn debug_print(\n        &self,\n        f: &mut std::fmt::Formatter<'_>,\n        backend: &DbBackend,\n    ) -> std::fmt::Result {\n        write!(f, \"EntitySchemaInfo {{\")?;\n        write!(f, \" table: {:?}\", backend.build(&self.table).to_string())?;\n        write!(f, \" enums: [\")?;\n        for (i, stmt) in self.enums.iter().enumerate() {\n            if i > 0 {\n                write!(f, \", \")?;\n            }\n            write!(f, \"{:?}\", backend.build(stmt).to_string())?;\n        }\n        write!(f, \" ]\")?;\n        write!(f, \" indexes: [\")?;\n        for (i, stmt) in self.indexes.iter().enumerate() {\n            if i > 0 {\n                write!(f, \", \")?;\n            }\n            write!(f, \"{:?}\", backend.build(stmt).to_string())?;\n        }\n        write!(f, \" ]\")?;\n        write!(f, \" }}\")\n    }\n}\n\nfn get_table_name(table_ref: Option<&TableRef>) -> TableName {\n    match table_ref {\n        Some(TableRef::Table(table_name, _)) => table_name.clone(),\n        None => panic!(\"Expect TableCreateStatement is properly built\"),\n        _ => unreachable!(\"Unexpected {table_ref:?}\"),\n    }\n}\n\nfn compare_foreign_key(a: &ForeignKeyCreateStatement, b: &ForeignKeyCreateStatement) -> bool {\n    let a = a.get_foreign_key();\n    let b = b.get_foreign_key();\n\n    a.get_name() == b.get_name()\n        || (a.get_ref_table() == b.get_ref_table()\n            && a.get_columns() == b.get_columns()\n            && a.get_ref_columns() == b.get_ref_columns())\n}\n"
  },
  {
    "path": "src/schema/entity.rs",
    "content": "use crate::{\n    ActiveEnum, ColumnTrait, ColumnType, DbBackend, EntityTrait, IdenStatic, Iterable,\n    PrimaryKeyArity, PrimaryKeyToColumn, PrimaryKeyTrait, RelationTrait, Schema,\n};\nuse sea_query::{\n    ColumnDef, DynIden, Iden, Index, IndexCreateStatement, SeaRc, TableCreateStatement,\n    extension::postgres::{Type, TypeCreateStatement},\n};\nuse std::collections::BTreeMap;\n\nimpl Schema {\n    /// Creates Postgres enums from an ActiveEnum. See [`TypeCreateStatement`] for more details.\n    /// Returns None if not Postgres.\n    pub fn create_enum_from_active_enum<A>(&self) -> Option<TypeCreateStatement>\n    where\n        A: ActiveEnum,\n    {\n        create_enum_from_active_enum::<A>(self.backend)\n    }\n\n    /// Creates Postgres enums from an Entity. See [`TypeCreateStatement`] for more details.\n    /// Returns empty vec if not Postgres.\n    pub fn create_enum_from_entity<E>(&self, entity: E) -> Vec<TypeCreateStatement>\n    where\n        E: EntityTrait,\n    {\n        create_enum_from_entity(entity, self.backend)\n    }\n\n    /// Creates a table from an Entity. See [TableCreateStatement] for more details.\n    pub fn create_table_from_entity<E>(&self, entity: E) -> TableCreateStatement\n    where\n        E: EntityTrait,\n    {\n        create_table_from_entity(entity, self.backend)\n    }\n\n    #[doc(hidden)]\n    pub fn create_table_with_index_from_entity<E>(&self, entity: E) -> TableCreateStatement\n    where\n        E: EntityTrait,\n    {\n        let mut table = create_table_from_entity(entity, self.backend);\n        for mut index in create_index_from_entity(entity, self.backend) {\n            table.index(&mut index);\n        }\n        table\n    }\n\n    /// Creates the indexes from an Entity, returning an empty Vec if there are none\n    /// to create. See [IndexCreateStatement] for more details\n    pub fn create_index_from_entity<E>(&self, entity: E) -> Vec<IndexCreateStatement>\n    where\n        E: EntityTrait,\n    {\n        create_index_from_entity(entity, self.backend)\n    }\n\n    /// Creates a column definition for example to update a table.\n    ///\n    /// ```\n    /// use sea_orm::sea_query::TableAlterStatement;\n    /// use sea_orm::{DbBackend, Schema, Statement};\n    ///\n    /// mod post {\n    ///     use sea_orm::entity::prelude::*;\n    ///\n    ///     #[sea_orm::model]\n    ///     #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    ///     #[sea_orm(table_name = \"posts\")]\n    ///     pub struct Model {\n    ///         #[sea_orm(primary_key)]\n    ///         pub id: u32,\n    ///         pub title: String,\n    ///     }\n    ///\n    ///     impl ActiveModelBehavior for ActiveModel {}\n    /// }\n    ///\n    /// let schema = Schema::new(DbBackend::MySql);\n    ///\n    /// let alter_table: Statement = DbBackend::MySql.build(\n    ///     TableAlterStatement::new()\n    ///         .table(post::Entity)\n    ///         .add_column(&mut schema.get_column_def::<post::Entity>(post::Column::Title)),\n    /// );\n    /// assert_eq!(\n    ///     alter_table.to_string(),\n    ///     \"ALTER TABLE `posts` ADD COLUMN `title` varchar(255) NOT NULL\"\n    /// );\n    /// ```\n    pub fn get_column_def<E>(&self, column: E::Column) -> ColumnDef\n    where\n        E: EntityTrait,\n    {\n        column_def_from_entity_column::<E>(column, self.backend)\n    }\n}\n\npub(crate) fn create_enum_from_active_enum<A>(backend: DbBackend) -> Option<TypeCreateStatement>\nwhere\n    A: ActiveEnum,\n{\n    if matches!(backend, DbBackend::MySql | DbBackend::Sqlite) {\n        return None;\n    }\n    let col_def = A::db_type();\n    let col_type = col_def.get_column_type();\n    create_enum_from_column_type(col_type)\n}\n\npub(crate) fn create_enum_from_column_type(col_type: &ColumnType) -> Option<TypeCreateStatement> {\n    let (name, values) = match col_type {\n        ColumnType::Enum { name, variants } => (name.clone(), variants.clone()),\n        _ => return None,\n    };\n    Some(Type::create().as_enum(name).values(values).to_owned())\n}\n\n#[allow(clippy::needless_borrow)]\npub(crate) fn create_enum_from_entity<E>(_: E, backend: DbBackend) -> Vec<TypeCreateStatement>\nwhere\n    E: EntityTrait,\n{\n    if matches!(backend, DbBackend::MySql | DbBackend::Sqlite) {\n        return Vec::new();\n    }\n    let mut vec = Vec::new();\n    for col in E::Column::iter() {\n        let col_def = col.def();\n        let col_type = col_def.get_column_type();\n        if !matches!(col_type, ColumnType::Enum { .. }) {\n            continue;\n        }\n        if let Some(stmt) = create_enum_from_column_type(&col_type) {\n            vec.push(stmt);\n        }\n    }\n    vec\n}\n\npub(crate) fn create_index_from_entity<E>(\n    entity: E,\n    _backend: DbBackend,\n) -> Vec<IndexCreateStatement>\nwhere\n    E: EntityTrait,\n{\n    let mut indexes = Vec::new();\n    let mut unique_keys: BTreeMap<String, Vec<DynIden>> = Default::default();\n\n    for column in E::Column::iter() {\n        let column_def = column.def();\n\n        if column_def.indexed && !column_def.unique {\n            let stmt = Index::create()\n                .name(format!(\"idx-{}-{}\", entity.to_string(), column.to_string()))\n                .table(entity)\n                .col(column)\n                .take();\n            indexes.push(stmt);\n        }\n\n        if let Some(key) = column_def.unique_key {\n            unique_keys.entry(key).or_default().push(SeaRc::new(column));\n        }\n    }\n\n    for (key, cols) in unique_keys {\n        let mut stmt = Index::create()\n            .name(format!(\"idx-{}-{}\", entity.to_string(), key))\n            .table(entity)\n            .unique()\n            .take();\n        for col in cols {\n            stmt.col(col);\n        }\n        indexes.push(stmt);\n    }\n\n    indexes\n}\n\npub(crate) fn create_table_from_entity<E>(entity: E, backend: DbBackend) -> TableCreateStatement\nwhere\n    E: EntityTrait,\n{\n    let mut stmt = TableCreateStatement::new();\n\n    if let Some(comment) = entity.comment() {\n        stmt.comment(comment);\n    }\n\n    for column in E::Column::iter() {\n        let mut column_def = column_def_from_entity_column::<E>(column, backend);\n        stmt.col(&mut column_def);\n    }\n\n    if <<E::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY > 1 {\n        let mut idx_pk = Index::create();\n        for primary_key in E::PrimaryKey::iter() {\n            idx_pk.col(primary_key);\n        }\n        stmt.primary_key(idx_pk.name(format!(\"pk-{}\", entity.to_string())).primary());\n    }\n\n    for relation in E::Relation::iter() {\n        let relation = relation.def();\n        if relation.is_owner || relation.skip_fk {\n            continue;\n        }\n        stmt.foreign_key(&mut relation.into());\n    }\n\n    stmt.table(entity.table_ref()).take()\n}\n\nfn column_def_from_entity_column<E>(column: E::Column, backend: DbBackend) -> ColumnDef\nwhere\n    E: EntityTrait,\n{\n    let orm_column_def = column.def();\n    let types = match &orm_column_def.col_type {\n        ColumnType::Enum { name, variants } => match backend {\n            DbBackend::MySql => {\n                let variants: Vec<String> = variants.iter().map(|v| v.to_string()).collect();\n                ColumnType::custom(format!(\"ENUM('{}')\", variants.join(\"', '\")))\n            }\n            DbBackend::Postgres => ColumnType::Custom(name.clone()),\n            DbBackend::Sqlite => orm_column_def.col_type,\n        },\n        _ => orm_column_def.col_type,\n    };\n    let mut column_def = ColumnDef::new_with_type(column, types);\n    if !orm_column_def.null {\n        column_def.not_null();\n    }\n    if orm_column_def.unique {\n        column_def.unique_key();\n    }\n    if let Some(default) = orm_column_def.default {\n        column_def.default(default);\n    }\n    if let Some(comment) = &orm_column_def.comment {\n        column_def.comment(comment);\n    }\n    if let Some(extra) = &orm_column_def.extra {\n        column_def.extra(extra);\n    }\n    match (&orm_column_def.renamed_from, &orm_column_def.comment) {\n        (Some(renamed_from), Some(comment)) => {\n            column_def.comment(format!(\"{comment}; renamed_from \\\"{renamed_from}\\\"\"));\n        }\n        (Some(renamed_from), None) => {\n            column_def.comment(format!(\"renamed_from \\\"{renamed_from}\\\"\"));\n        }\n        (None, _) => {}\n    }\n    for primary_key in E::PrimaryKey::iter() {\n        if column.as_str() == primary_key.into_column().as_str() {\n            if E::PrimaryKey::auto_increment() {\n                column_def.auto_increment();\n            }\n            if <<E::PrimaryKey as PrimaryKeyTrait>::ValueType as PrimaryKeyArity>::ARITY == 1 {\n                column_def.primary_key();\n            }\n        }\n    }\n    column_def\n}\n\n#[cfg(test)]\nmod tests {\n    use crate::{DbBackend, EntityName, Schema, sea_query::*, tests_cfg::*};\n    use pretty_assertions::assert_eq;\n\n    #[test]\n    fn test_create_table_from_entity_table_ref() {\n        for builder in [DbBackend::MySql, DbBackend::Postgres, DbBackend::Sqlite] {\n            let schema = Schema::new(builder);\n            assert_eq!(\n                builder.build(&schema.create_table_from_entity(CakeFillingPrice)),\n                builder.build(\n                    &get_cake_filling_price_stmt()\n                        .table(CakeFillingPrice.table_ref())\n                        .to_owned()\n                )\n            );\n        }\n    }\n\n    fn get_cake_filling_price_stmt() -> TableCreateStatement {\n        Table::create()\n            .col(\n                ColumnDef::new(cake_filling_price::Column::CakeId)\n                    .integer()\n                    .not_null(),\n            )\n            .col(\n                ColumnDef::new(cake_filling_price::Column::FillingId)\n                    .integer()\n                    .not_null(),\n            )\n            .col(\n                ColumnDef::new(cake_filling_price::Column::Price)\n                    .decimal()\n                    .not_null()\n                    .extra(\"CHECK (price > 0)\"),\n            )\n            .primary_key(\n                Index::create()\n                    .name(\"pk-cake_filling_price\")\n                    .col(cake_filling_price::Column::CakeId)\n                    .col(cake_filling_price::Column::FillingId)\n                    .primary(),\n            )\n            .foreign_key(\n                ForeignKeyCreateStatement::new()\n                    .name(\"fk-cake_filling_price-cake_id-filling_id\")\n                    .from_tbl(CakeFillingPrice)\n                    .from_col(cake_filling_price::Column::CakeId)\n                    .from_col(cake_filling_price::Column::FillingId)\n                    .to_tbl(CakeFilling)\n                    .to_col(cake_filling::Column::CakeId)\n                    .to_col(cake_filling::Column::FillingId),\n            )\n            .to_owned()\n    }\n\n    #[test]\n    fn test_create_index_from_entity_table_ref() {\n        for builder in [DbBackend::MySql, DbBackend::Postgres, DbBackend::Sqlite] {\n            let schema = Schema::new(builder);\n\n            assert_eq!(\n                builder.build(&schema.create_table_from_entity(indexes::Entity)),\n                builder.build(\n                    &get_indexes_table_stmt()\n                        .table(indexes::Entity.table_ref())\n                        .to_owned()\n                )\n            );\n\n            let stmts = schema.create_index_from_entity(indexes::Entity);\n            assert_eq!(stmts.len(), 2);\n\n            let idx: IndexCreateStatement = Index::create()\n                .name(\"idx-indexes-index1_attr\")\n                .table(indexes::Entity)\n                .col(indexes::Column::Index1Attr)\n                .to_owned();\n            assert_eq!(builder.build(&stmts[0]), builder.build(&idx));\n\n            let idx: IndexCreateStatement = Index::create()\n                .name(\"idx-indexes-my_unique\")\n                .table(indexes::Entity)\n                .col(indexes::Column::UniqueKeyA)\n                .col(indexes::Column::UniqueKeyB)\n                .unique()\n                .take();\n            assert_eq!(builder.build(&stmts[1]), builder.build(&idx));\n        }\n    }\n\n    fn get_indexes_table_stmt() -> TableCreateStatement {\n        Table::create()\n            .col(\n                ColumnDef::new(indexes::Column::IndexesId)\n                    .integer()\n                    .not_null()\n                    .auto_increment()\n                    .primary_key(),\n            )\n            .col(\n                ColumnDef::new(indexes::Column::UniqueAttr)\n                    .integer()\n                    .not_null()\n                    .unique_key(),\n            )\n            .col(\n                ColumnDef::new(indexes::Column::Index1Attr)\n                    .integer()\n                    .not_null(),\n            )\n            .col(\n                ColumnDef::new(indexes::Column::Index2Attr)\n                    .integer()\n                    .not_null()\n                    .unique_key(),\n            )\n            .col(\n                ColumnDef::new(indexes::Column::UniqueKeyA)\n                    .string()\n                    .not_null(),\n            )\n            .col(\n                ColumnDef::new(indexes::Column::UniqueKeyB)\n                    .string()\n                    .not_null(),\n            )\n            .to_owned()\n    }\n}\n"
  },
  {
    "path": "src/schema/json.rs",
    "content": "use crate::{ColumnTrait, ColumnType, EntityTrait, Iden, Iterable, Schema};\nuse serde_json::{Map, Value};\n\nimpl Schema {\n    /// Construct a schema description in json for the given Entity.\n    pub fn json_schema_from_entity<E>(&self, entity: E) -> Value\n    where\n        E: EntityTrait,\n    {\n        json_schema_from_entity(entity)\n    }\n}\n\npub(crate) fn json_schema_from_entity<E>(entity: E) -> Value\nwhere\n    E: EntityTrait,\n{\n    let mut obj = Map::new();\n    let mut cols = Vec::new();\n\n    if let Some(comment) = entity.comment() {\n        obj.insert(\"comment\".to_owned(), Value::String(comment.to_owned()));\n    }\n\n    for column in E::Column::iter() {\n        let col = json_schema_from_entity_column::<E>(column);\n        cols.push(col);\n    }\n    obj.insert(\"columns\".to_owned(), Value::Array(cols));\n\n    let mut pk = Vec::new();\n    for col in E::PrimaryKey::iter() {\n        pk.push(Value::String(col.to_string()));\n    }\n    obj.insert(\"primary_key\".to_owned(), Value::Array(pk));\n\n    Value::Object(obj)\n}\n\nfn json_schema_from_entity_column<E>(column: E::Column) -> Value\nwhere\n    E: EntityTrait,\n{\n    let mut obj = Map::new();\n\n    let column_def = column.def();\n    obj.insert(\"name\".to_owned(), Value::String(column.to_string()));\n    obj.insert(\n        \"type\".to_owned(),\n        type_def_from_column_def(&column_def.col_type),\n    );\n    obj.insert(\"nullable\".to_owned(), Value::Bool(column_def.null));\n    if column_def.unique {\n        obj.insert(\"unique\".to_owned(), Value::Bool(true));\n    }\n    if let Some(comment) = column_def.comment {\n        obj.insert(\"comment\".to_owned(), Value::String(comment));\n    }\n\n    Value::Object(obj)\n}\n\nfn type_def_from_column_def(column_type: &ColumnType) -> Value {\n    match column_type {\n        ColumnType::Char(_) | ColumnType::String(_) | ColumnType::Text => {\n            Value::String(\"string\".to_owned())\n        }\n        ColumnType::TinyInteger\n        | ColumnType::SmallInteger\n        | ColumnType::Integer\n        | ColumnType::BigInteger\n        | ColumnType::TinyUnsigned\n        | ColumnType::SmallUnsigned\n        | ColumnType::Unsigned\n        | ColumnType::BigUnsigned => Value::String(\"integer\".to_owned()),\n        ColumnType::Float | ColumnType::Double => Value::String(\"real\".to_owned()),\n        ColumnType::Decimal(_) | ColumnType::Money(_) => Value::String(\"decimal\".to_owned()),\n        ColumnType::DateTime | ColumnType::Timestamp | ColumnType::TimestampWithTimeZone => {\n            Value::String(\"datetime\".to_owned())\n        }\n        ColumnType::Time => Value::String(\"time\".to_owned()),\n        ColumnType::Date => Value::String(\"date\".to_owned()),\n        ColumnType::Year => Value::String(\"year\".to_owned()),\n        ColumnType::Binary(_)\n        | ColumnType::VarBinary(_)\n        | ColumnType::Bit(_)\n        | ColumnType::VarBit(_) => Value::String(\"binary\".to_owned()),\n        ColumnType::Boolean => Value::String(\"bool\".to_owned()),\n        ColumnType::Json | ColumnType::JsonBinary => Value::String(\"json\".to_owned()),\n        ColumnType::Uuid => Value::String(\"uuid\".to_owned()),\n        ColumnType::Custom(typename) => Value::String(typename.to_string()),\n        ColumnType::Enum { name, variants } => {\n            let mut enum_def = Map::new();\n            enum_def.insert(\"name\".to_owned(), Value::String(name.to_string()));\n            let variants: Vec<Value> = variants\n                .iter()\n                .map(|v| Value::String(v.to_string()))\n                .collect();\n            enum_def.insert(\"variants\".to_owned(), Value::Array(variants));\n            Value::Object(enum_def)\n        }\n        ColumnType::Array(inner) => {\n            let mut obj = Map::new();\n            obj.insert(\"array\".to_owned(), type_def_from_column_def(inner));\n            Value::Object(obj)\n        }\n        _ => Value::String(\"other\".to_owned()),\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::{\n        DbBackend,\n        tests_cfg::{cake, lunch_set},\n    };\n\n    #[test]\n    fn test_json_schema_from_entity() {\n        let json = Schema::new(DbBackend::MySql).json_schema_from_entity(cake::Entity);\n        println!(\"{}\", serde_json::to_string_pretty(&json).unwrap());\n        assert_eq!(\n            json,\n            serde_json::from_str::<Value>(\n                r#\"{\n                \"columns\": [\n                    {\n                        \"name\": \"id\",\n                        \"nullable\": false,\n                        \"type\": \"integer\"\n                    },\n                    {\n                        \"name\": \"name\",\n                        \"nullable\": false,\n                        \"type\": \"string\"\n                    }\n                ],\n                \"primary_key\": [\n                    \"id\"\n                ]\n            }\"#\n            )\n            .unwrap()\n        );\n\n        let json = Schema::new(DbBackend::MySql).json_schema_from_entity(lunch_set::Entity);\n        println!(\"{}\", serde_json::to_string_pretty(&json).unwrap());\n        assert_eq!(\n            json,\n            serde_json::from_str::<Value>(\n                r#\"{\n                \"columns\": [\n                    {\n                        \"name\": \"id\",\n                        \"nullable\": false,\n                        \"type\": \"integer\"\n                    },\n                    {\n                        \"name\": \"name\",\n                        \"nullable\": false,\n                        \"type\": \"string\"\n                    },\n                    {\n                        \"name\": \"tea\",\n                        \"nullable\": false,\n                        \"type\": {\n                            \"name\": \"tea\",\n                            \"variants\": [\n                                \"EverydayTea\",\n                                \"BreakfastTea\"\n                            ]\n                        }\n                    }\n                ],\n                \"primary_key\": [\n                    \"id\"\n                ]\n            }\"#\n            )\n            .unwrap()\n        );\n    }\n}\n"
  },
  {
    "path": "src/schema/mod.rs",
    "content": "use crate::DbBackend;\n\nmod builder;\nmod entity;\n#[cfg(feature = \"serde_json\")]\nmod json;\nmod topology;\n\npub use builder::*;\nuse topology::*;\n\n/// This is a helper struct to convert [`EntityTrait`](crate::EntityTrait)\n/// into different [`sea_query`](crate::sea_query) statements.\n#[derive(Debug)]\npub struct Schema {\n    backend: DbBackend,\n}\n\nimpl Schema {\n    /// Create a helper for a specific database backend\n    pub fn new(backend: DbBackend) -> Self {\n        Self { backend }\n    }\n\n    /// Creates a schema builder that can apply schema changes to database\n    pub fn builder(self) -> SchemaBuilder {\n        SchemaBuilder::new(self)\n    }\n}\n"
  },
  {
    "path": "src/schema/topology.rs",
    "content": "// Copyright 2016 oauth-client-rs Developers\n//\n// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or\n// https://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or\n// https://opensource.org/licenses/MIT>, at your option. This file may not be\n// copied, modified, or distributed except according to those terms.\n\n//! Performs topological sorting.\n//!\n//! Vendored from https://github.com/gifnksm/topological-sort-rs\n\n#![warn(bad_style)]\n#![warn(missing_copy_implementations)]\n#![warn(missing_debug_implementations)]\n#![warn(missing_docs)]\n#![warn(trivial_casts)]\n#![warn(trivial_numeric_casts)]\n#![allow(unused)]\n#![warn(unused_extern_crates)]\n#![warn(unused_import_braces)]\n#![warn(unused_qualifications)]\n#![warn(unused_results)]\n#![warn(clippy::if_not_else)]\n#![warn(clippy::invalid_upcast_comparisons)]\n#![warn(clippy::items_after_statements)]\n#![warn(clippy::mut_mut)]\n#![warn(clippy::never_loop)]\n#![warn(clippy::nonminimal_bool)]\n#![warn(clippy::used_underscore_binding)]\n\nuse std::cmp::Ordering;\nuse std::collections::hash_map::Entry;\nuse std::collections::{HashMap, HashSet};\nuse std::fmt;\nuse std::hash::Hash;\nuse std::iter::FromIterator;\n\n#[derive(Clone)]\nstruct Dependency<T> {\n    num_prec: usize,\n    succ: HashSet<T>,\n}\n\nimpl<T: Hash + Eq> Dependency<T> {\n    fn new() -> Dependency<T> {\n        Dependency {\n            num_prec: 0,\n            succ: HashSet::new(),\n        }\n    }\n}\n\n/// Performs topological sorting.\n#[derive(Clone)]\npub struct TopologicalSort<T> {\n    top: HashMap<T, Dependency<T>>,\n}\n\nimpl<T> Default for TopologicalSort<T> {\n    fn default() -> TopologicalSort<T> {\n        TopologicalSort {\n            top: HashMap::new(),\n        }\n    }\n}\n\nimpl<T: Hash + Eq + Clone> TopologicalSort<T> {\n    #[inline]\n    pub fn new() -> TopologicalSort<T> {\n        Default::default()\n    }\n\n    /// Returns the number of elements in the `TopologicalSort`.\n    #[inline]\n    pub fn len(&self) -> usize {\n        self.top.len()\n    }\n\n    /// Returns true if the `TopologicalSort` contains no elements.\n    #[inline]\n    pub fn is_empty(&self) -> bool {\n        self.top.is_empty()\n    }\n\n    /// Registers the two elements' dependency.\n    ///\n    /// # Arguments\n    ///\n    /// * `prec` - The element appears before `succ`. `prec` is depended on by `succ`.\n    /// * `succ` - The element appears after `prec`. `succ` depends on `prec`.\n    pub fn add_dependency<P, S>(&mut self, prec: P, succ: S)\n    where\n        P: Into<T>,\n        S: Into<T>,\n    {\n        self.add_dependency_impl(prec.into(), succ.into())\n    }\n\n    fn add_dependency_impl(&mut self, prec: T, succ: T) {\n        match self.top.entry(prec) {\n            Entry::Vacant(e) => {\n                let mut dep = Dependency::new();\n                let _ = dep.succ.insert(succ.clone());\n                let _ = e.insert(dep);\n            }\n            Entry::Occupied(e) => {\n                if !e.into_mut().succ.insert(succ.clone()) {\n                    // Already registered\n                    return;\n                }\n            }\n        }\n\n        match self.top.entry(succ) {\n            Entry::Vacant(e) => {\n                let mut dep = Dependency::new();\n                dep.num_prec += 1;\n                let _ = e.insert(dep);\n            }\n            Entry::Occupied(e) => {\n                e.into_mut().num_prec += 1;\n            }\n        }\n    }\n\n    /// Registers a dependency link.\n    pub fn add_link(&mut self, link: DependencyLink<T>) {\n        self.add_dependency(link.prec, link.succ)\n    }\n\n    /// Inserts an element, without adding any dependencies from or to it.\n    ///\n    /// If the `TopologicalSort` did not have this element present, `true` is returned.\n    ///\n    /// If the `TopologicalSort` already had this element present, `false` is returned.\n    pub fn insert<U>(&mut self, elt: U) -> bool\n    where\n        U: Into<T>,\n    {\n        match self.top.entry(elt.into()) {\n            Entry::Vacant(e) => {\n                let dep = Dependency::new();\n                let _ = e.insert(dep);\n                true\n            }\n            Entry::Occupied(_) => false,\n        }\n    }\n\n    /// Removes the item that is not depended on by any other items and returns it, or `None` if\n    /// there is no such item.\n    ///\n    /// If `pop` returns `None` and `len` is not 0, there is cyclic dependencies.\n    pub fn pop(&mut self) -> Option<T> {\n        self.peek().cloned().inspect(|key| {\n            let _ = self.remove(key);\n        })\n    }\n\n    /// Removes all items that are not depended on by any other items and returns it, or empty\n    /// vector if there are no such items.\n    ///\n    /// If `pop_all` returns an empty vector and `len` is not 0, there is cyclic dependencies.\n    pub fn pop_all(&mut self) -> Vec<T> {\n        let keys = self\n            .top\n            .iter()\n            .filter(|&(_, v)| v.num_prec == 0)\n            .map(|(k, _)| k.clone())\n            .collect::<Vec<_>>();\n        for k in &keys {\n            let _ = self.remove(k);\n        }\n        keys\n    }\n\n    /// Return a reference to the first item that does not depend on any other items, or `None` if\n    /// there is no such item.\n    pub fn peek(&self) -> Option<&T> {\n        self.top\n            .iter()\n            .filter(|&(_, v)| v.num_prec == 0)\n            .map(|(k, _)| k)\n            .next()\n    }\n\n    /// Return a vector of references to all items that do not depend on any other items, or an\n    /// empty vector if there are no such items.\n    pub fn peek_all(&self) -> Vec<&T> {\n        self.top\n            .iter()\n            .filter(|&(_, v)| v.num_prec == 0)\n            .map(|(k, _)| k)\n            .collect::<Vec<_>>()\n    }\n\n    fn remove(&mut self, prec: &T) -> Option<Dependency<T>> {\n        let result = self.top.remove(prec);\n        if let Some(ref p) = result {\n            for s in &p.succ {\n                if let Some(y) = self.top.get_mut(s) {\n                    y.num_prec -= 1;\n                }\n            }\n        }\n        result\n    }\n}\n\nimpl<T: PartialOrd + Eq + Hash + Clone> FromIterator<T> for TopologicalSort<T> {\n    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> TopologicalSort<T> {\n        let mut top = TopologicalSort::new();\n        let mut seen = Vec::<T>::default();\n        for item in iter {\n            let _ = top.insert(item.clone());\n            for seen_item in seen.iter().cloned() {\n                match seen_item.partial_cmp(&item) {\n                    Some(Ordering::Less) => {\n                        top.add_dependency(seen_item, item.clone());\n                    }\n                    Some(Ordering::Greater) => {\n                        top.add_dependency(item.clone(), seen_item);\n                    }\n                    _ => (),\n                }\n            }\n            seen.push(item);\n        }\n        top\n    }\n}\n\n/// A link between two items in a sort.\n#[derive(Copy, Clone, Debug)]\npub struct DependencyLink<T> {\n    /// The element which is depened upon by `succ`.\n    pub prec: T,\n    /// The element which depends on `prec`.\n    pub succ: T,\n}\n\nimpl<T> From<(T, T)> for DependencyLink<T> {\n    fn from(tuple: (T, T)) -> Self {\n        DependencyLink {\n            succ: tuple.0,\n            prec: tuple.1,\n        }\n    }\n}\n\nimpl<T: Eq + Hash + Clone> FromIterator<DependencyLink<T>> for TopologicalSort<T> {\n    fn from_iter<I: IntoIterator<Item = DependencyLink<T>>>(iter: I) -> TopologicalSort<T> {\n        let mut top = TopologicalSort::new();\n        for link in iter {\n            top.add_link(link);\n        }\n        top\n    }\n}\n\nimpl<T: Hash + Eq + Clone> Iterator for TopologicalSort<T> {\n    type Item = T;\n\n    fn next(&mut self) -> Option<T> {\n        self.pop()\n    }\n}\n\nimpl<T: fmt::Debug + Hash + Eq> fmt::Debug for Dependency<T> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"prec={}, succ={:?}\", self.num_prec, self.succ)\n    }\n}\n\nimpl<T: fmt::Debug + Hash + Eq + Clone> fmt::Debug for TopologicalSort<T> {\n    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {\n        write!(f, \"{:?}\", self.top)\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::TopologicalSort;\n    use std::iter::FromIterator;\n\n    #[test]\n    fn from_iter() {\n        let t = vec![4, 3, 3, 5, 7, 6, 8];\n        let mut ts = TopologicalSort::<i32>::from_iter(t);\n        assert_eq!(Some(3), ts.next());\n        assert_eq!(Some(4), ts.next());\n        assert_eq!(Some(5), ts.next());\n        assert_eq!(Some(6), ts.next());\n        assert_eq!(Some(7), ts.next());\n        assert_eq!(Some(8), ts.next());\n        assert_eq!(None, ts.next());\n    }\n\n    #[test]\n    fn iter() {\n        let mut ts = TopologicalSort::<i32>::new();\n        ts.add_dependency(1, 2);\n        ts.add_dependency(2, 3);\n        ts.add_dependency(3, 4);\n        assert_eq!(Some(1), ts.next());\n        assert_eq!(Some(2), ts.next());\n        assert_eq!(Some(3), ts.next());\n        assert_eq!(Some(4), ts.next());\n        assert_eq!(None, ts.next());\n    }\n\n    #[test]\n    fn pop_all() {\n        fn check(result: &[i32], ts: &mut TopologicalSort<i32>) {\n            let l = ts.len();\n            let mut v = ts.pop_all();\n            v.sort();\n            assert_eq!(result, &v[..]);\n            assert_eq!(l - result.len(), ts.len());\n        }\n\n        let mut ts = TopologicalSort::new();\n        ts.add_dependency(7, 11);\n        assert_eq!(2, ts.len());\n        ts.add_dependency(7, 8);\n        assert_eq!(3, ts.len());\n        ts.add_dependency(5, 11);\n        assert_eq!(4, ts.len());\n        ts.add_dependency(3, 8);\n        assert_eq!(5, ts.len());\n        ts.add_dependency(3, 10);\n        assert_eq!(6, ts.len());\n        ts.add_dependency(11, 2);\n        assert_eq!(7, ts.len());\n        ts.add_dependency(11, 9);\n        assert_eq!(8, ts.len());\n        ts.add_dependency(11, 10);\n        assert_eq!(8, ts.len());\n        ts.add_dependency(8, 9);\n        assert_eq!(8, ts.len());\n\n        check(&[3, 5, 7], &mut ts);\n        check(&[8, 11], &mut ts);\n        check(&[2, 9, 10], &mut ts);\n        check(&[], &mut ts);\n    }\n\n    #[test]\n    fn cyclic_deadlock() {\n        let mut ts = TopologicalSort::new();\n        ts.add_dependency(\"stone\", \"sharp\");\n\n        ts.add_dependency(\"bucket\", \"hole\");\n        ts.add_dependency(\"hole\", \"straw\");\n        ts.add_dependency(\"straw\", \"axe\");\n        ts.add_dependency(\"axe\", \"sharp\");\n        ts.add_dependency(\"sharp\", \"water\");\n        ts.add_dependency(\"water\", \"bucket\");\n        assert_eq!(ts.pop(), Some(\"stone\"));\n        assert!(ts.pop().is_none());\n        println!(\"{:?}\", ts);\n    }\n\n    #[allow(dead_code)]\n    fn topo_test_quickcheck(n: usize, edges: Vec<(usize, usize)>) {\n        use std::collections::{HashMap, HashSet};\n\n        let n = n.clamp(1, 1000);\n        let mut marked = vec![false; n];\n        let edges = edges\n            .into_iter()\n            .map(|(x, y)| (x % n, y % n))\n            .collect::<Vec<_>>();\n        let mut deps = HashMap::new();\n        let mut toposort = TopologicalSort::<usize>::new();\n\n        for i in 0..n {\n            let _ = deps.insert(i, HashSet::new());\n            assert!(toposort.insert(i));\n        }\n\n        for (op, inp) in edges.iter().map(|(x, y)| (y, x)) {\n            let inps = deps.get_mut(op).unwrap();\n            let _ = inps.insert(*inp);\n        }\n\n        let deps = deps;\n        for (inp, op) in edges {\n            toposort.add_dependency(inp, op);\n        }\n        while let Some(x) = toposort.pop() {\n            for dep in deps.get(&x).unwrap().iter() {\n                assert!(marked[*dep]);\n            }\n            marked[x] = true;\n        }\n\n        if toposort.is_empty() {\n            assert!(marked.into_iter().all(|x| x));\n        } else {\n            let dep_fixed = {\n                let mut ret = (0..n)\n                    .map(|i| (i, HashSet::new()))\n                    .collect::<HashMap<_, _>>();\n                let mut new_to_add = deps;\n\n                while !new_to_add.is_empty() {\n                    for (k, v) in new_to_add.drain() {\n                        let inps = ret.get_mut(&k).unwrap();\n                        inps.extend(v.into_iter());\n                    }\n                    for (k, vs) in ret.iter() {\n                        for k2 in vs.iter() {\n                            for v2 in ret.get(k2).unwrap().iter() {\n                                if !vs.contains(v2) {\n                                    let _ = new_to_add\n                                        .entry(*k)\n                                        .or_insert_with(HashSet::new)\n                                        .insert(*v2);\n                                }\n                            }\n                        }\n                    }\n                }\n\n                ret\n            };\n\n            assert!(dep_fixed.into_iter().any(|(op, deps)| deps.contains(&op)));\n        }\n    }\n}\n"
  },
  {
    "path": "src/tests_cfg/cake.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[cfg(feature = \"with-json\")]\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(has_one)]\n    pub fruit: HasOne<super::fruit::Entity>,\n    #[sea_orm(has_many, via = \"cake_filling\")]\n    pub fillings: HasMany<super::filling::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/cake_compact.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[cfg(feature = \"with-json\")]\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_name = \"name\", enum_name = \"Name\")]\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n    #[sea_orm(\n        has_many = \"super::fruit::Entity\",\n        on_condition = r#\"super::fruit::Column::Name.like(\"%tropical%\")\"#\n    )]\n    TropicalFruit,\n    #[sea_orm(\n        has_many = \"super::fruit::Entity\",\n        condition_type = \"any\",\n        on_condition = r#\"super::fruit::Column::Name.like(\"%tropical%\")\"#\n    )]\n    OrTropicalFruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/cake_expanded.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> &'static str {\n        \"cake\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {\n    Fruit,\n}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::None).def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        match self {\n            Self::Fruit => Entity::has_many(super::fruit::Entity).into(),\n        }\n    }\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/cake_filling.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::compact_model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake_filling\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub filling_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Cake,\n    #[sea_orm(\n        belongs_to = \"super::filling::Entity\",\n        from = \"Column::FillingId\",\n        to = \"super::filling::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Filling,\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Filling.def()\n    }\n}\n\nimpl Related<super::cake_filling_price::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling_price::Relation::CakeFilling.def().rev()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/cake_filling_price.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"public\", table_name = \"cake_filling_price\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub filling_id: i32,\n    #[cfg(feature = \"with-rust_decimal\")]\n    #[sea_orm(extra = \"CHECK (price > 0)\")]\n    pub price: Decimal,\n    #[sea_orm(ignore)]\n    pub ignored_attr: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake_filling::Entity\",\n        from = \"(Column::CakeId, Column::FillingId)\",\n        to = \"(super::cake_filling::Column::CakeId, super::cake_filling::Column::FillingId)\"\n    )]\n    CakeFilling,\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n        skip_fk\n    )]\n    Cake,\n}\n\nimpl Related<super::cake_filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::CakeFilling.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/cake_seaography.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_name = \"name\", enum_name = \"Name\")]\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::fruit::Entity\")]\n    Fruit,\n    #[sea_orm(\n        has_many = \"super::fruit::Entity\",\n        on_condition = r#\"super::fruit::Column::Name.like(\"%tropical%\")\"#\n    )]\n    TropicalFruit,\n    #[sea_orm(\n        has_many = \"super::fruit::Entity\",\n        condition_type = \"any\",\n        on_condition = r#\"super::fruit::Column::Name.like(\"%tropical%\")\"#\n    )]\n    OrTropicalFruit,\n}\n\nimpl Related<super::fruit::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Fruit.def()\n    }\n}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Filling.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Cake.def().rev())\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]\npub enum RelatedEntity {\n    #[sea_orm(entity = \"super::fruit::Entity\")]\n    Fruit,\n    #[sea_orm(entity = \"super::filling::Entity\")]\n    Filling,\n    #[sea_orm(\n        entity = \"super::fruit::Entity\",\n        def = \"Relation::TropicalFruit.def()\"\n    )]\n    TropicalFruit,\n    #[sea_orm(\n        entity = \"super::fruit::Entity\",\n        def = \"Relation::OrTropicalFruit.def()\"\n    )]\n    OrTropicalFruit,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/comment.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"comment\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub comment: String,\n    pub user_id: i32,\n    pub post_id: i32,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub user: HasOne<super::user::Entity>,\n    #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n    pub post: HasOne<super::post::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/entity_linked.rs",
    "content": "use crate::entity::prelude::*;\nuse sea_query::{Expr, ExprTrait, IntoCondition};\n\n#[derive(Debug)]\npub struct CakeToFilling;\n\nimpl Linked for CakeToFilling {\n    type FromEntity = super::cake::Entity;\n\n    type ToEntity = super::filling::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![\n            super::cake_filling::Relation::Cake.def().rev(),\n            super::cake_filling::Relation::Filling.def(),\n        ]\n    }\n}\n\n#[derive(Debug)]\npub struct CakeToFillingVendor;\n\nimpl Linked for CakeToFillingVendor {\n    type FromEntity = super::cake::Entity;\n\n    type ToEntity = super::vendor::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![\n            super::cake_filling::Relation::Cake.def().rev(),\n            super::cake_filling::Relation::Filling.def(),\n            super::filling::Relation::Vendor.def(),\n        ]\n    }\n}\n\n#[derive(Debug)]\npub struct CheeseCakeToFillingVendor;\n\nimpl Linked for CheeseCakeToFillingVendor {\n    type FromEntity = super::cake::Entity;\n\n    type ToEntity = super::vendor::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![\n            super::cake_filling::Relation::Cake\n                .def()\n                .on_condition(|left, _right| {\n                    Expr::col((left, super::cake::Column::Name))\n                        .like(\"%cheese%\")\n                        .into_condition()\n                })\n                .rev(),\n            super::cake_filling::Relation::Filling.def(),\n            super::filling::Relation::Vendor.def(),\n        ]\n    }\n}\n\n#[derive(Debug)]\npub struct CakeToCakeViaFilling;\n\nimpl Linked for CakeToCakeViaFilling {\n    type FromEntity = super::cake::Entity;\n\n    type ToEntity = super::cake::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![\n            super::cake_filling::Relation::Cake.def().rev(),\n            super::cake_filling::Relation::Filling.def(),\n            super::cake_filling::Relation::Filling.def().rev(),\n            super::cake_filling::Relation::Cake.def(),\n        ]\n    }\n}\n"
  },
  {
    "path": "src/tests_cfg/filling.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[cfg(feature = \"with-json\")]\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::compact_model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n#[sea_orm(table_name = \"filling\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub vendor_id: Option<i32>,\n    #[sea_orm(ignore)]\n    pub ignored_attr: i32,\n    pub ingredients: HasMany<super::ingredient::Entity>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::vendor::Entity\",\n        from = \"Column::VendorId\",\n        to = \"super::vendor::Column::Id\"\n    )]\n    Vendor,\n    #[sea_orm(has_many = \"super::ingredient::Entity\")]\n    Ingredient,\n}\n\nimpl Related<super::ingredient::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Ingredient.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Cake.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Filling.def().rev())\n    }\n}\n\nimpl Related<super::cake_compact::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cake_filling::Relation::Cake.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cake_filling::Relation::Filling.def().rev())\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/fruit.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[cfg(feature = \"with-json\")]\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::compact_model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n#[sea_orm(table_name = \"fruit\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    #[cfg_attr(feature = \"with-json\", serde(skip_deserializing))]\n    pub id: i32,\n    pub name: String,\n    pub cake_id: Option<i32>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\"\n    )]\n    Cake,\n    #[sea_orm(\n        belongs_to = \"super::cake_compact::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake_compact::Column::Id\"\n    )]\n    CakeCompact,\n    #[sea_orm(\n        belongs_to = \"super::cake_expanded::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake_expanded::Column::Id\"\n    )]\n    CakeExpanded,\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl Related<super::cake_compact::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::CakeCompact.def()\n    }\n}\n\nimpl Related<super::cake_expanded::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::CakeExpanded.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/indexes.rs",
    "content": "//! An entity definition for testing table index creation.\nuse crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(schema_name = \"public\", table_name = \"indexes\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub indexes_id: i32,\n    #[sea_orm(unique)]\n    pub unique_attr: i32,\n    #[sea_orm(indexed)]\n    pub index1_attr: i32,\n    #[sea_orm(unique, indexed)]\n    pub index2_attr: i32,\n    #[sea_orm(unique_key = \"my_unique\")]\n    pub unique_key_a: String,\n    #[sea_orm(unique_key = \"my_unique\")]\n    pub unique_key_b: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/ingredient.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[cfg(feature = \"with-json\")]\nuse serde::{Deserialize, Serialize};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n#[sea_orm(table_name = \"ingredient\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub filling_id: Option<i32>,\n    pub ingredient_id: Option<i32>,\n    #[sea_orm(belongs_to, from = \"filling_id\", to = \"id\")]\n    pub filling: HasOne<super::filling::Entity>,\n    #[sea_orm(\n        self_ref,\n        relation_enum = \"Ingredient\",\n        from = \"IngredientId\",\n        to = \"Id\"\n    )]\n    pub ingredient: HasOne<Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/lunch_set.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"lunch_set\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub tea: Tea,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/lunch_set_expanded.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> &'static str {\n        \"lunch_set\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\n#[sea_orm(table_name = \"lunch_set\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub tea: Tea,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n    Tea,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::None).def(),\n            Self::Tea => Tea::db_type().def(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        panic!(\"No RelationDef\")\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/mod.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\n//! Configurations for test cases and examples. Not intended for actual use.\n\n#[cfg(feature = \"entity-registry\")]\nmod registry;\n\npub mod cake;\npub mod cake_compact;\npub mod cake_expanded;\npub mod cake_filling;\npub mod cake_filling_price;\npub mod entity_linked;\npub mod filling;\npub mod fruit;\npub mod indexes;\npub mod ingredient;\npub mod lunch_set;\npub mod lunch_set_expanded;\npub mod rust_keyword;\npub mod sea_orm_active_enums;\n#[cfg(feature = \"with-json\")]\npub mod serde_rename;\npub mod vendor;\n\npub mod comment;\npub mod post;\npub mod post_tag;\npub mod profile;\npub mod tag;\npub mod user;\n\npub use cake::Entity as Cake;\npub use cake_filling::Entity as CakeFilling;\npub use cake_filling_price::Entity as CakeFillingPrice;\npub use filling::Entity as Filling;\npub use fruit::Entity as Fruit;\npub use lunch_set::Entity as LunchSet;\npub use lunch_set_expanded::Entity as LunchSetExpanded;\npub use rust_keyword::Entity as RustKeyword;\npub use vendor::Entity as Vendor;\n"
  },
  {
    "path": "src/tests_cfg/post.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"post\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub user_id: i32,\n    pub title: String,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub author: HasOne<super::user::Entity>,\n    #[sea_orm(has_many)]\n    pub comments: HasMany<super::comment::Entity>,\n    #[sea_orm(has_many, via = \"post_tag\")]\n    pub tags: HasMany<super::tag::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/post_tag.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n#[sea_orm(table_name = \"post_tag\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub post_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub tag_id: i32,\n    #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n    pub post: Option<super::post::Entity>,\n    #[sea_orm(belongs_to, from = \"tag_id\", to = \"id\")]\n    pub tag: Option<super::tag::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/profile.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"profile\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub picture: String,\n    #[sea_orm(unique)]\n    pub user_id: i32,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub user: HasOne<super::user::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/registry.rs",
    "content": "#[cfg(test)]\nmod test {\n    #[test]\n    fn test_entity_registry() {\n        let entities: Vec<_> = inventory::iter::<crate::EntityRegistry>().collect();\n\n        for target in [\n            \"sea_orm::tests_cfg::cake\",\n            \"sea_orm::tests_cfg::cake_compact\",\n            \"sea_orm::tests_cfg::cake_expanded\",\n            \"sea_orm::tests_cfg::cake_filling\",\n            \"sea_orm::tests_cfg::cake_filling_price\",\n            \"sea_orm::tests_cfg::filling\",\n            \"sea_orm::tests_cfg::fruit\",\n            \"sea_orm::tests_cfg::indexes\",\n            \"sea_orm::tests_cfg::ingredient\",\n            \"sea_orm::tests_cfg::lunch_set\",\n            \"sea_orm::tests_cfg::lunch_set_expanded\",\n            \"sea_orm::tests_cfg::rust_keyword\",\n            \"sea_orm::tests_cfg::vendor\",\n        ] {\n            if !entities.iter().any(|e| e.module_path == target) {\n                panic!(\"{target} not found\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/tests_cfg/rust_keyword.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"rust_keyword\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub testing: i32,\n    pub rust: i32,\n    pub keywords: i32,\n    pub r#raw_identifier: i32,\n    pub r#as: i32,\n    pub r#async: i32,\n    pub r#await: i32,\n    pub r#break: i32,\n    pub r#const: i32,\n    pub r#continue: i32,\n    pub crate_: i32,\n    pub r#dyn: i32,\n    pub r#else: i32,\n    pub r#enum: i32,\n    pub r#extern: i32,\n    pub r#false: i32,\n    pub r#fn: i32,\n    pub r#for: i32,\n    pub r#if: i32,\n    pub r#impl: i32,\n    pub r#in: i32,\n    pub r#let: i32,\n    pub r#loop: i32,\n    pub r#match: i32,\n    pub r#mod: i32,\n    pub r#move: i32,\n    pub r#mut: i32,\n    pub r#pub: i32,\n    pub r#ref: i32,\n    pub r#return: i32,\n    pub self_: i32,\n    pub r#static: i32,\n    pub r#struct: i32,\n    pub r#trait: i32,\n    pub r#true: i32,\n    pub r#type: i32,\n    pub r#union: i32,\n    pub r#unsafe: i32,\n    pub r#use: i32,\n    pub r#where: i32,\n    pub r#while: i32,\n    pub r#abstract: i32,\n    pub r#become: i32,\n    pub r#box: i32,\n    pub r#do: i32,\n    pub r#final: i32,\n    pub r#macro: i32,\n    pub r#override: i32,\n    pub r#priv: i32,\n    pub r#try: i32,\n    pub r#typeof: i32,\n    pub r#unsized: i32,\n    pub r#virtual: i32,\n    pub r#yield: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[cfg(test)]\nmod tests {\n    use crate::tests_cfg::rust_keyword::*;\n    use sea_query::Iden;\n\n    #[test]\n    fn test_columns() {\n        assert_eq!(Column::Id.to_string().as_str(), \"id\");\n        assert_eq!(Column::Testing.to_string().as_str(), \"testing\");\n        assert_eq!(Column::Rust.to_string().as_str(), \"rust\");\n        assert_eq!(Column::Keywords.to_string().as_str(), \"keywords\");\n        assert_eq!(Column::RawIdentifier.to_string().as_str(), \"raw_identifier\");\n        assert_eq!(Column::As.to_string().as_str(), \"as\");\n        assert_eq!(Column::Async.to_string().as_str(), \"async\");\n        assert_eq!(Column::Await.to_string().as_str(), \"await\");\n        assert_eq!(Column::Break.to_string().as_str(), \"break\");\n        assert_eq!(Column::Const.to_string().as_str(), \"const\");\n        assert_eq!(Column::Continue.to_string().as_str(), \"continue\");\n        assert_eq!(Column::Dyn.to_string().as_str(), \"dyn\");\n        assert_eq!(Column::Crate.to_string().as_str(), \"crate\");\n        assert_eq!(Column::Else.to_string().as_str(), \"else\");\n        assert_eq!(Column::Enum.to_string().as_str(), \"enum\");\n        assert_eq!(Column::Extern.to_string().as_str(), \"extern\");\n        assert_eq!(Column::False.to_string().as_str(), \"false\");\n        assert_eq!(Column::Fn.to_string().as_str(), \"fn\");\n        assert_eq!(Column::For.to_string().as_str(), \"for\");\n        assert_eq!(Column::If.to_string().as_str(), \"if\");\n        assert_eq!(Column::Impl.to_string().as_str(), \"impl\");\n        assert_eq!(Column::In.to_string().as_str(), \"in\");\n        assert_eq!(Column::Let.to_string().as_str(), \"let\");\n        assert_eq!(Column::Loop.to_string().as_str(), \"loop\");\n        assert_eq!(Column::Match.to_string().as_str(), \"match\");\n        assert_eq!(Column::Mod.to_string().as_str(), \"mod\");\n        assert_eq!(Column::Move.to_string().as_str(), \"move\");\n        assert_eq!(Column::Mut.to_string().as_str(), \"mut\");\n        assert_eq!(Column::Pub.to_string().as_str(), \"pub\");\n        assert_eq!(Column::Ref.to_string().as_str(), \"ref\");\n        assert_eq!(Column::Return.to_string().as_str(), \"return\");\n        assert_eq!(Column::Self_.to_string().as_str(), \"self\");\n        assert_eq!(Column::Static.to_string().as_str(), \"static\");\n        assert_eq!(Column::Struct.to_string().as_str(), \"struct\");\n        assert_eq!(Column::Trait.to_string().as_str(), \"trait\");\n        assert_eq!(Column::True.to_string().as_str(), \"true\");\n        assert_eq!(Column::Type.to_string().as_str(), \"type\");\n        assert_eq!(Column::Union.to_string().as_str(), \"union\");\n        assert_eq!(Column::Unsafe.to_string().as_str(), \"unsafe\");\n        assert_eq!(Column::Use.to_string().as_str(), \"use\");\n        assert_eq!(Column::Where.to_string().as_str(), \"where\");\n        assert_eq!(Column::While.to_string().as_str(), \"while\");\n        assert_eq!(Column::Abstract.to_string().as_str(), \"abstract\");\n        assert_eq!(Column::Become.to_string().as_str(), \"become\");\n        assert_eq!(Column::Box.to_string().as_str(), \"box\");\n        assert_eq!(Column::Do.to_string().as_str(), \"do\");\n        assert_eq!(Column::Final.to_string().as_str(), \"final\");\n        assert_eq!(Column::Macro.to_string().as_str(), \"macro\");\n        assert_eq!(Column::Override.to_string().as_str(), \"override\");\n        assert_eq!(Column::Priv.to_string().as_str(), \"priv\");\n        assert_eq!(Column::Try.to_string().as_str(), \"try\");\n        assert_eq!(Column::Typeof.to_string().as_str(), \"typeof\");\n        assert_eq!(Column::Unsized.to_string().as_str(), \"unsized\");\n        assert_eq!(Column::Virtual.to_string().as_str(), \"virtual\");\n        assert_eq!(Column::Yield.to_string().as_str(), \"yield\");\n    }\n}\n"
  },
  {
    "path": "src/tests_cfg/sea_orm_active_enums.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"tea\")]\npub enum Tea {\n    #[sea_orm(string_value = \"EverydayTea\")]\n    EverydayTea,\n    #[sea_orm(string_value = \"BreakfastTea\")]\n    BreakfastTea,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"String\", db_type = \"String(StringLen::None)\")]\npub enum SeaORM {\n    #[sea_orm(string_value = \"씨오알엠\")]\n    씨오알엠,\n}\n"
  },
  {
    "path": "src/tests_cfg/serde_rename.rs",
    "content": "#![allow(clippy::unwrap_used)]\nuse crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[cfg(feature = \"with-json\")]\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n#[sea_orm(table_name = \"user\")]\n#[cfg_attr(feature = \"with-json\", serde(rename_all = \"camelCase\"))]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub first_name: String,\n    pub last_name: String,\n    pub email: String,\n    pub is_admin: bool,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\npub mod field_rename {\n    use crate as sea_orm;\n    use sea_orm::entity::prelude::*;\n\n    #[cfg(feature = \"with-json\")]\n    use serde::{Deserialize, Serialize};\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n    #[sea_orm(table_name = \"order\")]\n    #[cfg_attr(\n        feature = \"with-json\",\n        serde(rename_all = \"camelCase\", rename = \"Model\")\n    )]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub order_date: String,\n        // #[serde(rename = \"...\")] applies to both serialize and deserialize\n        #[cfg_attr(feature = \"with-json\", serde(rename = \"order-id\"))]\n        pub order_id: String,\n        // serialize only - does not affect json_key (uses camelCase)\n        #[cfg_attr(feature = \"with-json\", serde(rename(serialize = \"serializedOnly\")))]\n        pub ser_only: String,\n        // deserialize only - affects json_key\n        #[cfg_attr(feature = \"with-json\", serde(rename(deserialize = \"deOnly\")))]\n        pub de_only: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod no_serde_rename {\n    use crate as sea_orm;\n    use sea_orm::entity::prelude::*;\n\n    #[cfg(feature = \"with-json\")]\n    use serde::{Deserialize, Serialize};\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n    #[sea_orm(table_name = \"legacy\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub field_name: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod directional_rename_all {\n    use crate as sea_orm;\n    use sea_orm::entity::prelude::*;\n\n    #[cfg(feature = \"with-json\")]\n    use serde::{Deserialize, Serialize};\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[cfg_attr(feature = \"with-json\", derive(Serialize, Deserialize))]\n    #[sea_orm(table_name = \"directional\")]\n    #[cfg_attr(\n        feature = \"with-json\",\n        serde(rename_all(serialize = \"SCREAMING_SNAKE_CASE\", deserialize = \"camelCase\"))\n    )]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub user_name: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[cfg(all(test, feature = \"with-json\"))]\nmod tests {\n    use super::*;\n    use crate::ActiveValue;\n    use crate::entity::ActiveModelTrait;\n\n    #[test]\n    fn test_rename_all() {\n        // json_key returns camelCase names\n        assert_eq!(Column::Id.json_key(), \"id\");\n        assert_eq!(Column::FirstName.json_key(), \"firstName\");\n        assert_eq!(Column::LastName.json_key(), \"lastName\");\n        assert_eq!(Column::Email.json_key(), \"email\");\n        assert_eq!(Column::IsAdmin.json_key(), \"isAdmin\");\n\n        // from_json uses camelCase keys\n        let json = serde_json::json!({\n            \"id\": 1,\n            \"firstName\": \"Max\",\n            \"lastName\": \"Hermit\",\n            \"email\": \"max@domain.com\",\n            \"isAdmin\": true,\n        });\n\n        let am = ActiveModel::from_json(json).unwrap();\n\n        assert_eq!(am.id, ActiveValue::Set(1));\n        assert_eq!(am.first_name, ActiveValue::Set(\"Max\".to_string()));\n        assert_eq!(am.last_name, ActiveValue::Set(\"Hermit\".to_string()));\n        assert_eq!(am.email, ActiveValue::Set(\"max@domain.com\".to_string()));\n        assert_eq!(am.is_admin, ActiveValue::Set(true));\n    }\n\n    #[test]\n    fn test_field_rename() {\n        use field_rename::{ActiveModel, Column};\n\n        // json_key behavior:\n        // - rename = \"...\" uses that name\n        // - rename(deserialize = \"...\") uses deserialize name\n        // - rename(serialize = \"...\") falls back to rename_all\n        assert_eq!(Column::Id.json_key(), \"id\");\n        assert_eq!(Column::OrderDate.json_key(), \"orderDate\");\n        assert_eq!(Column::OrderId.json_key(), \"order-id\");\n        assert_eq!(Column::SerOnly.json_key(), \"serOnly\"); // camelCase, not \"serializedOnly\"\n        assert_eq!(Column::DeOnly.json_key(), \"deOnly\");\n\n        // from_json uses deserialize names\n        let json = serde_json::json!({\n            \"id\": 1,\n            \"orderDate\": \"2024-01-01\",\n            \"order-id\": \"ORD123\",\n            \"serOnly\": \"ser-value\",\n            \"deOnly\": \"de-value\"\n        });\n\n        let am = ActiveModel::from_json(json).unwrap();\n\n        assert_eq!(am.id, ActiveValue::Set(1));\n        assert_eq!(am.order_date, ActiveValue::Set(\"2024-01-01\".to_string()));\n        assert_eq!(am.order_id, ActiveValue::Set(\"ORD123\".to_string()));\n        assert_eq!(am.ser_only, ActiveValue::Set(\"ser-value\".to_string()));\n        assert_eq!(am.de_only, ActiveValue::Set(\"de-value\".to_string()));\n    }\n\n    #[test]\n    fn test_no_serde_rename() {\n        use no_serde_rename::{ActiveModel, Column};\n\n        assert_eq!(Column::Id.json_key(), \"id\");\n        assert_eq!(Column::FieldName.json_key(), \"field_name\");\n\n        let json = serde_json::json!({\n            \"id\": 1,\n            \"field_name\": \"value\"\n        });\n\n        let am = ActiveModel::from_json(json).unwrap();\n\n        assert_eq!(am.id, ActiveValue::Set(1));\n        assert_eq!(am.field_name, ActiveValue::Set(\"value\".to_string()));\n    }\n\n    #[test]\n    fn test_directional_rename_all() {\n        use directional_rename_all::{ActiveModel, Column, Model};\n\n        assert_eq!(Column::Id.json_key(), \"id\");\n        assert_eq!(Column::UserName.json_key(), \"userName\");\n\n        let json = serde_json::json!({\n            \"id\": 1,\n            \"userName\": \"test_user\"\n        });\n\n        let am = ActiveModel::from_json(json).unwrap();\n\n        assert_eq!(am.id, ActiveValue::Set(1));\n        assert_eq!(am.user_name, ActiveValue::Set(\"test_user\".to_string()));\n    }\n}\n"
  },
  {
    "path": "src/tests_cfg/tag.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"tag\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub tag: String,\n    #[sea_orm(has_many, via = \"post_tag\")]\n    pub posts: HasMany<super::post::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/user.rs",
    "content": "use crate as sea_orm;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"user\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(unique)]\n    pub email: String,\n    #[sea_orm(has_one)]\n    pub profile: HasOne<super::profile::Entity>,\n    #[sea_orm(has_many)]\n    pub posts: HasMany<super::post::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/tests_cfg/vendor.rs",
    "content": "use crate as sea_orm;\nuse crate::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"vendor\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl Related<super::filling::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::filling::Relation::Vendor.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "src/util.rs",
    "content": "/// Uses the `log` crate to perform logging.\n/// This must be enabled using the feature flag `debug-print`.\n/// ### Usage\n/// ```\n/// use sea_orm::debug_print;\n///\n/// #[derive(Debug)]\n/// enum FooError {\n///     Bar,\n///     Baz,\n/// }\n///\n/// debug_print!(\"{:?}\", FooError::Bar);\n/// ```\n#[macro_export]\n#[cfg(feature = \"debug-print\")]\nmacro_rules! debug_print {\n    ($( $args:expr ),*) => { tracing::debug!( $( $args ),* ); }\n}\n\n#[macro_export]\n/// Non-debug version\n#[cfg(not(feature = \"debug-print\"))]\nmacro_rules! debug_print {\n    ($( $args:expr ),*) => {\n        true;\n    };\n}\n\n#[cfg(all(test, feature = \"sync\"))]\npub trait StreamShim<T> {\n    fn try_next(&mut self) -> Result<Option<T>, crate::DbErr>;\n}\n\n#[cfg(all(test, feature = \"sync\"))]\nimpl<I, T> StreamShim<T> for I\nwhere\n    I: Iterator<Item = Result<T, crate::DbErr>>,\n{\n    fn try_next(&mut self) -> Result<Option<T>, crate::DbErr> {\n        self.next().transpose()\n    }\n}\n"
  },
  {
    "path": "src/value/text_uuid.rs",
    "content": "use std::ops::{Deref, DerefMut};\n\nuse sea_query::{ValueType, ValueTypeErr};\n\nuse crate::TryGetable;\nuse crate::{self as sea_orm, TryFromU64};\nuse crate::{DbErr, TryGetError};\n\n/// Newtype making sure that UUIDs will be stored as `TEXT` columns,\n/// instead of `BLOB` (which is the default).\n/// Advantages:\n/// - TEXT makes it easier to interact with the SQLite DB directly\n/// - Allows for queries like `WHERE id IN (<uuid>, <uuid>, ...)` which are\n///   impossible to write with `BLOB` values\n#[derive(Clone, Debug, PartialEq, Eq, Copy)]\npub struct TextUuid(pub uuid::Uuid);\n\nimpl From<TextUuid> for sea_query::Value {\n    fn from(value: TextUuid) -> Self {\n        value.0.to_string().into()\n    }\n}\n\nimpl TryGetable for TextUuid {\n    fn try_get_by<I: sea_orm::ColIdx>(\n        res: &sea_orm::QueryResult,\n        index: I,\n    ) -> Result<Self, sea_orm::TryGetError> {\n        let uuid_str: String = res.try_get_by(index)?;\n        let uuid = uuid::Uuid::parse_str(&uuid_str).map_err(|e| {\n            TryGetError::DbErr(DbErr::Type(format!(\"Failed to parse string as UUID: {e}\")))\n        })?;\n        Ok(TextUuid(uuid))\n    }\n}\n\nimpl ValueType for TextUuid {\n    fn try_from(v: sea_orm::Value) -> Result<Self, ValueTypeErr> {\n        match v {\n            sea_orm::Value::String(Some(s)) => {\n                let uuid = uuid::Uuid::parse_str(&s).map_err(|_| ValueTypeErr)?;\n                Ok(TextUuid(uuid))\n            }\n            _ => Err(ValueTypeErr),\n        }\n    }\n\n    fn type_name() -> String {\n        \"TextUuid\".to_string()\n    }\n\n    fn array_type() -> sea_query::ArrayType {\n        <String as sea_query::ValueType>::array_type()\n    }\n\n    fn column_type() -> sea_orm::ColumnType {\n        <String as sea_query::ValueType>::column_type()\n    }\n}\n\n// This seems to be required when using TextUuid as a primary key\nimpl TryFromU64 for TextUuid {\n    fn try_from_u64(_n: u64) -> Result<Self, sea_orm::DbErr> {\n        Err(sea_orm::DbErr::ConvertFromU64(\"TextUuid\"))\n    }\n}\n\nimpl sea_query::Nullable for TextUuid {\n    fn null() -> sea_orm::Value {\n        <String as sea_query::Nullable>::null()\n    }\n}\n\nimpl sea_orm::IntoActiveValue<TextUuid> for TextUuid {\n    fn into_active_value(self) -> crate::ActiveValue<TextUuid> {\n        sea_orm::ActiveValue::Set(self)\n    }\n}\n\nimpl Deref for TextUuid {\n    type Target = uuid::Uuid;\n\n    fn deref(&self) -> &uuid::Uuid {\n        &self.0\n    }\n}\n\nimpl DerefMut for TextUuid {\n    fn deref_mut(&mut self) -> &mut uuid::Uuid {\n        &mut self.0\n    }\n}\n\nimpl From<uuid::Uuid> for TextUuid {\n    fn from(value: uuid::Uuid) -> Self {\n        TextUuid(value)\n    }\n}\n\nimpl From<TextUuid> for uuid::Uuid {\n    fn from(value: TextUuid) -> Self {\n        value.0\n    }\n}\n"
  },
  {
    "path": "src/value/timestamp.rs",
    "content": "macro_rules! impl_timestamp {\n    ($ty:ident, $inner:ident, $from:ident, $to:ident) => {\n        impl std::convert::From<$inner> for $ty {\n            fn from(value: $inner) -> Self {\n                Self(value)\n            }\n        }\n\n        impl std::convert::From<$ty> for sea_orm::Value {\n            fn from(source: $ty) -> Self {\n                $to(source).into()\n            }\n        }\n\n        impl sea_orm::TryGetable for $ty {\n            fn try_get_by<I: sea_orm::ColIdx>(\n                res: &sea_orm::QueryResult,\n                idx: I,\n            ) -> std::result::Result<Self, TryGetError> {\n                let ts = <i64 as sea_orm::TryGetable>::try_get_by(res, idx)?;\n                $from(ts).ok_or(TryGetError::DbErr(DbErr::Type(\n                    \"Failed to convert i64 to timestamp\".to_owned(),\n                )))\n            }\n        }\n\n        impl sea_orm::sea_query::ValueType for $ty {\n            fn try_from(\n                v: sea_orm::Value,\n            ) -> std::result::Result<Self, sea_orm::sea_query::ValueTypeErr> {\n                let ts = <i64 as sea_orm::sea_query::ValueType>::try_from(v)?;\n                $from(ts).ok_or(sea_orm::sea_query::ValueTypeErr)\n            }\n\n            fn type_name() -> std::string::String {\n                stringify!($ty).to_owned()\n            }\n\n            fn array_type() -> sea_orm::sea_query::ArrayType {\n                <i64 as sea_orm::sea_query::ValueType>::array_type()\n            }\n\n            fn column_type() -> sea_orm::sea_query::ColumnType {\n                <i64 as sea_orm::sea_query::ValueType>::column_type()\n            }\n        }\n\n        impl sea_orm::sea_query::Nullable for $ty {\n            fn null() -> sea_orm::Value {\n                <i64 as sea_orm::sea_query::Nullable>::null()\n            }\n        }\n\n        impl sea_orm::IntoActiveValue<$ty> for $ty {\n            fn into_active_value(self) -> sea_orm::ActiveValue<$ty> {\n                sea_orm::ActiveValue::Set(self)\n            }\n        }\n\n        impl Deref for $ty {\n            type Target = $inner;\n\n            fn deref(&self) -> &Self::Target {\n                &self.0\n            }\n        }\n\n        impl DerefMut for $ty {\n            fn deref_mut(&mut self) -> &mut Self::Target {\n                &mut self.0\n            }\n        }\n\n        impl PartialEq<$inner> for $ty {\n            fn eq(&self, other: &$inner) -> bool {\n                self.0.eq(other)\n            }\n        }\n    };\n}\n\npub(super) use impl_timestamp;\n"
  },
  {
    "path": "src/value/with_chrono.rs",
    "content": "use super::impl_timestamp;\nuse crate as sea_orm;\nuse crate::{DbErr, TryGetError, prelude::ChronoDateTimeUtc};\nuse std::ops::{Deref, DerefMut};\n\n/// A DataTime<Utc> mapped to i64 in database\n#[derive(derive_more::Debug, Copy, Clone, PartialEq, Eq, Hash)]\n#[debug(\"{_0:?}\")]\npub struct ChronoUnixTimestamp(pub ChronoDateTimeUtc);\n\n/// A DataTime<Utc> mapped to i64 in database, but in milliseconds\n#[derive(derive_more::Debug, Copy, Clone, PartialEq, Eq, Hash)]\n#[debug(\"{_0:?}\")]\npub struct ChronoUnixTimestampMillis(pub ChronoDateTimeUtc);\n\nimpl_timestamp!(\n    ChronoUnixTimestamp,\n    ChronoDateTimeUtc,\n    from_timestamp,\n    to_timestamp\n);\n\nimpl_timestamp!(\n    ChronoUnixTimestampMillis,\n    ChronoDateTimeUtc,\n    from_timestamp_millis,\n    to_timestamp_millis\n);\n\nfn from_timestamp(ts: i64) -> Option<ChronoUnixTimestamp> {\n    ChronoDateTimeUtc::from_timestamp(ts, 0).map(ChronoUnixTimestamp)\n}\n\nfn to_timestamp(ts: ChronoUnixTimestamp) -> i64 {\n    ts.0.timestamp()\n}\n\nfn from_timestamp_millis(ts: i64) -> Option<ChronoUnixTimestampMillis> {\n    ChronoDateTimeUtc::from_timestamp_millis(ts).map(ChronoUnixTimestampMillis)\n}\n\nfn to_timestamp_millis(ts: ChronoUnixTimestampMillis) -> i64 {\n    ts.0.timestamp_millis()\n}\n"
  },
  {
    "path": "src/value/with_time.rs",
    "content": "use super::impl_timestamp;\nuse crate as sea_orm;\nuse crate::{DbErr, TryGetError, prelude::TimeDateTimeWithTimeZone};\nuse std::ops::{Deref, DerefMut};\n\n/// A OffsetDateTime mapped to i64 in database\n#[derive(derive_more::Debug, Copy, Clone, PartialEq, Eq, Hash)]\n#[debug(\"{_0:?}\")]\npub struct TimeUnixTimestamp(pub TimeDateTimeWithTimeZone);\n\n/// A OffsetDateTime mapped to i64 in database, but in milliseconds\n#[derive(derive_more::Debug, Copy, Clone, PartialEq, Eq, Hash)]\n#[debug(\"{_0:?}\")]\npub struct TimeUnixTimestampMillis(pub TimeDateTimeWithTimeZone);\n\nimpl_timestamp!(\n    TimeUnixTimestamp,\n    TimeDateTimeWithTimeZone,\n    from_timestamp,\n    to_timestamp\n);\n\nimpl_timestamp!(\n    TimeUnixTimestampMillis,\n    TimeDateTimeWithTimeZone,\n    from_timestamp_millis,\n    to_timestamp_millis\n);\n\nfn from_timestamp(ts: i64) -> Option<TimeUnixTimestamp> {\n    TimeDateTimeWithTimeZone::from_unix_timestamp(ts)\n        .ok()\n        .map(TimeUnixTimestamp)\n}\n\nfn to_timestamp(ts: TimeUnixTimestamp) -> i64 {\n    ts.0.unix_timestamp()\n}\n\nfn from_timestamp_millis(ts: i64) -> Option<TimeUnixTimestampMillis> {\n    TimeDateTimeWithTimeZone::from_unix_timestamp_nanos(ts as i128 * 1_000_000)\n        .ok()\n        .map(TimeUnixTimestampMillis)\n}\n\nfn to_timestamp_millis(ts: TimeUnixTimestampMillis) -> i64 {\n    (ts.0.unix_timestamp_nanos() / 1_000_000) as i64\n}\n"
  },
  {
    "path": "src/value.rs",
    "content": "use crate::sea_query::{Nullable, ValueType};\nuse crate::{ActiveValue, Value};\n\nmod timestamp;\nuse timestamp::*;\n\n#[cfg(feature = \"with-chrono\")]\nmod with_chrono;\n#[cfg(feature = \"with-chrono\")]\npub use with_chrono::*;\n\n#[cfg(feature = \"with-time\")]\nmod with_time;\n#[cfg(feature = \"with-time\")]\npub use with_time::*;\n\n#[cfg(feature = \"with-uuid\")]\nmod text_uuid;\n#[cfg(feature = \"with-uuid\")]\npub use text_uuid::*;\n\n/// Default value for T\npub trait DefaultActiveValue {\n    /// `Default::default()` if implemented, dummy value otherwise\n    fn default_value(&self) -> Self;\n}\n\n/// Default value for Option<T>\npub trait DefaultActiveValueNone {\n    /// Always `None`\n    fn default_value(&self) -> Self;\n}\n\n/// Default value for types that's not nullable\npub trait DefaultActiveValueNotSet {\n    /// The owned value type\n    type Value;\n\n    /// Always `NotSet`\n    fn default_value(&self) -> Self::Value;\n}\n\nimpl<V> DefaultActiveValue for ActiveValue<V>\nwhere\n    V: Into<Value> + ValueType + Nullable,\n{\n    fn default_value(&self) -> Self {\n        match V::try_from(V::null().dummy_value()) {\n            Ok(v) => ActiveValue::Set(v),\n            Err(_) => ActiveValue::NotSet,\n        }\n    }\n}\n\nimpl<V> DefaultActiveValueNone for ActiveValue<Option<V>>\nwhere\n    V: Into<Value> + Nullable,\n{\n    fn default_value(&self) -> Self {\n        ActiveValue::Set(None)\n    }\n}\n\nimpl<V> DefaultActiveValueNotSet for &ActiveValue<V>\nwhere\n    V: Into<Value>,\n{\n    type Value = ActiveValue<V>;\n\n    fn default_value(&self) -> Self::Value {\n        ActiveValue::NotSet\n    }\n}\n\n#[cfg(test)]\nmod test {\n    use super::*;\n    use crate::prelude::TimeDateTime;\n\n    #[test]\n    fn test_default_value() {\n        let v = (&ActiveValue::<i32>::NotSet).default_value();\n        assert_eq!(v, ActiveValue::Set(0));\n\n        let v = (&ActiveValue::<Option<i32>>::NotSet).default_value();\n        assert_eq!(v, ActiveValue::Set(None));\n\n        let v = (&ActiveValue::<String>::NotSet).default_value();\n        assert_eq!(v, ActiveValue::Set(\"\".to_owned()));\n\n        let v = (&ActiveValue::<Option<String>>::NotSet).default_value();\n        assert_eq!(v, ActiveValue::Set(None));\n\n        let v = (&ActiveValue::<TimeDateTime>::NotSet).default_value();\n        assert!(matches!(v, ActiveValue::Set(_)));\n    }\n}\n"
  },
  {
    "path": "tests/active_enum_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse active_enum::Entity as ActiveEnumEntity;\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\n#[cfg(feature = \"sqlx-postgres\")]\nuse sea_orm::QueryTrait;\nuse sea_orm::{\n    ActiveEnum as ActiveEnumTrait, DatabaseConnection, DbErr, FromQueryResult, QueryFilter,\n    QuerySelect,\n    entity::*,\n    sea_query::{BinOper, Expr, ExprTrait},\n};\n\n#[sea_orm_macros::test]\nasync fn active_enum_tests() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"active_enum_tests\").await;\n    create_tea_enum(&ctx.db).await?;\n    create_active_enum_table(&ctx.db).await?;\n    create_active_enum_child_table(&ctx.db).await?;\n    #[cfg(feature = \"sqlx-postgres\")]\n    create_categories_table(&ctx.db).await?;\n\n    insert_active_enum(&ctx.db).await?;\n    insert_active_enum_child(&ctx.db).await?;\n\n    #[cfg(feature = \"sqlx-postgres\")]\n    insert_active_enum_vec(&ctx.db).await?;\n\n    find_related_active_enum(&ctx.db).await?;\n    find_linked_active_enum(&ctx.db).await?;\n\n    delete_active_enum(&ctx.db).await?;\n\n    ctx.delete().await;\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn active_enum_schema_sync_test() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"active_enum_schema_sync_test\").await;\n    let db = &ctx.db;\n\n    let mut schema_builder = db.get_schema_builder().register(active_enum::Entity);\n\n    #[cfg(feature = \"sqlx-postgres\")]\n    {\n        schema_builder = schema_builder\n            .register(active_enum_child::Entity)\n            .register(categories::Entity);\n    }\n\n    #[cfg(not(feature = \"schema-sync\"))]\n    schema_builder.apply(db).await?;\n\n    #[cfg(feature = \"schema-sync\")]\n    schema_builder.sync(db).await?;\n\n    insert_active_enum(&ctx.db).await?;\n    #[cfg(feature = \"sqlx-postgres\")]\n    insert_active_enum_vec(&ctx.db).await?;\n\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn insert_active_enum(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use active_enum::*;\n\n    let model = Model {\n        id: 1,\n        category: None,\n        color: None,\n        tea: None,\n    };\n\n    assert_eq!(\n        model,\n        ActiveModel {\n            category: Set(None),\n            color: Set(None),\n            tea: Set(None),\n            ..Default::default()\n        }\n        .insert(db)\n        .await?\n    );\n    assert_eq!(model, Entity::find().one(db).await?.unwrap());\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.is_not_null())\n            .filter(Column::Category.is_null())\n            .filter(Column::Color.is_null())\n            .filter(Column::Tea.is_null())\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    let _ = ActiveModel {\n        category: Set(Some(Category::Big)),\n        color: Set(Some(Color::Black)),\n        tea: Set(Some(Tea::EverydayTea)),\n        ..model.into_active_model()\n    }\n    .save(db)\n    .await?;\n\n    let model = Entity::find().one(db).await?.unwrap();\n    assert_eq!(\n        model,\n        Model {\n            id: 1,\n            category: Some(Category::Big),\n            color: Some(Color::Black),\n            tea: Some(Tea::EverydayTea),\n        }\n    );\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.eq(1))\n            .filter(Column::Category.eq(Category::Big))\n            .filter(Column::Color.eq(Color::Black))\n            .filter(Column::Tea.eq(Tea::EverydayTea))\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    #[derive(Debug, FromQueryResult, PartialEq)]\n    struct SelectResult {\n        tea_alias: Option<Tea>,\n    }\n\n    assert_eq!(\n        SelectResult {\n            tea_alias: Some(Tea::EverydayTea),\n        },\n        Entity::find()\n            .select_only()\n            .column_as(Column::Tea, \"tea_alias\")\n            .into_model()\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    assert_eq!(\n        serde_json::json!({\n            \"id\": 1,\n            \"category\": \"B\",\n            \"color\": 0,\n            \"tea\": \"EverydayTea\",\n        }),\n        Entity::find().into_json().one(db).await?.unwrap()\n    );\n\n    assert_eq!(\n        serde_json::json!({\n            \"tea_alias\": \"EverydayTea\",\n        }),\n        Entity::find()\n            .select_only()\n            .column_as(Column::Tea, \"tea_alias\")\n            .into_json()\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Expr::col(Column::Tea).binary(\n                BinOper::In,\n                Expr::tuple([ActiveEnumTrait::as_enum(&Tea::EverydayTea)])\n            ))\n            .one(db)\n            .await?\n            .unwrap()\n    );\n    // Equivalent to the above.\n    let select_with_tea_in =\n        Entity::find().filter(Column::Tea.is_in([Tea::EverydayTea, Tea::BreakfastTea]));\n    #[cfg(feature = \"sqlx-postgres\")]\n    assert_eq!(\n        select_with_tea_in\n            .build(sea_orm::DatabaseBackend::Postgres)\n            .to_string(),\n        [\n            r#\"SELECT \"active_enum\".\"id\",\"#,\n            r#\"\"active_enum\".\"category\",\"#,\n            r#\"\"active_enum\".\"color\",\"#,\n            r#\"CAST(\"active_enum\".\"tea\" AS \"text\")\"#,\n            r#\"FROM \"public\".\"active_enum\"\"#,\n            r#\"WHERE \"active_enum\".\"tea\" IN (CAST('EverydayTea' AS \"tea\"), CAST('BreakfastTea' AS \"tea\"))\"#,\n        ]\n        .join(\" \")\n    );\n    assert_eq!(model, select_with_tea_in.one(db).await?.unwrap());\n\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Tea.is_not_null())\n            .filter(Expr::col(Column::Tea).binary(\n                BinOper::NotIn,\n                Expr::tuple([ActiveEnumTrait::as_enum(&Tea::BreakfastTea)])\n            ))\n            .one(db)\n            .await?\n            .unwrap()\n    );\n    // Equivalent to the above.\n    let select_with_tea_not_in = Entity::find()\n        .filter(Column::Tea.is_not_null())\n        .filter(Column::Tea.is_not_in([Tea::BreakfastTea]));\n\n    #[cfg(feature = \"sqlx-postgres\")]\n    assert_eq!(\n        select_with_tea_not_in\n            .build(sea_orm::DatabaseBackend::Postgres)\n            .to_string(),\n        [\n            r#\"SELECT \"active_enum\".\"id\",\"#,\n            r#\"\"active_enum\".\"category\",\"#,\n            r#\"\"active_enum\".\"color\",\"#,\n            r#\"CAST(\"active_enum\".\"tea\" AS \"text\")\"#,\n            r#\"FROM \"public\".\"active_enum\"\"#,\n            r#\"WHERE \"active_enum\".\"tea\" IS NOT NULL\"#,\n            r#\"AND \"active_enum\".\"tea\" NOT IN (CAST('BreakfastTea' AS \"tea\"))\"#,\n        ]\n        .join(\" \")\n    );\n\n    assert_eq!(model, select_with_tea_not_in.one(db).await?.unwrap());\n\n    // String enums should be compared alphabetically in all supported DBs.\n    // 'B' < 'S', so Big is considered \"smaller\" than Small.\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Category.lt(Category::Small))\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    // Integer enums should be compared by value in all supported DBs.\n    // 0 <= 1, so Black is considered \"smaller or equal to\" White.\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Color.lte(Color::White))\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    // Native enum comparisons are not portable.\n    //\n    // Postgres enums are compared by their definition order\n    // (see https://www.postgresql.org/docs/current/datatype-enum.html#DATATYPE-ENUM-ORDERING).\n    // Tea was defined as ('EverydayTea', 'BreakfastTea'), so EverydayTea is considered \"smaller\" than BreakfastTea.\n    //\n    // SQLite doesn't support enum types and SeaORM works around this limitation by storing them as strings.\n    // When treated as strings, EverydayTea is not \"smaller\" than BreakfastTea!\n    //\n    // MySQL should be the same as Postgres (see https://dev.mysql.com/doc/refman/8.0/en/enum.html#enum-sorting),\n    // but in practice this test case behaves like SQLite. I'm not sure why.\n    #[cfg(feature = \"sqlx-postgres\")]\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Tea.lt(Tea::BreakfastTea))\n            .one(db)\n            .await?\n            .unwrap()\n    );\n    #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n    assert_eq!(\n        None,\n        Entity::find()\n            .filter(Column::Tea.lt(Tea::BreakfastTea))\n            .one(db)\n            .await?\n    );\n\n    let res = model.delete(db).await?;\n\n    assert_eq!(res.rows_affected, 1);\n    assert_eq!(Entity::find().one(db).await?, None);\n\n    Ok(())\n}\n\npub async fn insert_active_enum_child(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use active_enum_child::*;\n\n    active_enum::ActiveModel {\n        category: Set(Some(Category::Small)),\n        color: Set(Some(Color::White)),\n        tea: Set(Some(Tea::BreakfastTea)),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    let am = ActiveModel {\n        parent_id: Set(2),\n        category: Set(None),\n        color: Set(None),\n        tea: Set(None),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    let model = Entity::find().one(db).await?.unwrap();\n    assert_eq!(\n        model,\n        Model {\n            id: 1,\n            parent_id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        }\n    );\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.is_not_null())\n            .filter(Column::Category.is_null())\n            .filter(Column::Color.is_null())\n            .filter(Column::Tea.is_null())\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    ActiveModel {\n        category: Set(Some(Category::Big)),\n        color: Set(Some(Color::Black)),\n        tea: Set(Some(Tea::EverydayTea)),\n        ..am.into_active_model()\n    }\n    .save(db)\n    .await?;\n\n    let model = Entity::find().one(db).await?.unwrap();\n    assert_eq!(\n        model,\n        Model {\n            id: 1,\n            parent_id: 2,\n            category: Some(Category::Big),\n            color: Some(Color::Black),\n            tea: Some(Tea::EverydayTea),\n        }\n    );\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.eq(1))\n            .filter(Column::Category.eq(Category::Big))\n            .filter(Column::Color.eq(Color::Black))\n            .filter(Column::Tea.eq(Tea::EverydayTea))\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    Ok(())\n}\n\npub async fn insert_active_enum_vec(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use categories::*;\n\n    let model = Model {\n        id: 1,\n        categories: None,\n    };\n\n    assert_eq!(\n        model,\n        ActiveModel {\n            id: Set(1),\n            categories: Set(None),\n            ..Default::default()\n        }\n        .insert(db)\n        .await?\n    );\n    assert_eq!(model, Entity::find().one(db).await?.unwrap());\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.is_not_null())\n            .filter(Column::Categories.is_null())\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    let _ = ActiveModel {\n        id: Set(1),\n        categories: Set(Some(vec![Category::Big, Category::Small])),\n        ..model.into_active_model()\n    }\n    .save(db)\n    .await?;\n\n    let model = Entity::find().one(db).await?.unwrap();\n    assert_eq!(\n        model,\n        Model {\n            id: 1,\n            categories: Some(vec![Category::Big, Category::Small]),\n        }\n    );\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.eq(1))\n            .filter(Expr::cust_with_values(\n                r#\"$1 = ANY(\"categories\")\"#,\n                vec![Category::Big]\n            ))\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    let res = model.delete(db).await?;\n\n    assert_eq!(res.rows_affected, 1);\n    assert_eq!(Entity::find().one(db).await?, None);\n\n    Ok(())\n}\n\npub async fn find_related_active_enum(db: &DatabaseConnection) -> Result<(), DbErr> {\n    assert_eq!(\n        active_enum::Model {\n            id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        }\n        .find_related(ActiveEnumChild)\n        .all(db)\n        .await?,\n        [active_enum_child::Model {\n            id: 1,\n            parent_id: 2,\n            category: Some(Category::Big),\n            color: Some(Color::Black),\n            tea: Some(Tea::EverydayTea),\n        }]\n    );\n    assert_eq!(\n        ActiveEnumEntity::find()\n            .find_with_related(ActiveEnumChild)\n            .all(db)\n            .await?,\n        [(\n            active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            },\n            vec![active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            }]\n        )]\n    );\n    assert_eq!(\n        ActiveEnumEntity::find()\n            .find_also_related(ActiveEnumChild)\n            .all(db)\n            .await?,\n        [(\n            active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            },\n            Some(active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            })\n        )]\n    );\n\n    assert_eq!(\n        active_enum_child::Model {\n            id: 1,\n            parent_id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        }\n        .find_related(ActiveEnum)\n        .all(db)\n        .await?,\n        [active_enum::Model {\n            id: 2,\n            category: Some(Category::Small),\n            color: Some(Color::White),\n            tea: Some(Tea::BreakfastTea),\n        }]\n    );\n    assert_eq!(\n        ActiveEnumChild::find()\n            .find_with_related(ActiveEnum)\n            .all(db)\n            .await?,\n        [(\n            active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            },\n            vec![active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            }]\n        )]\n    );\n    assert_eq!(\n        ActiveEnumChild::find()\n            .find_also_related(ActiveEnum)\n            .all(db)\n            .await?,\n        [(\n            active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            },\n            Some(active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            })\n        )]\n    );\n\n    Ok(())\n}\n\npub async fn find_linked_active_enum(db: &DatabaseConnection) -> Result<(), DbErr> {\n    assert_eq!(\n        active_enum::Model {\n            id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        }\n        .find_linked(active_enum::ActiveEnumChildLink)\n        .all(db)\n        .await?,\n        [active_enum_child::Model {\n            id: 1,\n            parent_id: 2,\n            category: Some(Category::Big),\n            color: Some(Color::Black),\n            tea: Some(Tea::EverydayTea),\n        }]\n    );\n    assert_eq!(\n        ActiveEnumEntity::find()\n            .find_also_linked(active_enum::ActiveEnumChildLink)\n            .all(db)\n            .await?,\n        [(\n            active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            },\n            Some(active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            })\n        )]\n    );\n    assert_eq!(\n        ActiveEnumEntity::find()\n            .find_with_linked(active_enum::ActiveEnumChildLink)\n            .all(db)\n            .await?,\n        [(\n            active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            },\n            vec![active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            }]\n        )]\n    );\n\n    assert_eq!(\n        active_enum_child::Model {\n            id: 1,\n            parent_id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        }\n        .find_linked(active_enum_child::ActiveEnumLink)\n        .all(db)\n        .await?,\n        [active_enum::Model {\n            id: 2,\n            category: Some(Category::Small),\n            color: Some(Color::White),\n            tea: Some(Tea::BreakfastTea),\n        }]\n    );\n    assert_eq!(\n        ActiveEnumChild::find()\n            .find_also_linked(active_enum_child::ActiveEnumLink)\n            .all(db)\n            .await?,\n        [(\n            active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            },\n            Some(active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            })\n        )]\n    );\n    assert_eq!(\n        ActiveEnumChild::find()\n            .find_with_linked(active_enum_child::ActiveEnumLink)\n            .all(db)\n            .await?,\n        [(\n            active_enum_child::Model {\n                id: 1,\n                parent_id: 2,\n                category: Some(Category::Big),\n                color: Some(Color::Black),\n                tea: Some(Tea::EverydayTea),\n            },\n            vec![active_enum::Model {\n                id: 2,\n                category: Some(Category::Small),\n                color: Some(Color::White),\n                tea: Some(Tea::BreakfastTea),\n            }]\n        )]\n    );\n\n    Ok(())\n}\n\nasync fn delete_active_enum(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use active_enum_child::*;\n\n    if db.get_database_backend().support_returning() {\n        let model = Entity::find().one(db).await?.unwrap();\n\n        assert_eq!(model.id, 1);\n\n        assert_eq!(\n            model,\n            Entity::delete(model.clone().into_active_model())\n                .exec_with_returning(db)\n                .await?\n                .unwrap()\n        );\n    }\n\n    Ok(())\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    pub use pretty_assertions::assert_eq;\n    pub use sea_orm::{DbBackend, QueryTrait};\n\n    #[test]\n    fn active_enum_find_related() {\n        let active_enum_model = active_enum::Model {\n            id: 1,\n            category: None,\n            color: None,\n            tea: None,\n        };\n        let _select = active_enum_model.find_related(ActiveEnumChild);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select.build(DbBackend::Sqlite).to_string(),\n                [\n                    r#\"SELECT \"active_enum_child\".\"id\", \"active_enum_child\".\"parent_id\", \"active_enum_child\".\"category\", \"active_enum_child\".\"color\", \"active_enum_child\".\"tea\"\"#,\n                    r#\"FROM \"active_enum_child\"\"#,\n                    r#\"INNER JOIN \"active_enum\" ON \"active_enum\".\"id\" = \"active_enum_child\".\"parent_id\"\"#,\n                    r#\"WHERE \"active_enum\".\"id\" = 1\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select.build(DbBackend::MySql).to_string(),\n                [\n                    \"SELECT `active_enum_child`.`id`, `active_enum_child`.`parent_id`, `active_enum_child`.`category`, `active_enum_child`.`color`, `active_enum_child`.`tea`\",\n                    \"FROM `active_enum_child`\",\n                    \"INNER JOIN `active_enum` ON `active_enum`.`id` = `active_enum_child`.`parent_id`\",\n                    \"WHERE `active_enum`.`id` = 1\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select.build(DbBackend::Postgres).to_string(),\n            [\n                r#\"SELECT \"active_enum_child\".\"id\", \"active_enum_child\".\"parent_id\", \"active_enum_child\".\"category\", \"active_enum_child\".\"color\", CAST(\"active_enum_child\".\"tea\" AS \"text\")\"#,\n                r#\"FROM \"public\".\"active_enum_child\"\"#,\n                r#\"INNER JOIN \"public\".\"active_enum\" ON \"active_enum\".\"id\" = \"active_enum_child\".\"parent_id\"\"#,\n                r#\"WHERE \"active_enum\".\"id\" = 1\"#,\n            ]\n            .join(\" \")\n        );\n\n        let _select = ActiveEnumEntity::find().find_also_related(ActiveEnumChild);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select\n                    .build(DbBackend::Sqlite)\n                    .to_string(),\n                [\n                    r#\"SELECT \"active_enum\".\"id\" AS \"A_id\", \"active_enum\".\"category\" AS \"A_category\", \"active_enum\".\"color\" AS \"A_color\", \"active_enum\".\"tea\" AS \"A_tea\",\"#,\n                    r#\"\"active_enum_child\".\"id\" AS \"B_id\", \"active_enum_child\".\"parent_id\" AS \"B_parent_id\", \"active_enum_child\".\"category\" AS \"B_category\", \"active_enum_child\".\"color\" AS \"B_color\", \"active_enum_child\".\"tea\" AS \"B_tea\"\"#,\n                    r#\"FROM \"active_enum\"\"#,\n                    r#\"LEFT JOIN \"active_enum_child\" ON \"active_enum\".\"id\" = \"active_enum_child\".\"parent_id\"\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select\n                    .build(DbBackend::MySql)\n                    .to_string(),\n                [\n                    \"SELECT `active_enum`.`id` AS `A_id`, `active_enum`.`category` AS `A_category`, `active_enum`.`color` AS `A_color`, `active_enum`.`tea` AS `A_tea`,\",\n                    \"`active_enum_child`.`id` AS `B_id`, `active_enum_child`.`parent_id` AS `B_parent_id`, `active_enum_child`.`category` AS `B_category`, `active_enum_child`.`color` AS `B_color`, `active_enum_child`.`tea` AS `B_tea`\",\n                    \"FROM `active_enum`\",\n                    \"LEFT JOIN `active_enum_child` ON `active_enum`.`id` = `active_enum_child`.`parent_id`\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select\n                .build(DbBackend::Postgres)\n                .to_string(),\n            [\n                r#\"SELECT \"active_enum\".\"id\" AS \"A_id\", \"active_enum\".\"category\" AS \"A_category\", \"active_enum\".\"color\" AS \"A_color\", CAST(\"active_enum\".\"tea\" AS \"text\") AS \"A_tea\",\"#,\n                r#\"\"active_enum_child\".\"id\" AS \"B_id\", \"active_enum_child\".\"parent_id\" AS \"B_parent_id\", \"active_enum_child\".\"category\" AS \"B_category\", \"active_enum_child\".\"color\" AS \"B_color\", CAST(\"active_enum_child\".\"tea\" AS \"text\") AS \"B_tea\"\"#,\n                r#\"FROM \"public\".\"active_enum\"\"#,\n                r#\"LEFT JOIN \"public\".\"active_enum_child\" ON \"active_enum\".\"id\" = \"active_enum_child\".\"parent_id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn active_enum_find_linked() {\n        let active_enum_model = active_enum::Model {\n            id: 1,\n            category: None,\n            color: None,\n            tea: None,\n        };\n        let _select = active_enum_model.find_linked(active_enum::ActiveEnumChildLink);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select.build(DbBackend::Sqlite).to_string(),\n                [\n                    r#\"SELECT \"active_enum_child\".\"id\", \"active_enum_child\".\"parent_id\", \"active_enum_child\".\"category\", \"active_enum_child\".\"color\", \"active_enum_child\".\"tea\"\"#,\n                    r#\"FROM \"active_enum_child\"\"#,\n                    r#\"INNER JOIN \"active_enum\" AS \"r0\" ON \"r0\".\"id\" = \"active_enum_child\".\"parent_id\"\"#,\n                    r#\"WHERE \"r0\".\"id\" = 1\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select.build(DbBackend::MySql).to_string(),\n                [\n                    \"SELECT `active_enum_child`.`id`, `active_enum_child`.`parent_id`, `active_enum_child`.`category`, `active_enum_child`.`color`, `active_enum_child`.`tea`\",\n                    \"FROM `active_enum_child`\",\n                    \"INNER JOIN `active_enum` AS `r0` ON `r0`.`id` = `active_enum_child`.`parent_id`\",\n                    \"WHERE `r0`.`id` = 1\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select.build(DbBackend::Postgres).to_string(),\n            [\n                r#\"SELECT \"active_enum_child\".\"id\", \"active_enum_child\".\"parent_id\", \"active_enum_child\".\"category\", \"active_enum_child\".\"color\", CAST(\"active_enum_child\".\"tea\" AS \"text\")\"#,\n                r#\"FROM \"public\".\"active_enum_child\"\"#,\n                r#\"INNER JOIN \"public\".\"active_enum\" AS \"r0\" ON \"r0\".\"id\" = \"active_enum_child\".\"parent_id\"\"#,\n                r#\"WHERE \"r0\".\"id\" = 1\"#,\n            ]\n            .join(\" \")\n        );\n\n        let _select = ActiveEnumEntity::find().find_also_linked(active_enum::ActiveEnumChildLink);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select\n                    .build(DbBackend::Sqlite)\n                    .to_string(),\n                [\n                    r#\"SELECT \"active_enum\".\"id\" AS \"A_id\", \"active_enum\".\"category\" AS \"A_category\", \"active_enum\".\"color\" AS \"A_color\", \"active_enum\".\"tea\" AS \"A_tea\",\"#,\n                    r#\"\"r0\".\"id\" AS \"B_id\", \"r0\".\"parent_id\" AS \"B_parent_id\", \"r0\".\"category\" AS \"B_category\", \"r0\".\"color\" AS \"B_color\", \"r0\".\"tea\" AS \"B_tea\"\"#,\n                    r#\"FROM \"active_enum\"\"#,\n                    r#\"LEFT JOIN \"active_enum_child\" AS \"r0\" ON \"active_enum\".\"id\" = \"r0\".\"parent_id\"\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select\n                    .build(DbBackend::MySql)\n                    .to_string(),\n                [\n                    \"SELECT `active_enum`.`id` AS `A_id`, `active_enum`.`category` AS `A_category`, `active_enum`.`color` AS `A_color`, `active_enum`.`tea` AS `A_tea`,\",\n                    \"`r0`.`id` AS `B_id`, `r0`.`parent_id` AS `B_parent_id`, `r0`.`category` AS `B_category`, `r0`.`color` AS `B_color`, `r0`.`tea` AS `B_tea`\",\n                    \"FROM `active_enum`\",\n                    \"LEFT JOIN `active_enum_child` AS `r0` ON `active_enum`.`id` = `r0`.`parent_id`\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select\n                .build(DbBackend::Postgres)\n                .to_string(),\n            [\n                r#\"SELECT \"active_enum\".\"id\" AS \"A_id\", \"active_enum\".\"category\" AS \"A_category\", \"active_enum\".\"color\" AS \"A_color\", CAST(\"active_enum\".\"tea\" AS \"text\") AS \"A_tea\",\"#,\n                r#\"\"r0\".\"id\" AS \"B_id\", \"r0\".\"parent_id\" AS \"B_parent_id\", \"r0\".\"category\" AS \"B_category\", \"r0\".\"color\" AS \"B_color\", CAST(\"r0\".\"tea\" AS \"text\") AS \"B_tea\"\"#,\n                r#\"FROM \"public\".\"active_enum\"\"#,\n                r#\"LEFT JOIN \"public\".\"active_enum_child\" AS \"r0\" ON \"active_enum\".\"id\" = \"r0\".\"parent_id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn active_enum_child_find_related() {\n        let active_enum_child_model = active_enum_child::Model {\n            id: 1,\n            parent_id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        };\n        let _select = active_enum_child_model.find_related(ActiveEnum);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select.build(DbBackend::Sqlite).to_string(),\n                [\n                    r#\"SELECT \"active_enum\".\"id\", \"active_enum\".\"category\", \"active_enum\".\"color\", \"active_enum\".\"tea\"\"#,\n                    r#\"FROM \"active_enum\"\"#,\n                    r#\"INNER JOIN \"active_enum_child\" ON \"active_enum_child\".\"parent_id\" = \"active_enum\".\"id\"\"#,\n                    r#\"WHERE \"active_enum_child\".\"id\" = 1\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select.build(DbBackend::MySql).to_string(),\n                [\n                    \"SELECT `active_enum`.`id`, `active_enum`.`category`, `active_enum`.`color`, `active_enum`.`tea`\",\n                    \"FROM `active_enum`\",\n                    \"INNER JOIN `active_enum_child` ON `active_enum_child`.`parent_id` = `active_enum`.`id`\",\n                    \"WHERE `active_enum_child`.`id` = 1\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select.build(DbBackend::Postgres).to_string(),\n            [\n                r#\"SELECT \"active_enum\".\"id\", \"active_enum\".\"category\", \"active_enum\".\"color\", CAST(\"active_enum\".\"tea\" AS \"text\")\"#,\n                r#\"FROM \"public\".\"active_enum\"\"#,\n                r#\"INNER JOIN \"public\".\"active_enum_child\" ON \"active_enum_child\".\"parent_id\" = \"active_enum\".\"id\"\"#,\n                r#\"WHERE \"active_enum_child\".\"id\" = 1\"#,\n            ]\n            .join(\" \")\n        );\n\n        let _select = ActiveEnumChild::find().find_also_related(ActiveEnum);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select\n                    .build(DbBackend::Sqlite)\n                    .to_string(),\n                [\n                    r#\"SELECT \"active_enum_child\".\"id\" AS \"A_id\", \"active_enum_child\".\"parent_id\" AS \"A_parent_id\", \"active_enum_child\".\"category\" AS \"A_category\", \"active_enum_child\".\"color\" AS \"A_color\", \"active_enum_child\".\"tea\" AS \"A_tea\",\"#,\n                    r#\"\"active_enum\".\"id\" AS \"B_id\", \"active_enum\".\"category\" AS \"B_category\", \"active_enum\".\"color\" AS \"B_color\", \"active_enum\".\"tea\" AS \"B_tea\"\"#,\n                    r#\"FROM \"active_enum_child\"\"#,\n                    r#\"LEFT JOIN \"active_enum\" ON \"active_enum_child\".\"parent_id\" = \"active_enum\".\"id\"\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select\n                    .build(DbBackend::MySql)\n                    .to_string(),\n                [\n                    \"SELECT `active_enum_child`.`id` AS `A_id`, `active_enum_child`.`parent_id` AS `A_parent_id`, `active_enum_child`.`category` AS `A_category`, `active_enum_child`.`color` AS `A_color`, `active_enum_child`.`tea` AS `A_tea`,\",\n                    \"`active_enum`.`id` AS `B_id`, `active_enum`.`category` AS `B_category`, `active_enum`.`color` AS `B_color`, `active_enum`.`tea` AS `B_tea`\",\n                    \"FROM `active_enum_child`\",\n                    \"LEFT JOIN `active_enum` ON `active_enum_child`.`parent_id` = `active_enum`.`id`\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select\n                .build(DbBackend::Postgres)\n                .to_string(),\n            [\n                r#\"SELECT \"active_enum_child\".\"id\" AS \"A_id\", \"active_enum_child\".\"parent_id\" AS \"A_parent_id\", \"active_enum_child\".\"category\" AS \"A_category\", \"active_enum_child\".\"color\" AS \"A_color\", CAST(\"active_enum_child\".\"tea\" AS \"text\") AS \"A_tea\",\"#,\n                r#\"\"active_enum\".\"id\" AS \"B_id\", \"active_enum\".\"category\" AS \"B_category\", \"active_enum\".\"color\" AS \"B_color\", CAST(\"active_enum\".\"tea\" AS \"text\") AS \"B_tea\"\"#,\n                r#\"FROM \"public\".\"active_enum_child\"\"#,\n                r#\"LEFT JOIN \"public\".\"active_enum\" ON \"active_enum_child\".\"parent_id\" = \"active_enum\".\"id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn active_enum_child_find_linked() {\n        let active_enum_child_model = active_enum_child::Model {\n            id: 1,\n            parent_id: 2,\n            category: None,\n            color: None,\n            tea: None,\n        };\n        let _select = active_enum_child_model.find_linked(active_enum_child::ActiveEnumLink);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select.build(DbBackend::Sqlite).to_string(),\n                [\n                    r#\"SELECT \"active_enum\".\"id\", \"active_enum\".\"category\", \"active_enum\".\"color\", \"active_enum\".\"tea\"\"#,\n                    r#\"FROM \"active_enum\"\"#,\n                    r#\"INNER JOIN \"active_enum_child\" AS \"r0\" ON \"r0\".\"parent_id\" = \"active_enum\".\"id\"\"#,\n                    r#\"WHERE \"r0\".\"id\" = 1\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select.build(DbBackend::MySql).to_string(),\n                [\n                    \"SELECT `active_enum`.`id`, `active_enum`.`category`, `active_enum`.`color`, `active_enum`.`tea`\",\n                    \"FROM `active_enum`\",\n                    \"INNER JOIN `active_enum_child` AS `r0` ON `r0`.`parent_id` = `active_enum`.`id`\",\n                    \"WHERE `r0`.`id` = 1\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select.build(DbBackend::Postgres).to_string(),\n            [\n                r#\"SELECT \"active_enum\".\"id\", \"active_enum\".\"category\", \"active_enum\".\"color\", CAST(\"active_enum\".\"tea\" AS \"text\")\"#,\n                r#\"FROM \"public\".\"active_enum\"\"#,\n                r#\"INNER JOIN \"public\".\"active_enum_child\" AS \"r0\" ON \"r0\".\"parent_id\" = \"active_enum\".\"id\"\"#,\n                r#\"WHERE \"r0\".\"id\" = 1\"#,\n            ]\n            .join(\" \")\n        );\n\n        let _select = ActiveEnumChild::find().find_also_linked(active_enum_child::ActiveEnumLink);\n        #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n        {\n            assert_eq!(\n                _select\n                    .build(DbBackend::Sqlite)\n                    .to_string(),\n                [\n                    r#\"SELECT \"active_enum_child\".\"id\" AS \"A_id\", \"active_enum_child\".\"parent_id\" AS \"A_parent_id\", \"active_enum_child\".\"category\" AS \"A_category\", \"active_enum_child\".\"color\" AS \"A_color\", \"active_enum_child\".\"tea\" AS \"A_tea\",\"#,\n                    r#\"\"r0\".\"id\" AS \"B_id\", \"r0\".\"category\" AS \"B_category\", \"r0\".\"color\" AS \"B_color\", \"r0\".\"tea\" AS \"B_tea\"\"#,\n                    r#\"FROM \"active_enum_child\"\"#,\n                    r#\"LEFT JOIN \"active_enum\" AS \"r0\" ON \"active_enum_child\".\"parent_id\" = \"r0\".\"id\"\"#,\n                ]\n                .join(\" \")\n            );\n            assert_eq!(\n                _select\n                    .build(DbBackend::MySql)\n                    .to_string(),\n                [\n                    \"SELECT `active_enum_child`.`id` AS `A_id`, `active_enum_child`.`parent_id` AS `A_parent_id`, `active_enum_child`.`category` AS `A_category`, `active_enum_child`.`color` AS `A_color`, `active_enum_child`.`tea` AS `A_tea`,\",\n                    \"`r0`.`id` AS `B_id`, `r0`.`category` AS `B_category`, `r0`.`color` AS `B_color`, `r0`.`tea` AS `B_tea`\",\n                    \"FROM `active_enum_child`\",\n                    \"LEFT JOIN `active_enum` AS `r0` ON `active_enum_child`.`parent_id` = `r0`.`id`\",\n                ]\n                .join(\" \")\n            );\n        }\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert_eq!(\n            _select\n                .build(DbBackend::Postgres)\n                .to_string(),\n            [\n                r#\"SELECT \"active_enum_child\".\"id\" AS \"A_id\", \"active_enum_child\".\"parent_id\" AS \"A_parent_id\", \"active_enum_child\".\"category\" AS \"A_category\", \"active_enum_child\".\"color\" AS \"A_color\", CAST(\"active_enum_child\".\"tea\" AS \"text\") AS \"A_tea\",\"#,\n                r#\"\"r0\".\"id\" AS \"B_id\", \"r0\".\"category\" AS \"B_category\", \"r0\".\"color\" AS \"B_color\", CAST(\"r0\".\"tea\" AS \"text\") AS \"B_tea\"\"#,\n                r#\"FROM \"public\".\"active_enum_child\"\"#,\n                r#\"LEFT JOIN \"public\".\"active_enum\" AS \"r0\" ON \"active_enum_child\".\"parent_id\" = \"r0\".\"id\"\"#,\n            ]\n            .join(\" \")\n        );\n    }\n\n    #[test]\n    fn create_enum_from() {\n        use sea_orm::{Schema, Statement};\n\n        let db_postgres = DbBackend::Postgres;\n        let schema = Schema::new(db_postgres);\n\n        assert_eq!(\n            schema\n                .create_enum_from_entity(active_enum::Entity)\n                .iter()\n                .map(|stmt| db_postgres.build(stmt))\n                .collect::<Vec<_>>(),\n            [Statement::from_string(\n                db_postgres,\n                r#\"CREATE TYPE \"tea\" AS ENUM ('EverydayTea', 'BreakfastTea', 'AfternoonTea')\"#\n                    .to_owned()\n            ),]\n        );\n\n        assert_eq!(\n            db_postgres.build(&schema.create_enum_from_active_enum::<Tea>().unwrap()),\n            Statement::from_string(\n                db_postgres,\n                r#\"CREATE TYPE \"tea\" AS ENUM ('EverydayTea', 'BreakfastTea', 'AfternoonTea')\"#\n                    .to_owned()\n            )\n        );\n    }\n\n    #[test]\n    fn display_test() {\n        assert_eq!(format!(\"{}\", Tea::BreakfastTea), \"BreakfastTea\");\n        assert_eq!(format!(\"{}\", DisplayTea::BreakfastTea), \"Breakfast\");\n        assert_eq!(format!(\"{}\", Tea::EverydayTea), \"EverydayTea\");\n        assert_eq!(format!(\"{}\", DisplayTea::EverydayTea), \"Everyday\");\n    }\n\n    #[cfg(feature = \"sqlx-postgres\")]\n    #[test]\n    fn derive_partial_model_active_enum_casts_to_text() {\n        use sea_orm::*;\n        use sea_query::PostgresQueryBuilder;\n\n        #[derive(Debug, DerivePartialModel)]\n        #[sea_orm(entity = \"active_enum::Entity\")]\n        struct PartialWithEnum {\n            tea: Option<Tea>,\n        }\n\n        let sql = active_enum::Entity::find()\n            .into_partial_model::<PartialWithEnum>()\n            .into_statement(DbBackend::Postgres)\n            .sql;\n\n        assert_eq!(\n            sql,\n            r#\"SELECT CAST(\"active_enum\".\"tea\" AS \"text\") AS \"tea\" FROM \"public\".\"active_enum\"\"#,\n        );\n\n        #[derive(Debug, DerivePartialModel)]\n        #[sea_orm(entity = \"active_enum::Entity\", from_query_result, alias = \"zzz\")]\n        struct PartialWithEnumAndAlias {\n            #[sea_orm(from_col = \"tea\")]\n            foo: Option<Tea>,\n        }\n\n        let sql = active_enum::Entity::find()\n            .into_partial_model::<PartialWithEnumAndAlias>()\n            .into_statement(DbBackend::Postgres)\n            .sql;\n\n        assert_eq!(\n            sql,\n            r#\"SELECT CAST(\"zzz\".\"tea\" AS \"text\") AS \"foo\" FROM \"public\".\"active_enum\"\"#,\n        );\n\n        #[derive(Debug, DerivePartialModel)]\n        #[sea_orm(entity = \"active_enum::Entity\", from_query_result)]\n        struct PartialWithEnumNested {\n            tea: Option<Tea>,\n            #[sea_orm(nested, alias = \"foo\")]\n            nested: Option<PartialWithEnum>,\n        }\n\n        let sql = active_enum::Entity::find()\n            .into_partial_model::<PartialWithEnumNested>()\n            .into_statement(DbBackend::Postgres)\n            .sql;\n\n        assert_eq!(\n            sql,\n            r#\"SELECT CAST(\"active_enum\".\"tea\" AS \"text\") AS \"tea\", CAST(\"foo\".\"tea\" AS \"text\") AS \"nested_tea\" FROM \"public\".\"active_enum\"\"#,\n        );\n\n        #[derive(Debug, DerivePartialModel)]\n        #[sea_orm(entity = \"active_enum::Entity\", from_query_result, alias = \"aaa\")]\n        struct PartialWithEnumNestedWithAlias {\n            tea: Option<Tea>,\n            #[sea_orm(nested, alias = \"foo\")]\n            nested: Option<PartialWithEnum>,\n        }\n\n        let sql = active_enum::Entity::find()\n            .into_partial_model::<PartialWithEnumNestedWithAlias>()\n            .into_statement(DbBackend::Postgres)\n            .sql;\n\n        assert_eq!(\n            sql,\n            r#\"SELECT CAST(\"aaa\".\"tea\" AS \"text\") AS \"tea\", CAST(\"foo\".\"tea\" AS \"text\") AS \"nested_tea\" FROM \"public\".\"active_enum\"\"#,\n        );\n    }\n}\n"
  },
  {
    "path": "tests/active_model_ex_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\nmod common;\n\nuse crate::common::TestContext;\nuse sea_orm::{Database, DbConn, DbErr, entity::*, prelude::*, query::*};\nuse tracing::info;\n\n#[sea_orm_macros::test]\nasync fn test_active_model_ex_blog() -> Result<(), DbErr> {\n    use common::blogger::*;\n\n    let ctx = TestContext::new(\"test_active_model_ex_blog\").await;\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(user::Entity)\n        .register(user_follower::Entity)\n        .register(profile::Entity)\n        .register(post::Entity)\n        .register(post_tag::Entity)\n        .register(tag::Entity)\n        .register(attachment::Entity)\n        .register(comment::Entity)\n        .apply(db)\n        .await?;\n\n    info!(\"save a new user\");\n    let user = user::ActiveModel::builder()\n        .set_name(\"Alice\")\n        .set_email(\"@1\")\n        .save(db)\n        .await?;\n\n    assert_eq!(user.id, Unchanged(1));\n\n    info!(\"save a post with an existing user\");\n    let post = post::ActiveModel::builder()\n        .set_title(\"post 1\")\n        .set_author(user)\n        .save(db)\n        .await?;\n\n    assert_eq!(\n        post,\n        post::ActiveModelEx {\n            id: Unchanged(1),\n            user_id: Unchanged(1),\n            title: Unchanged(\"post 1\".into()),\n            author: HasOneModel::set(user::ActiveModelEx {\n                id: Unchanged(1),\n                name: Unchanged(\"Alice\".into()),\n                email: Unchanged(\"@1\".into()),\n                profile: HasOneModel::NotSet,\n                posts: HasManyModel::NotSet,\n                followers: HasManyModel::NotSet,\n                following: HasManyModel::NotSet,\n            }),\n            comments: HasManyModel::NotSet,\n            attachments: HasManyModel::NotSet,\n            tags: HasManyModel::NotSet,\n        }\n    );\n\n    info!(\"save a post with a new user\");\n    let post = post::ActiveModel::builder()\n        .set_title(\"post 2\")\n        .set_author(user::ActiveModel::builder().set_name(\"Bob\").set_email(\"@2\"))\n        .save(db)\n        .await?;\n\n    if false {\n        post::ActiveModelEx {\n            title: Set(\"post 2\".into()),\n            author: HasOneModel::set(user::ActiveModelEx {\n                name: Set(\"Bob\".into()),\n                email: Set(\"@2\".into()),\n                ..Default::default()\n            }),\n            ..Default::default()\n        };\n    }\n\n    assert_eq!(\n        post,\n        post::ActiveModelEx {\n            id: Unchanged(2),\n            user_id: Unchanged(2),\n            title: Unchanged(\"post 2\".into()),\n            author: HasOneModel::set(user::ActiveModelEx {\n                id: Unchanged(2),\n                name: Unchanged(\"Bob\".into()),\n                email: Unchanged(\"@2\".into()),\n                ..Default::default()\n            }),\n            ..Default::default()\n        }\n    );\n\n    info!(\"save a new user with a new profile\");\n    let user = user::ActiveModel::builder()\n        .set_name(\"Sam\")\n        .set_email(\"@3\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Sam.jpg\"))\n        .save(db)\n        .await?;\n\n    if false {\n        user::ActiveModelEx {\n            name: Set(\"Sam\".into()),\n            email: Set(\"@3\".into()),\n            profile: HasOneModel::set(profile::ActiveModelEx {\n                picture: Set(\"Sam.jpg\".into()),\n                ..Default::default()\n            }),\n            ..Default::default()\n        };\n    }\n\n    assert_eq!(\n        user,\n        user::ActiveModelEx {\n            id: Unchanged(3),\n            name: Unchanged(\"Sam\".into()),\n            email: Unchanged(\"@3\".into()),\n            profile: HasOneModel::set(profile::ActiveModelEx {\n                id: Unchanged(1),\n                picture: Unchanged(\"Sam.jpg\".into()),\n                user_id: Unchanged(3),\n                user: HasOneModel::NotSet,\n            }),\n            ..Default::default()\n        }\n    );\n\n    info!(\"save a new user with a new profile and 2 posts\");\n    let mut user = user::ActiveModel::builder()\n        .set_name(\"Alan\")\n        .set_email(\"@4\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Alan.jpg\"))\n        .add_post(post::ActiveModel::builder().set_title(\"post 3\"))\n        .add_post(post::ActiveModel::builder().set_title(\"post 4\"))\n        .save(db)\n        .await?;\n\n    assert_eq!(\n        user,\n        user::ActiveModelEx {\n            id: Unchanged(4),\n            name: Unchanged(\"Alan\".into()),\n            email: Unchanged(\"@4\".into()),\n            profile: HasOneModel::set(profile::ActiveModelEx {\n                id: Unchanged(2),\n                picture: Unchanged(\"Alan.jpg\".into()),\n                user_id: Unchanged(4),\n                user: HasOneModel::NotSet,\n            }),\n            posts: HasManyModel::Append(vec![\n                post::ActiveModelEx {\n                    id: Unchanged(3),\n                    user_id: Unchanged(4),\n                    title: Unchanged(\"post 3\".into()),\n                    ..Default::default()\n                },\n                post::ActiveModelEx {\n                    id: Unchanged(4),\n                    user_id: Unchanged(4),\n                    title: Unchanged(\"post 4\".into()),\n                    ..Default::default()\n                },\n            ]),\n            followers: HasManyModel::NotSet,\n            following: HasManyModel::NotSet,\n        }\n    );\n\n    let posts = user.find_related(post::Entity).all(db).await?;\n    assert_eq!(posts.len(), 2);\n    assert_eq!(posts[0].id, 3);\n    assert_eq!(posts[1].id, 4);\n\n    info!(\"replace posts of user: delete 3,4; insert 5 with attachment\");\n    user.posts = HasManyModel::Replace(vec![post::ActiveModelEx {\n        title: Set(\"post 5\".into()),\n        attachments: HasManyModel::Append(vec![attachment::ActiveModelEx {\n            file: Set(\"for post 5\".into()),\n            ..Default::default()\n        }]),\n        ..Default::default()\n    }]);\n\n    let mut user = user.save(db).await?;\n\n    let posts = user.find_related(post::Entity).all(db).await?;\n    assert_eq!(posts.len(), 1);\n    assert_eq!(posts[0].id, 5);\n    let attachments = posts[0].find_related(attachment::Entity).all(db).await?;\n    assert_eq!(attachments.len(), 1);\n    assert_eq!(attachments[0].id, 1);\n    assert_eq!(attachments[0].file, \"for post 5\");\n\n    info!(\"insert attachment for later use\");\n    let attachment_6 = attachment::ActiveModel::builder()\n        .set_file(\"for post 6\")\n        .save(db)\n        .await?;\n\n    info!(\"add new post to user: insert 6 and attach existing attachment\");\n    user.posts = HasManyModel::Append(vec![post::ActiveModelEx {\n        title: Set(\"post 6\".into()),\n        attachments: HasManyModel::Append(vec![attachment_6]),\n        ..Default::default()\n    }]);\n\n    let mut user = user.save(db).await?;\n\n    let posts = user.find_related(post::Entity).all(db).await?;\n    assert_eq!(posts.len(), 2);\n    assert_eq!(posts[0].id, 5);\n    assert_eq!(posts[1].id, 6);\n    let attachments = posts[1].find_related(attachment::Entity).all(db).await?;\n    assert_eq!(attachments.len(), 1);\n    assert_eq!(attachments[0].file, \"for post 6\");\n\n    info!(\"update post 6 through user\");\n    user.posts[0].title = Set(\"post 6!\".into());\n\n    let mut user = user.save(db).await?;\n\n    let posts = user.find_related(post::Entity).all(db).await?;\n    assert_eq!(posts.len(), 2);\n    assert_eq!(posts[0].id, 5);\n    assert_eq!(posts[0].title, \"post 5\");\n    assert_eq!(posts[1].id, 6);\n    assert_eq!(posts[1].title, \"post 6!\");\n\n    info!(\"update user profile and delete all posts\");\n    user.profile.as_mut().unwrap().picture = Set(\"Alan2.jpg\".into());\n    // user.posts = HasManyModel::Replace(vec![]);\n    user.posts.replace_all([]);\n    user.save(db).await?;\n\n    info!(\"check that user has 0 posts\");\n    let user = user::Entity::load()\n        .filter_by_id(4)\n        .with(profile::Entity)\n        .with(post::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(\n        user,\n        user::ModelEx {\n            id: 4,\n            name: \"Alan\".into(),\n            email: \"@4\".into(),\n            profile: HasOne::loaded(profile::Model {\n                id: 2,\n                picture: \"Alan2.jpg\".into(),\n                user_id: 4,\n            }),\n            posts: HasMany::Loaded(vec![]),\n            followers: HasMany::Unloaded,\n            following: HasMany::Unloaded,\n        }\n    );\n\n    info!(\"check that attachment still exists\");\n    let attachment_1 = attachment::Entity::find_by_id(1).one(db).await?.unwrap();\n    assert_eq!(attachment_1.file, \"for post 5\");\n    assert!(attachment_1.post_id.is_none());\n\n    info!(\"insert one tag for later use\");\n    let day = tag::ActiveModel {\n        tag: Set(\"day\".into()),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    info!(\"insert new post and set 2 tags\");\n    let post_ = post::ActiveModelEx {\n        id: NotSet,\n        user_id: NotSet,\n        title: Set(\"post 7\".into()),\n        author: HasOneModel::set(user.clone().into_active_model()),\n        comments: HasManyModel::NotSet,\n        attachments: HasManyModel::NotSet,\n        tags: HasManyModel::Append(vec![\n            day.clone().into_active_model().into(),\n            tag::ActiveModel {\n                id: NotSet,\n                tag: Set(\"pet\".into()),\n            }\n            .into(),\n        ]),\n    };\n\n    let post = post::ActiveModel::builder()\n        .set_title(\"post 7\")\n        .set_author(user.into_active_model())\n        .add_tag(day.into_active_model())\n        .add_tag(tag::ActiveModel::builder().set_tag(\"pet\"));\n\n    assert_eq!(post, post_);\n\n    let post = post.save(db).await?;\n\n    assert_eq!(\n        post,\n        post::ActiveModelEx {\n            id: Unchanged(7),\n            user_id: Unchanged(4),\n            title: Unchanged(\"post 7\".into()),\n            author: HasOneModel::set(user::ActiveModelEx {\n                id: Unchanged(4),\n                name: Unchanged(\"Alan\".into()),\n                email: Unchanged(\"@4\".into()),\n                profile: HasOneModel::set(profile::ActiveModelEx {\n                    id: Unchanged(2),\n                    picture: Unchanged(\"Alan2.jpg\".into()),\n                    user_id: Unchanged(4),\n                    user: HasOneModel::NotSet,\n                }),\n                posts: HasManyModel::Append(vec![]),\n                followers: HasManyModel::NotSet,\n                following: HasManyModel::NotSet,\n            }),\n            comments: HasManyModel::NotSet,\n            attachments: HasManyModel::NotSet,\n            tags: HasManyModel::Append(vec![\n                tag::ActiveModel {\n                    id: Unchanged(1),\n                    tag: Unchanged(\"day\".into()),\n                }\n                .into(),\n                tag::ActiveModel {\n                    id: Unchanged(2),\n                    tag: Unchanged(\"pet\".into()),\n                }\n                .into(),\n            ]),\n        }\n    );\n\n    info!(\"replace should be idempotent\");\n    let mut post = post.save(db).await?;\n\n    info!(\"append should be idempotent\");\n    post.tags.convert_to_append();\n    let mut post = post.save(db).await?;\n\n    info!(\"get back the post and tags\");\n    let post_7 = post::Entity::load()\n        .filter_by_id(7)\n        .with(tag::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(post_7.id, 7);\n    assert_eq!(post_7.tags.len(), 2);\n    assert_eq!(post_7.tags[0].tag, \"day\");\n    assert_eq!(post_7.tags[1].tag, \"pet\");\n\n    info!(\"add attachment to post\");\n    let mut post_7 = post_7.into_active_model();\n    post_7.attachments.push(attachment::ActiveModel {\n        file: Set(\"for post 7\".into()),\n        ..Default::default()\n    });\n    post_7.insert(db).await?;\n\n    info!(\"get back the post and attachment\");\n    let post_7 = post::Entity::load()\n        .filter_by_id(7)\n        .with(attachment::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(post_7.attachments.len(), 1);\n    assert_eq!(post_7.attachments[0].file, \"for post 7\");\n\n    info!(\"update user profile through post\");\n    post.author\n        .as_mut()\n        .unwrap()\n        .profile\n        .as_mut()\n        .unwrap()\n        .picture = Set(\"Alan3.jpg\".into());\n    let mut post = post.save(db).await?;\n    assert_eq!(\n        profile::Entity::find_by_id(2)\n            .one(db)\n            .await?\n            .unwrap()\n            .picture,\n        \"Alan3.jpg\"\n    );\n\n    info!(\"replace post tags: remove tag 1 add tag 3\");\n    post.tags = HasManyModel::Replace(vec![\n        tag::ActiveModel {\n            id: NotSet, // new tag\n            tag: Set(\"food\".into()),\n        }\n        .into(),\n        tag::ActiveModel {\n            id: Unchanged(2), // retain\n            tag: Unchanged(\"pet\".into()),\n        }\n        .into(),\n    ]);\n    let mut post = post.save(db).await?;\n\n    info!(\"get back the post and tags\");\n    let post_7 = post::Entity::load()\n        .filter_by_id(7)\n        .with(tag::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(post_7.id, 7);\n    assert_eq!(post_7.tags.len(), 2);\n    assert_eq!(post_7.tags[0].tag, \"pet\");\n    assert_eq!(post_7.tags[1].tag, \"food\");\n\n    info!(\"update post title and add new tag\");\n    post.title = Set(\"post 7!\".into());\n    post.tags = HasManyModel::Append(vec![\n        tag::ActiveModel {\n            id: NotSet, // new tag\n            tag: Set(\"sunny\".into()),\n        }\n        .into(),\n    ]);\n    post.save(db).await?;\n\n    info!(\"get back the post and tags\");\n    let post_7 = post::Entity::load()\n        .filter_by_id(7)\n        .with(tag::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(post_7.id, 7);\n    assert_eq!(post_7.title, \"post 7!\");\n    assert_eq!(post_7.tags.len(), 3);\n    assert_eq!(post_7.tags[0].tag, \"pet\");\n    assert_eq!(post_7.tags[1].tag, \"food\");\n    assert_eq!(post_7.tags[2].tag, \"sunny\");\n\n    let user_1 = user::Entity::find_by_email(\"@1\").one(db).await?.unwrap();\n    info!(\"can't delete as there are posts belonging to user\");\n    assert!(user_1.clone().delete(db).await.is_err());\n    info!(\"cascade delete user 1\");\n    assert_eq!(user_1.cascade_delete(db).await?.rows_affected, 2); // user + post\n    assert!(user::Entity::find_by_email(\"@1\").one(db).await?.is_none());\n\n    info!(\"cascade delete user 2\");\n    let user_2 = user::Entity::find_by_email(\"@2\").one(db).await?.unwrap();\n    assert_eq!(user_2.cascade_delete(db).await?.rows_affected, 2); // user + post\n    assert!(user::Entity::find_by_email(\"@2\").one(db).await?.is_none());\n\n    info!(\"cascade delete user 4\");\n    let user_4 = user::Entity::find_by_id(4).one(db).await?.unwrap();\n    assert_eq!(\n        user_4.cascade_delete(db).await?.rows_affected,\n        1 + 1 + 3 + 1\n    ); // user + profile + post_tag + post\n    assert!(user::Entity::find_by_id(4).one(db).await?.is_none());\n\n    info!(\"insert a new user with a new profile and new post with tag\");\n    let user = user::ActiveModel::builder()\n        .set_name(\"Bob\")\n        .set_email(\"bob@sea-ql.org\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"image.jpg\"))\n        .add_post(\n            post::ActiveModel::builder()\n                .set_title(\"Nice weather\")\n                .add_tag(tag::ActiveModel::builder().set_tag(\"sunny\")),\n        )\n        .insert(db)\n        .await?;\n\n    info!(\"get back the user with profile, posts and tags\");\n    assert_eq!(\n        user::Entity::load()\n            .filter_by_id(user.id)\n            .with(profile::Entity)\n            .with((post::Entity, tag::Entity))\n            .one(db)\n            .await?\n            .unwrap(),\n        user::ModelEx {\n            id: 5,\n            name: \"Bob\".into(),\n            email: \"bob@sea-ql.org\".into(),\n            profile: HasOne::loaded(profile::Model {\n                id: 3,\n                picture: \"image.jpg\".into(),\n                user_id: 5,\n            }),\n            posts: HasMany::Loaded(vec![post::ModelEx {\n                id: 8,\n                user_id: 5,\n                title: \"Nice weather\".into(),\n                author: HasOne::Unloaded,\n                attachments: HasMany::Unloaded,\n                comments: HasMany::Unloaded,\n                tags: HasMany::Loaded(vec![tag::ModelEx {\n                    id: 5,\n                    tag: \"sunny\".into(),\n                    posts: HasMany::Unloaded,\n                }]),\n            }]),\n            followers: HasMany::Unloaded,\n            following: HasMany::Unloaded,\n        }\n    );\n\n    info!(\"should be no-op\");\n    assert_eq!(user, user.clone().into_active_model().update(db).await?);\n\n    // test self_ref via\n\n    info!(\"save a new user Alice\");\n    let alice = user::ActiveModel::builder()\n        .set_name(\"Alice\")\n        .set_email(\"@alice\")\n        .save(db)\n        .await?;\n\n    let bob = user::Entity::find()\n        .filter(user::COLUMN.name.eq(\"Bob\"))\n        .one(db)\n        .await?\n        .unwrap()\n        .into_active_model()\n        .into_ex();\n\n    let sam = user::Entity::find()\n        .filter(user::COLUMN.name.eq(\"Sam\"))\n        .one(db)\n        .await?\n        .unwrap()\n        .into_active_model();\n\n    info!(\"Add follower to Alice\");\n    let alice = alice.add_follower(bob.clone()).save(db).await?;\n\n    info!(\"Sam starts following Alice\");\n    sam.clone().into_ex().add_following(alice).save(db).await?;\n\n    info!(\"Add follower to Bob\");\n    bob.add_follower(sam).save(db).await?;\n\n    let users = user::Entity::load()\n        .with(user_follower::Entity)\n        .with(user_follower::Entity::REVERSE)\n        .order_by_asc(user::COLUMN.name)\n        .all(db)\n        .await?;\n\n    assert_eq!(users[0].name, \"Alice\");\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0].name, \"Sam\");\n    assert_eq!(users[0].followers[1].name, \"Bob\");\n    assert!(users[0].following.is_empty());\n\n    assert_eq!(users[1].name, \"Bob\");\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0].name, \"Sam\");\n    assert_eq!(users[1].following.len(), 1);\n    assert_eq!(users[1].following[0].name, \"Alice\");\n\n    assert_eq!(users[2].name, \"Sam\");\n    assert!(users[2].followers.is_empty());\n    assert_eq!(users[2].following.len(), 2);\n    assert_eq!(users[2].following[0].name, \"Bob\");\n    assert_eq!(users[2].following[1].name, \"Alice\");\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn test_active_model_ex_film_store() -> Result<(), DbErr> {\n    use common::film_store::*;\n\n    let ctx = TestContext::new(\"test_active_model_ex_film_store\").await;\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(film::Entity)\n        .register(actor::Entity)\n        .register(film_actor::Entity)\n        .register(staff::Entity)\n        .apply(db)\n        .await?;\n\n    info!(\"save film Mission, no actors\");\n    let mut film = film::ActiveModel {\n        title: Set(\"Mission\".into()),\n        ..Default::default()\n    }\n    .save(db)\n    .await?\n    .into_ex();\n\n    info!(\"create two actors and add to film Mission\");\n    film.actors.push(actor::ActiveModel {\n        name: Set(\"Tom\".into()),\n        ..Default::default()\n    });\n    film.actors.push(actor::ActiveModel {\n        name: Set(\"Ben\".into()),\n        ..Default::default()\n    });\n    film.save(db).await?;\n\n    info!(\"check that film has two actors\");\n    let film = film::Entity::load()\n        .with(actor::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(film.title, \"Mission\");\n    assert_eq!(film.actors.len(), 2);\n    assert_eq!(film.actors[0].name, \"Tom\");\n    assert_eq!(film.actors[1].name, \"Ben\");\n\n    info!(\"save new actor Sam, no films\");\n    let tom = film.actors.into_iter().next().unwrap();\n    let sam = actor::ActiveModel {\n        // new actor\n        name: Set(\"Sam\".into()),\n        ..Default::default()\n    }\n    .save(db)\n    .await?;\n\n    info!(\"save new films Galaxy with Tom and Sam as actors\");\n    film::ActiveModelEx {\n        title: Set(\"Galaxy\".into()),\n        actors: HasManyModel::Replace(vec![tom.into_active_model(), sam.into_ex()]),\n        ..Default::default()\n    }\n    .save(db)\n    .await?;\n\n    info!(\"film Galaxy has two actors\");\n    let film = film::Entity::load()\n        .filter_by_id(2)\n        .with(actor::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(film.title, \"Galaxy\");\n    assert_eq!(film.actors.len(), 2);\n    assert_eq!(film.actors[0].name, \"Tom\");\n    assert_eq!(film.actors[1].name, \"Sam\");\n\n    info!(\"actor Tom has two films\");\n    let tom = actor::Entity::load()\n        .filter_by_name(\"Tom\")\n        .with(film::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(tom.name, \"Tom\");\n    assert_eq!(tom.films.len(), 2);\n    assert_eq!(tom.films[0].title, \"Mission\");\n    assert_eq!(tom.films[1].title, \"Galaxy\");\n\n    info!(\"cascade delete film Galaxy\");\n    assert_eq!(film.delete(db).await?.rows_affected, 3); // film + 2 film_actor\n\n    info!(\"tom has 1 film left\");\n    let tom = actor::Entity::load()\n        .filter_by_name(\"Tom\")\n        .with(film::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(tom.name, \"Tom\");\n    assert_eq!(tom.films.len(), 1);\n    assert_eq!(tom.films[0].title, \"Mission\");\n\n    info!(\"sam still exists, but no films\");\n    let sam = actor::Entity::load()\n        .filter_by_name(\"Sam\")\n        .with(film::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(sam.name, \"Sam\");\n    assert_eq!(sam.films.len(), 0);\n\n    info!(\"should be idempotent\");\n    let mut film = film::Entity::find_by_id(1)\n        .one(db)\n        .await?\n        .unwrap()\n        .into_active_model()\n        .into_ex();\n    film.actors.push(tom.into_active_model());\n    film.save(db).await?;\n\n    // test self_ref\n\n    info!(\"insert new staff: alan\");\n\n    let alan = staff::ActiveModel::builder()\n        .set_name(\"Alan\")\n        .insert(db)\n        .await?;\n\n    info!(\"insert new staff: Ben reports to Alan\");\n    staff::ActiveModel::builder()\n        .set_name(\"Ben\")\n        .set_reports_to(alan.clone())\n        .insert(db)\n        .await?;\n\n    info!(\"insert new staff: Alice\");\n    let alice = staff::ActiveModel::builder()\n        .set_name(\"Alice\")\n        .insert(db)\n        .await?;\n\n    info!(\"assign Alice to report to Alan\");\n    let alan = alan\n        .into_active_model()\n        .add_manage(alice.clone())\n        .save(db)\n        .await?;\n\n    info!(\"insert new staff: Elle\");\n    staff::ActiveModel::builder()\n        .set_name(\"Elle\")\n        .insert(db)\n        .await?;\n\n    info!(\"load all staff\");\n    let staff = staff::Entity::load()\n        .with(staff::Relation::ReportsTo)\n        .with(staff::Relation::Manages)\n        .all(db)\n        .await?;\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(staff[0].reports_to, None);\n    assert_eq!(staff[0].manages[0].name, \"Ben\");\n    assert_eq!(staff[0].manages[1].name, \"Alice\");\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n    assert!(staff[1].manages.is_empty());\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n    assert!(staff[2].manages.is_empty());\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(staff[3].reports_to, None);\n    assert!(staff[3].manages.is_empty());\n\n    info!(\"delete alan, reports_to should be cleared\");\n    alan.delete(db).await?;\n\n    info!(\"verify Alice still exists\");\n    assert!(\n        staff::Entity::find_by_id(alice.id)\n            .one(db)\n            .await?\n            .unwrap()\n            .reports_to_id\n            .is_none()\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/arrow_schema_tests.rs",
    "content": "#![cfg(feature = \"with-arrow\")]\n//! Tests for the DeriveArrowSchema macro.\n//!\n//! cargo t --test arrow_schema_tests --features=with-arrow\n\nuse sea_orm::ArrowSchema;\nuse sea_orm_arrow::arrow::datatypes::{DataType, Field, Schema, TimeUnit};\n\n// ---------------------------------------------------------------------------\n// Entities using #[sea_orm::model] (2.0 format, arrow_schema flag)\n// ---------------------------------------------------------------------------\n\nmod basic_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"basic\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_name = \"user_name\")]\n        pub name: String,\n        pub flag: bool,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod split_attrs_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"split_attrs\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        #[sea_orm(auto_increment = false)]\n        pub id: i32,\n        pub name: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod float_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"floats\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub float_val: f32,\n        pub double_val: f64,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod nullable_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"nullable\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub required_name: String,\n        pub optional_name: Option<String>,\n        pub optional_int: Option<i32>,\n        #[sea_orm(nullable)]\n        pub nullable_via_attr: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod string_variants_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"string_variants\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub plain: String,\n        #[sea_orm(column_type = \"Text\")]\n        pub text_field: String,\n        #[sea_orm(column_type = \"Char(Some(10))\")]\n        pub char_field: String,\n        #[sea_orm(column_type = \"String(StringLen::N(100))\")]\n        pub short_string: String,\n        #[sea_orm(column_type = \"String(StringLen::N(50000))\")]\n        pub long_string: String,\n        #[sea_orm(column_type = \"String(StringLen::Max)\")]\n        pub max_string: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod comment_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"comment_test\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(arrow_comment = \"The user's display name\")]\n        pub name: String,\n        #[sea_orm(nullable, arrow_comment = \"Optional email address\")]\n        pub email: Option<String>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod timestamp_override_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"timestamp_override\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_type = \"DateTime\", arrow_timestamp_unit = \"Nanosecond\")]\n        pub nano_ts: String,\n        #[sea_orm(column_type = \"DateTime\", arrow_timestamp_unit = \"Second\")]\n        pub second_ts: String,\n        #[sea_orm(column_type = \"DateTime\", arrow_timestamp_unit = \"Millisecond\")]\n        pub milli_ts: String,\n        #[sea_orm(\n            column_type = \"DateTime\",\n            arrow_timestamp_unit = \"Nanosecond\",\n            arrow_timezone = \"America/New_York\"\n        )]\n        pub nano_with_tz: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod decimal_override_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"decimal_override\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(\n            column_type = \"Decimal(Some((10, 2)))\",\n            arrow_precision = 20,\n            arrow_scale = 4\n        )]\n        pub overridden: String,\n        #[sea_orm(column_type = \"Decimal(Some((10, 2)))\", arrow_precision = 50)]\n        pub large_precision: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// ---------------------------------------------------------------------------\n// Entities using old format (manual Relation enum + DeriveArrowSchema)\n// ---------------------------------------------------------------------------\n\nmod all_integers_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, DeriveArrowSchema)]\n    #[sea_orm(table_name = \"all_integers\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub tiny: i8,\n        pub small: i16,\n        pub big: i64,\n        pub tiny_u: u8,\n        pub small_u: u16,\n        pub uint: u32,\n        pub big_u: u64,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod column_type_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel, DeriveArrowSchema)]\n    #[sea_orm(table_name = \"column_types\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_type = \"Text\")]\n        pub description: String,\n        #[sea_orm(column_type = \"Boolean\")]\n        pub active: bool,\n        #[sea_orm(column_type = \"TinyInteger\")]\n        pub tiny: i8,\n        #[sea_orm(column_type = \"SmallInteger\")]\n        pub small: i16,\n        #[sea_orm(column_type = \"BigInteger\")]\n        pub big: i64,\n        #[sea_orm(column_type = \"TinyUnsigned\")]\n        pub tiny_u: u8,\n        #[sea_orm(column_type = \"SmallUnsigned\")]\n        pub small_u: u16,\n        #[sea_orm(column_type = \"Unsigned\")]\n        pub uint: u32,\n        #[sea_orm(column_type = \"BigUnsigned\")]\n        pub big_u: u64,\n        #[sea_orm(column_type = \"Float\")]\n        pub fval: f32,\n        #[sea_orm(column_type = \"Double\")]\n        pub dval: f64,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod skip_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, DeriveArrowSchema)]\n    #[sea_orm(table_name = \"skip_test\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_name = \"db_visible\", arrow_field = \"arrowVisible\")]\n        pub visible: String,\n        #[sea_orm(arrow_skip)]\n        pub internal: String,\n        #[sea_orm(column_name = \"db_also_visible\")]\n        pub also_visible: bool,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod special_types_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, DeriveArrowSchema)]\n    #[sea_orm(table_name = \"special_types\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_type = \"Json\")]\n        pub json_data: String,\n        #[sea_orm(column_type = \"JsonBinary\")]\n        pub jsonb_data: String,\n        #[sea_orm(column_type = \"Uuid\")]\n        pub uuid_val: String,\n        #[sea_orm(column_type = \"Binary(16)\")]\n        pub bin_val: Vec<u8>,\n        #[sea_orm(column_type = \"VarBinary(StringLen::N(256))\")]\n        pub varbin_val: Vec<u8>,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod date_time_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, DeriveArrowSchema)]\n    #[sea_orm(table_name = \"date_time_test\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub date_val: Date,\n        pub time_val: Time,\n        pub datetime_val: DateTime,\n        #[sea_orm(column_type = \"Timestamp\")]\n        pub timestamp_val: String,\n        pub timestamptz_val: DateTimeWithTimeZone,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod decimal_column_type_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, DeriveArrowSchema)]\n    #[sea_orm(table_name = \"decimal_column_type\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_type = \"Decimal(Some((10, 2)))\")]\n        pub price: String,\n        #[sea_orm(column_type = \"Decimal(Some((20, 4)))\")]\n        pub amount: String,\n        #[sea_orm(column_type = \"Decimal(None)\")]\n        pub default_decimal: String,\n        #[sea_orm(column_type = \"Money(None)\")]\n        pub money_val: String,\n        #[sea_orm(column_type = \"Money(Some((12, 3)))\")]\n        pub money_custom: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// ---------------------------------------------------------------------------\n// Tests\n// ---------------------------------------------------------------------------\n\n#[test]\nfn test_basic_schema() {\n    let schema = basic_entity::Entity::arrow_schema();\n    let expected = Schema::new(vec![\n        Field::new(\"id\", DataType::Int32, true),\n        // column_name = \"user_name\" should be used instead of \"name\"\n        Field::new(\"user_name\", DataType::Utf8, true),\n        Field::new(\"flag\", DataType::Boolean, true),\n    ]);\n    assert_eq!(schema, expected);\n}\n\n#[test]\nfn test_all_integer_types() {\n    let schema = all_integers_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n    assert_eq!(fields.len(), 8);\n    assert_eq!(fields[0].as_ref(), &Field::new(\"id\", DataType::Int32, true));\n    assert_eq!(\n        fields[1].as_ref(),\n        &Field::new(\"tiny\", DataType::Int8, true)\n    );\n    assert_eq!(\n        fields[2].as_ref(),\n        &Field::new(\"small\", DataType::Int16, true)\n    );\n    assert_eq!(\n        fields[3].as_ref(),\n        &Field::new(\"big\", DataType::Int64, true)\n    );\n    assert_eq!(\n        fields[4].as_ref(),\n        &Field::new(\"tiny_u\", DataType::UInt8, true)\n    );\n    assert_eq!(\n        fields[5].as_ref(),\n        &Field::new(\"small_u\", DataType::UInt16, true)\n    );\n    assert_eq!(\n        fields[6].as_ref(),\n        &Field::new(\"uint\", DataType::UInt32, true)\n    );\n    assert_eq!(\n        fields[7].as_ref(),\n        &Field::new(\"big_u\", DataType::UInt64, true)\n    );\n}\n\n#[test]\nfn test_float_types() {\n    let schema = float_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n    assert_eq!(\n        fields[1].as_ref(),\n        &Field::new(\"float_val\", DataType::Float32, true)\n    );\n    assert_eq!(\n        fields[2].as_ref(),\n        &Field::new(\"double_val\", DataType::Float64, true)\n    );\n}\n\n#[test]\nfn test_nullable_fields() {\n    let schema = nullable_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // required_name: not nullable\n    assert_eq!(fields[1].name(), \"required_name\");\n    assert!(fields[1].is_nullable());\n\n    // optional_name: Option<String> -> nullable\n    assert_eq!(fields[2].name(), \"optional_name\");\n    assert!(fields[2].is_nullable());\n\n    // optional_int: Option<i32> -> nullable\n    assert_eq!(fields[3].name(), \"optional_int\");\n    assert!(fields[3].is_nullable());\n\n    // nullable_via_attr: #[sea_orm(nullable)] -> nullable\n    assert_eq!(fields[4].name(), \"nullable_via_attr\");\n    assert!(fields[4].is_nullable());\n}\n\n#[test]\nfn test_column_type_overrides() {\n    let schema = column_type_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    assert_eq!(fields[0].data_type(), &DataType::Int32); // id\n    assert_eq!(fields[1].data_type(), &DataType::LargeUtf8); // Text\n    assert_eq!(fields[2].data_type(), &DataType::Boolean); // Boolean\n    assert_eq!(fields[3].data_type(), &DataType::Int8); // TinyInteger\n    assert_eq!(fields[4].data_type(), &DataType::Int16); // SmallInteger\n    assert_eq!(fields[5].data_type(), &DataType::Int64); // BigInteger\n    assert_eq!(fields[6].data_type(), &DataType::UInt8); // TinyUnsigned\n    assert_eq!(fields[7].data_type(), &DataType::UInt16); // SmallUnsigned\n    assert_eq!(fields[8].data_type(), &DataType::UInt32); // Unsigned\n    assert_eq!(fields[9].data_type(), &DataType::UInt64); // BigUnsigned\n    assert_eq!(fields[10].data_type(), &DataType::Float32); // Float\n    assert_eq!(fields[11].data_type(), &DataType::Float64); // Double\n}\n\n#[test]\nfn test_string_variants() {\n    let schema = string_variants_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // plain String -> Utf8\n    assert_eq!(fields[1].data_type(), &DataType::Utf8);\n    // Text -> LargeUtf8\n    assert_eq!(fields[2].data_type(), &DataType::LargeUtf8);\n    // Char -> Utf8\n    assert_eq!(fields[3].data_type(), &DataType::Utf8);\n    // String(N(100)) where 100 <= 32767 -> Utf8\n    assert_eq!(fields[4].data_type(), &DataType::Utf8);\n    // String(N(50000)) where 50000 > 32767 -> LargeUtf8\n    assert_eq!(fields[5].data_type(), &DataType::LargeUtf8);\n    // String(Max) -> LargeUtf8\n    assert_eq!(fields[6].data_type(), &DataType::LargeUtf8);\n}\n\n#[test]\nfn test_arrow_skip() {\n    let schema = skip_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // Should have 3 fields: id, visible, also_visible (internal is skipped)\n    assert_eq!(fields.len(), 3);\n    assert_eq!(fields[0].name(), \"id\");\n    // arrow_field = \"arrowVisible\" takes priority over column_name = \"db_visible\"\n    assert_eq!(fields[1].name(), \"arrowVisible\");\n    // column_name = \"db_also_visible\" is used when no arrow_field is set\n    assert_eq!(fields[2].name(), \"db_also_visible\");\n}\n\n#[test]\nfn test_arrow_comment_metadata() {\n    let schema = comment_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // name field has comment metadata\n    let name_field = fields[1].as_ref();\n    assert_eq!(name_field.name(), \"name\");\n    let metadata = name_field.metadata();\n    assert_eq!(\n        metadata.get(\"comment\"),\n        Some(&\"The user's display name\".to_string())\n    );\n\n    // email field has comment metadata and is nullable\n    let email_field = fields[2].as_ref();\n    assert_eq!(email_field.name(), \"email\");\n    assert!(email_field.is_nullable());\n    let metadata = email_field.metadata();\n    assert_eq!(\n        metadata.get(\"comment\"),\n        Some(&\"Optional email address\".to_string())\n    );\n}\n\n#[test]\nfn test_special_types() {\n    let schema = special_types_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // Json -> Utf8\n    assert_eq!(fields[1].data_type(), &DataType::Utf8);\n    // JsonBinary -> Utf8\n    assert_eq!(fields[2].data_type(), &DataType::Utf8);\n    // Uuid -> Binary\n    assert_eq!(fields[3].data_type(), &DataType::Binary);\n    // Binary(16) -> Binary\n    assert_eq!(fields[4].data_type(), &DataType::Binary);\n    // VarBinary -> Binary\n    assert_eq!(fields[5].data_type(), &DataType::Binary);\n}\n\n#[test]\nfn test_date_time_column_types() {\n    let schema = date_time_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // Date -> Date32\n    assert_eq!(fields[1].data_type(), &DataType::Date32);\n    // Time -> Time64(Microsecond)\n    assert_eq!(\n        fields[2].data_type(),\n        &DataType::Time64(TimeUnit::Microsecond)\n    );\n    // DateTime -> Timestamp(Microsecond, None)\n    assert_eq!(\n        fields[3].data_type(),\n        &DataType::Timestamp(TimeUnit::Microsecond, None)\n    );\n    // Timestamp -> Timestamp(Microsecond, None)\n    assert_eq!(\n        fields[4].data_type(),\n        &DataType::Timestamp(TimeUnit::Microsecond, None)\n    );\n    // TimestampWithTimeZone -> Timestamp(Microsecond, Some(\"UTC\"))\n    assert_eq!(\n        fields[5].data_type(),\n        &DataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into()))\n    );\n}\n\n#[test]\nfn test_timestamp_unit_overrides() {\n    let schema = timestamp_override_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // Nanosecond override\n    assert_eq!(\n        fields[1].data_type(),\n        &DataType::Timestamp(TimeUnit::Nanosecond, None)\n    );\n    // Second override\n    assert_eq!(\n        fields[2].data_type(),\n        &DataType::Timestamp(TimeUnit::Second, None)\n    );\n    // Millisecond override\n    assert_eq!(\n        fields[3].data_type(),\n        &DataType::Timestamp(TimeUnit::Millisecond, None)\n    );\n    // Nanosecond + timezone override\n    assert_eq!(\n        fields[4].data_type(),\n        &DataType::Timestamp(TimeUnit::Nanosecond, Some(\"America/New_York\".into()))\n    );\n}\n\n#[test]\nfn test_decimal_column_types() {\n    let schema = decimal_column_type_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // Decimal(Some((10, 2))) -> Decimal64(10, 2) (precision ≤ 18)\n    assert_eq!(fields[1].data_type(), &DataType::Decimal64(10, 2));\n    // Decimal(Some((20, 4))) -> Decimal128(20, 4) (precision > 18)\n    assert_eq!(fields[2].data_type(), &DataType::Decimal128(20, 4));\n    // Decimal(None) -> Decimal128(38, 10)\n    assert_eq!(fields[3].data_type(), &DataType::Decimal128(38, 10));\n    // Money(None) -> Decimal128(19, 4) (precision 19 > 18)\n    assert_eq!(fields[4].data_type(), &DataType::Decimal128(19, 4));\n    // Money(Some((12, 3))) -> Decimal128 (defaults to precision 19)\n    assert!(matches!(fields[5].data_type(), DataType::Decimal128(..)));\n}\n\n#[test]\nfn test_decimal_arrow_precision_override() {\n    let schema = decimal_override_entity::Entity::arrow_schema();\n    let fields = schema.fields();\n\n    // arrow_precision=20, arrow_scale=4 overrides column_type's (10, 2)\n    assert_eq!(fields[1].data_type(), &DataType::Decimal128(20, 4));\n\n    // arrow_precision=50 (>38) -> Decimal256, scale falls back to column_type's 2\n    assert_eq!(fields[2].data_type(), &DataType::Decimal256(50, 2));\n}\n\n#[test]\nfn test_field_count_matches() {\n    assert_eq!(basic_entity::Entity::arrow_schema().fields().len(), 3);\n    assert_eq!(\n        all_integers_entity::Entity::arrow_schema().fields().len(),\n        8\n    );\n    assert_eq!(float_entity::Entity::arrow_schema().fields().len(), 3);\n    assert_eq!(nullable_entity::Entity::arrow_schema().fields().len(), 5);\n    assert_eq!(skip_entity::Entity::arrow_schema().fields().len(), 3); // 1 skipped\n    assert_eq!(comment_entity::Entity::arrow_schema().fields().len(), 3);\n}\n\n#[test]\nfn test_field_names_preserve_snake_case() {\n    let schema = all_integers_entity::Entity::arrow_schema();\n    let names: Vec<&str> = schema.fields().iter().map(|f| f.name().as_str()).collect();\n    assert_eq!(\n        names,\n        vec![\n            \"id\", \"tiny\", \"small\", \"big\", \"tiny_u\", \"small_u\", \"uint\", \"big_u\"\n        ]\n    );\n}\n\n// ---------------------------------------------------------------------------\n// Chrono type tests (feature-gated)\n// ---------------------------------------------------------------------------\n\n#[cfg(feature = \"with-chrono\")]\nmod chrono_schema_tests {\n    use super::*;\n\n    // 2.0 format\n    mod chrono_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[sea_orm::model]\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"chrono_schema\", arrow_schema)]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            pub date_val: ChronoDate,\n            pub time_val: ChronoTime,\n            pub datetime_val: ChronoDateTime,\n            pub datetime_utc: ChronoDateTimeUtc,\n            pub optional_date: Option<ChronoDate>,\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    // Old format\n    mod chrono_override_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel, DeriveArrowSchema)]\n        #[sea_orm(table_name = \"chrono_override\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(arrow_timestamp_unit = \"Nanosecond\")]\n            pub nano_dt: ChronoDateTime,\n            #[sea_orm(arrow_timestamp_unit = \"Nanosecond\", arrow_timezone = \"UTC\")]\n            pub nano_utc: ChronoDateTimeUtc,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn test_chrono_date() {\n        let schema = chrono_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        assert_eq!(fields[1].name(), \"date_val\");\n        assert_eq!(fields[1].data_type(), &DataType::Date32);\n        assert!(fields[1].is_nullable());\n    }\n\n    #[test]\n    fn test_chrono_time() {\n        let schema = chrono_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        assert_eq!(fields[2].name(), \"time_val\");\n        assert_eq!(\n            fields[2].data_type(),\n            &DataType::Time64(TimeUnit::Microsecond)\n        );\n    }\n\n    #[test]\n    fn test_chrono_datetime_naive() {\n        let schema = chrono_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        assert_eq!(fields[3].name(), \"datetime_val\");\n        assert_eq!(\n            fields[3].data_type(),\n            &DataType::Timestamp(TimeUnit::Microsecond, None)\n        );\n    }\n\n    #[test]\n    fn test_chrono_datetime_utc() {\n        let schema = chrono_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        assert_eq!(fields[4].name(), \"datetime_utc\");\n        assert_eq!(\n            fields[4].data_type(),\n            &DataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into()))\n        );\n    }\n\n    #[test]\n    fn test_chrono_optional_nullable() {\n        let schema = chrono_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        assert_eq!(fields[5].name(), \"optional_date\");\n        assert!(fields[5].is_nullable());\n        assert_eq!(fields[5].data_type(), &DataType::Date32);\n    }\n\n    #[test]\n    fn test_chrono_timestamp_unit_override() {\n        let schema = chrono_override_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        // ChronoDateTime with Nanosecond override, no timezone\n        assert_eq!(\n            fields[1].data_type(),\n            &DataType::Timestamp(TimeUnit::Nanosecond, None)\n        );\n\n        // ChronoDateTimeUtc with Nanosecond + explicit UTC\n        assert_eq!(\n            fields[2].data_type(),\n            &DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into()))\n        );\n    }\n}\n\n// ---------------------------------------------------------------------------\n// Decimal type tests with rust_decimal (feature-gated)\n// ---------------------------------------------------------------------------\n\n#[cfg(feature = \"with-rust_decimal\")]\nmod rust_decimal_schema_tests {\n    use super::*;\n\n    // Old format\n    mod decimal_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel, DeriveArrowSchema)]\n        #[sea_orm(table_name = \"decimal_schema\")]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(column_type = \"Decimal(Some((10, 2)))\")]\n            pub price: Decimal,\n            pub inferred_decimal: Decimal,\n            pub optional_decimal: Option<Decimal>,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {}\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn test_decimal_with_column_type() {\n        let schema = decimal_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        // precision 10 ≤ 18 → Decimal64\n        assert_eq!(fields[1].data_type(), &DataType::Decimal64(10, 2));\n        assert!(fields[1].is_nullable());\n    }\n\n    #[test]\n    fn test_decimal_inferred_type() {\n        let schema = decimal_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        // Inferred from Rust type Decimal -> Decimal128(38, 10) defaults\n        assert_eq!(fields[2].data_type(), &DataType::Decimal128(38, 10));\n    }\n\n    #[test]\n    fn test_decimal_optional_nullable() {\n        let schema = decimal_entity::Entity::arrow_schema();\n        let fields = schema.fields();\n\n        assert!(fields[3].is_nullable());\n        assert_eq!(fields[3].data_type(), &DataType::Decimal128(38, 10));\n    }\n}\n"
  },
  {
    "path": "tests/arrow_tests.rs",
    "content": "#![cfg(feature = \"with-arrow\")]\n//! cargo t --test arrow_tests --features=with-arrow\n//! cargo t --test arrow_tests --features=with-arrow,with-bigdecimal\nuse sea_orm::entity::prelude::*;\nuse sea_orm::{ActiveValue::NotSet, ArrowSchema, Set, arrow};\nuse sea_orm_arrow::arrow::array::*;\nuse sea_orm_arrow::arrow::datatypes::{DataType, Field, Schema, TimeUnit};\nuse std::sync::Arc;\n\n/// Test entity with all supported primitive types\nmod primitive_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"test_arrow\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub tiny: i8,\n        pub small: i16,\n        pub big: i64,\n        pub tiny_u: u8,\n        pub small_u: u16,\n        pub uint: u32,\n        pub big_u: u64,\n        pub float_val: f32,\n        pub double_val: f64,\n        pub name: String,\n        pub flag: bool,\n        pub nullable_int: Option<i32>,\n        pub nullable_name: Option<String>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n/// Test entity with column_name overrides\nmod column_name_entity {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"test_col_names\", arrow_schema)]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_name = \"user_name\")]\n        pub name: String,\n        #[sea_orm(column_name = \"is_active\")]\n        pub active: bool,\n        #[sea_orm(column_name = \"score_value\")]\n        pub score: Option<f64>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nfn make_batch() -> RecordBatch {\n    let schema = Arc::new(Schema::new(vec![\n        Field::new(\"id\", DataType::Int32, false),\n        Field::new(\"tiny\", DataType::Int8, false),\n        Field::new(\"small\", DataType::Int16, false),\n        Field::new(\"big\", DataType::Int64, false),\n        Field::new(\"tiny_u\", DataType::UInt8, false),\n        Field::new(\"small_u\", DataType::UInt16, false),\n        Field::new(\"uint\", DataType::UInt32, false),\n        Field::new(\"big_u\", DataType::UInt64, false),\n        Field::new(\"float_val\", DataType::Float32, false),\n        Field::new(\"double_val\", DataType::Float64, false),\n        Field::new(\"name\", DataType::Utf8, false),\n        Field::new(\"flag\", DataType::Boolean, false),\n        Field::new(\"nullable_int\", DataType::Int32, true),\n        Field::new(\"nullable_name\", DataType::Utf8, true),\n    ]));\n\n    RecordBatch::try_new(\n        schema,\n        vec![\n            Arc::new(Int32Array::from(vec![1, 2])),\n            Arc::new(Int8Array::from(vec![10i8, 20])),\n            Arc::new(Int16Array::from(vec![100i16, 200])),\n            Arc::new(Int64Array::from(vec![1000i64, 2000])),\n            Arc::new(UInt8Array::from(vec![5u8, 6])),\n            Arc::new(UInt16Array::from(vec![50u16, 60])),\n            Arc::new(UInt32Array::from(vec![500u32, 600])),\n            Arc::new(UInt64Array::from(vec![5000u64, 6000])),\n            Arc::new(Float32Array::from(vec![1.5f32, 2.5])),\n            Arc::new(Float64Array::from(vec![10.5f64, 20.5])),\n            Arc::new(StringArray::from(vec![\"Alice\", \"Bob\"])),\n            Arc::new(BooleanArray::from(vec![true, false])),\n            Arc::new(Int32Array::from(vec![Some(42), None])),\n            Arc::new(StringArray::from(vec![Some(\"hello\"), None])),\n        ],\n    )\n    .expect(\"Failed to create RecordBatch\")\n}\n\n#[test]\nfn test_from_arrow_basic() {\n    let batch = make_batch();\n    let active_models =\n        primitive_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n\n    assert_eq!(active_models.len(), 2);\n\n    let am = &active_models[0];\n    assert_eq!(am.id, Set(1));\n    assert_eq!(am.tiny, Set(10));\n    assert_eq!(am.small, Set(100));\n    assert_eq!(am.big, Set(1000));\n    assert_eq!(am.tiny_u, Set(5));\n    assert_eq!(am.small_u, Set(50));\n    assert_eq!(am.uint, Set(500));\n    assert_eq!(am.big_u, Set(5000));\n    assert_eq!(am.float_val, Set(1.5));\n    assert_eq!(am.double_val, Set(10.5));\n    assert_eq!(am.name, Set(\"Alice\".to_owned()));\n    assert_eq!(am.flag, Set(true));\n    assert_eq!(am.nullable_int, Set(Some(42)));\n    assert_eq!(am.nullable_name, Set(Some(\"hello\".to_owned())));\n\n    let am = &active_models[1];\n    assert_eq!(am.id, Set(2));\n    assert_eq!(am.tiny, Set(20));\n    assert_eq!(am.name, Set(\"Bob\".to_owned()));\n    assert_eq!(am.flag, Set(false));\n    assert_eq!(am.nullable_int, Set(None));\n    assert_eq!(am.nullable_name, Set(None));\n}\n\n#[test]\nfn test_from_arrow_missing_columns() {\n    let schema = Arc::new(Schema::new(vec![\n        Field::new(\"id\", DataType::Int32, false),\n        Field::new(\"name\", DataType::Utf8, false),\n    ]));\n\n    let batch = RecordBatch::try_new(\n        schema,\n        vec![\n            Arc::new(Int32Array::from(vec![42])),\n            Arc::new(StringArray::from(vec![\"partial\"])),\n        ],\n    )\n    .expect(\"Failed to create RecordBatch\");\n\n    let active_models =\n        primitive_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n    assert_eq!(active_models.len(), 1);\n\n    let am = &active_models[0];\n    assert_eq!(am.id, Set(42));\n    assert_eq!(am.name, Set(\"partial\".to_owned()));\n    assert_eq!(am.tiny, NotSet);\n    assert_eq!(am.small, NotSet);\n    assert_eq!(am.big, NotSet);\n    assert_eq!(am.float_val, NotSet);\n    assert_eq!(am.double_val, NotSet);\n    assert_eq!(am.flag, NotSet);\n    assert_eq!(am.nullable_int, NotSet);\n    assert_eq!(am.nullable_name, NotSet);\n}\n\n#[test]\nfn test_from_arrow_empty_batch() {\n    let schema = Arc::new(Schema::new(vec![\n        Field::new(\"id\", DataType::Int32, false),\n        Field::new(\"name\", DataType::Utf8, false),\n    ]));\n\n    let batch = RecordBatch::new_empty(schema);\n    let active_models =\n        primitive_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n    assert!(active_models.is_empty());\n}\n\n#[test]\nfn test_from_arrow_type_mismatch() {\n    let schema = Arc::new(Schema::new(vec![Field::new(\"id\", DataType::Int64, false)]));\n\n    let batch = RecordBatch::try_new(schema, vec![Arc::new(Int64Array::from(vec![1i64]))])\n        .expect(\"Failed to create RecordBatch\");\n\n    let result = primitive_entity::ActiveModel::from_arrow(&batch);\n    assert!(result.is_err());\n    assert!(matches!(result.unwrap_err(), DbErr::Type(_)));\n}\n\n// ===========================================================================\n// to_arrow tests\n// ===========================================================================\n\n#[test]\nfn test_to_arrow_basic_primitives() {\n    use sea_orm::ArrowSchema;\n\n    let schema = primitive_entity::Entity::arrow_schema();\n\n    let models = vec![\n        primitive_entity::ActiveModel {\n            id: Set(1),\n            tiny: Set(10),\n            small: Set(100),\n            big: Set(1000),\n            tiny_u: Set(5),\n            small_u: Set(50),\n            uint: Set(500),\n            big_u: Set(5000),\n            float_val: Set(1.5),\n            double_val: Set(10.5),\n            name: Set(\"Alice\".to_owned()),\n            flag: Set(true),\n            nullable_int: Set(Some(42)),\n            nullable_name: Set(Some(\"hello\".to_owned())),\n        },\n        primitive_entity::ActiveModel {\n            id: Set(2),\n            tiny: Set(20),\n            small: Set(200),\n            big: Set(2000),\n            tiny_u: Set(6),\n            small_u: Set(60),\n            uint: Set(600),\n            big_u: Set(6000),\n            float_val: Set(2.5),\n            double_val: Set(20.5),\n            name: Set(\"Bob\".to_owned()),\n            flag: Set(false),\n            nullable_int: Set(None),\n            nullable_name: Set(None),\n        },\n    ];\n\n    let batch = primitive_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n\n    assert_eq!(batch.num_rows(), 2);\n    assert_eq!(batch.num_columns(), 14);\n\n    // Verify integer columns\n    let id_arr = batch\n        .column_by_name(\"id\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Int32Array>()\n        .unwrap();\n    assert_eq!(id_arr.value(0), 1);\n    assert_eq!(id_arr.value(1), 2);\n\n    let tiny_arr = batch\n        .column_by_name(\"tiny\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Int8Array>()\n        .unwrap();\n    assert_eq!(tiny_arr.value(0), 10);\n    assert_eq!(tiny_arr.value(1), 20);\n\n    // Verify unsigned\n    let tiny_u_arr = batch\n        .column_by_name(\"tiny_u\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<UInt8Array>()\n        .unwrap();\n    assert_eq!(tiny_u_arr.value(0), 5);\n\n    // Verify floats\n    let float_arr = batch\n        .column_by_name(\"float_val\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Float32Array>()\n        .unwrap();\n    assert_eq!(float_arr.value(0), 1.5);\n\n    let double_arr = batch\n        .column_by_name(\"double_val\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Float64Array>()\n        .unwrap();\n    assert_eq!(double_arr.value(0), 10.5);\n\n    // Verify strings\n    let name_arr = batch\n        .column_by_name(\"name\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<StringArray>()\n        .unwrap();\n    assert_eq!(name_arr.value(0), \"Alice\");\n    assert_eq!(name_arr.value(1), \"Bob\");\n\n    // Verify boolean\n    let flag_arr = batch\n        .column_by_name(\"flag\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<BooleanArray>()\n        .unwrap();\n    assert!(flag_arr.value(0));\n    assert!(!flag_arr.value(1));\n\n    // Verify nullable: row 0 has values, row 1 has nulls\n    let ni_arr = batch\n        .column_by_name(\"nullable_int\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Int32Array>()\n        .unwrap();\n    assert!(!ni_arr.is_null(0));\n    assert_eq!(ni_arr.value(0), 42);\n    assert!(ni_arr.is_null(1));\n\n    let nn_arr = batch\n        .column_by_name(\"nullable_name\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<StringArray>()\n        .unwrap();\n    assert!(!nn_arr.is_null(0));\n    assert_eq!(nn_arr.value(0), \"hello\");\n    assert!(nn_arr.is_null(1));\n}\n\n#[test]\nfn test_to_arrow_not_set_becomes_null() {\n    // Use an all-nullable schema so that NotSet → null is accepted by Arrow\n    let base = primitive_entity::Entity::arrow_schema();\n    let nullable_fields: Vec<Field> = base\n        .fields()\n        .iter()\n        .map(|f| Field::new(f.name(), f.data_type().clone(), true))\n        .collect();\n    let schema = Schema::new(nullable_fields);\n\n    // ActiveModel with only id and name set; everything else is NotSet\n    let models = vec![primitive_entity::ActiveModel {\n        id: Set(99),\n        name: Set(\"partial\".to_owned()),\n        ..Default::default()\n    }];\n\n    let batch = primitive_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n    assert_eq!(batch.num_rows(), 1);\n\n    // id and name should be present\n    let id_arr = batch\n        .column_by_name(\"id\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Int32Array>()\n        .unwrap();\n    assert_eq!(id_arr.value(0), 99);\n\n    // NotSet fields should be null\n    let tiny_arr = batch\n        .column_by_name(\"tiny\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Int8Array>()\n        .unwrap();\n    assert!(tiny_arr.is_null(0));\n\n    let flag_arr = batch\n        .column_by_name(\"flag\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<BooleanArray>()\n        .unwrap();\n    assert!(flag_arr.is_null(0));\n}\n\n#[test]\nfn test_to_arrow_empty_slice() {\n    let schema = primitive_entity::Entity::arrow_schema();\n    let batch = primitive_entity::ActiveModel::to_arrow(&[], &schema).expect(\"to_arrow failed\");\n    assert_eq!(batch.num_rows(), 0);\n    assert_eq!(batch.num_columns(), 14);\n}\n\n// ===========================================================================\n// column_name attribute tests\n// ===========================================================================\n\n#[test]\nfn test_column_name_schema_uses_db_names() {\n    // DeriveArrowSchema should use the column_name attribute values, not the Rust field names\n    let schema = column_name_entity::Entity::arrow_schema();\n    let field_names: Vec<&str> = schema.fields().iter().map(|f| f.name().as_str()).collect();\n\n    assert_eq!(\n        field_names,\n        vec![\"id\", \"user_name\", \"is_active\", \"score_value\"]\n    );\n}\n\n#[test]\nfn test_column_name_to_arrow_uses_db_names() {\n    let schema = column_name_entity::Entity::arrow_schema();\n\n    let models = vec![column_name_entity::ActiveModel {\n        id: Set(1),\n        name: Set(\"Alice\".to_owned()),\n        active: Set(true),\n        score: Set(Some(95.5)),\n    }];\n\n    let batch =\n        column_name_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n\n    // Columns should be accessible by their column_name (db name), not the Rust field name\n    assert!(batch.column_by_name(\"user_name\").is_some());\n    assert!(batch.column_by_name(\"is_active\").is_some());\n    assert!(batch.column_by_name(\"score_value\").is_some());\n\n    // Rust field names should NOT appear in the batch\n    assert!(batch.column_by_name(\"name\").is_none());\n    assert!(batch.column_by_name(\"active\").is_none());\n    assert!(batch.column_by_name(\"score\").is_none());\n\n    // Verify values\n    let name_arr = batch\n        .column_by_name(\"user_name\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<StringArray>()\n        .unwrap();\n    assert_eq!(name_arr.value(0), \"Alice\");\n\n    let active_arr = batch\n        .column_by_name(\"is_active\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<BooleanArray>()\n        .unwrap();\n    assert!(active_arr.value(0));\n\n    let score_arr = batch\n        .column_by_name(\"score_value\")\n        .unwrap()\n        .as_any()\n        .downcast_ref::<Float64Array>()\n        .unwrap();\n    assert_eq!(score_arr.value(0), 95.5);\n}\n\n#[test]\nfn test_column_name_from_arrow_uses_db_names() {\n    // Build a RecordBatch with column_name (db) names\n    let schema = Arc::new(column_name_entity::Entity::arrow_schema());\n\n    let batch = RecordBatch::try_new(\n        schema,\n        vec![\n            Arc::new(Int32Array::from(vec![1])),\n            Arc::new(StringArray::from(vec![\"Bob\"])),\n            Arc::new(BooleanArray::from(vec![false])),\n            Arc::new(Float64Array::from(vec![Some(88.0)])),\n        ],\n    )\n    .expect(\"Failed to create RecordBatch\");\n\n    let ams = column_name_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n    assert_eq!(ams.len(), 1);\n\n    // Values should be set on the Rust fields correctly\n    assert_eq!(ams[0].id, Set(1));\n    assert_eq!(ams[0].name, Set(\"Bob\".to_owned()));\n    assert_eq!(ams[0].active, Set(false));\n    assert_eq!(ams[0].score, Set(Some(88.0)));\n}\n\n#[test]\nfn test_column_name_roundtrip() {\n    let schema = column_name_entity::Entity::arrow_schema();\n\n    let original = vec![\n        column_name_entity::ActiveModel {\n            id: Set(1),\n            name: Set(\"Alice\".to_owned()),\n            active: Set(true),\n            score: Set(Some(95.5)),\n        },\n        column_name_entity::ActiveModel {\n            id: Set(2),\n            name: Set(\"Bob\".to_owned()),\n            active: Set(false),\n            score: Set(None),\n        },\n    ];\n\n    let batch =\n        column_name_entity::ActiveModel::to_arrow(&original, &schema).expect(\"to_arrow failed\");\n    let roundtripped =\n        column_name_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n\n    assert_eq!(roundtripped, original);\n}\n\n#[test]\nfn test_column_name_from_arrow_ignores_rust_field_names() {\n    // Build a RecordBatch using the Rust field names instead of column_name values.\n    // from_arrow should NOT find these columns (they don't match col.as_str()).\n    let schema = Arc::new(Schema::new(vec![\n        Field::new(\"id\", DataType::Int32, false),\n        Field::new(\"name\", DataType::Utf8, false), // Rust field name, not \"user_name\"\n        Field::new(\"active\", DataType::Boolean, false), // Rust field name, not \"is_active\"\n        Field::new(\"score\", DataType::Float64, true), // Rust field name, not \"score_value\"\n    ]));\n\n    let batch = RecordBatch::try_new(\n        schema,\n        vec![\n            Arc::new(Int32Array::from(vec![1])),\n            Arc::new(StringArray::from(vec![\"Alice\"])),\n            Arc::new(BooleanArray::from(vec![true])),\n            Arc::new(Float64Array::from(vec![Some(95.5)])),\n        ],\n    )\n    .expect(\"Failed to create RecordBatch\");\n\n    let ams = column_name_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n    assert_eq!(ams.len(), 1);\n\n    // id should be found (same name in both)\n    assert_eq!(ams[0].id, Set(1));\n\n    // The other fields should be NotSet because \"name\"/\"active\"/\"score\"\n    // don't match \"user_name\"/\"is_active\"/\"score_value\"\n    assert_eq!(ams[0].name, NotSet);\n    assert_eq!(ams[0].active, NotSet);\n    assert_eq!(ams[0].score, NotSet);\n}\n\n#[test]\nfn test_to_arrow_roundtrip_primitives() {\n    let schema = primitive_entity::Entity::arrow_schema();\n\n    let original = vec![\n        primitive_entity::ActiveModel {\n            id: Set(1),\n            tiny: Set(10),\n            small: Set(100),\n            big: Set(1000),\n            tiny_u: Set(5),\n            small_u: Set(50),\n            uint: Set(500),\n            big_u: Set(5000),\n            float_val: Set(1.5),\n            double_val: Set(10.5),\n            name: Set(\"Alice\".to_owned()),\n            flag: Set(true),\n            nullable_int: Set(Some(42)),\n            nullable_name: Set(Some(\"hello\".to_owned())),\n        },\n        primitive_entity::ActiveModel {\n            id: Set(2),\n            tiny: Set(20),\n            small: Set(200),\n            big: Set(2000),\n            tiny_u: Set(6),\n            small_u: Set(60),\n            uint: Set(600),\n            big_u: Set(6000),\n            float_val: Set(2.5),\n            double_val: Set(20.5),\n            name: Set(\"Bob\".to_owned()),\n            flag: Set(false),\n            nullable_int: Set(None),\n            nullable_name: Set(None),\n        },\n    ];\n\n    // to_arrow -> from_arrow roundtrip\n    let batch =\n        primitive_entity::ActiveModel::to_arrow(&original, &schema).expect(\"to_arrow failed\");\n    let roundtripped =\n        primitive_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n\n    assert_eq!(roundtripped.len(), 2);\n\n    // First row\n    assert_eq!(roundtripped, original);\n}\n\n/// Chrono datetime tests\n#[cfg(feature = \"with-chrono\")]\nmod chrono_tests {\n    use super::*;\n\n    mod chrono_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[sea_orm::model]\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"test_chrono\", arrow_schema)]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            pub created_date: ChronoDate,\n            pub created_time: ChronoTime,\n            pub created_at: ChronoDateTime,\n            pub updated_at: ChronoDateTimeUtc,\n            pub nullable_ts: Option<ChronoDateTimeUtc>,\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn test_to_arrow_chrono_roundtrip() {\n        use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};\n        use sea_orm::ArrowSchema;\n\n        let schema = chrono_entity::Entity::arrow_schema();\n\n        let date = NaiveDate::from_ymd_opt(2024, 6, 15).unwrap();\n        let time = NaiveTime::from_hms_opt(10, 30, 0).unwrap();\n        let naive_dt = NaiveDateTime::new(date, time);\n        let utc_dt: DateTime<Utc> = DateTime::from_timestamp_micros(1_718_447_400_000_000).unwrap();\n\n        let models = vec![\n            chrono_entity::ActiveModel {\n                id: Set(1),\n                created_date: Set(date),\n                created_time: Set(time),\n                created_at: Set(naive_dt),\n                updated_at: Set(utc_dt),\n                nullable_ts: Set(Some(utc_dt)),\n            },\n            chrono_entity::ActiveModel {\n                id: Set(2),\n                created_date: Set(date),\n                created_time: Set(time),\n                created_at: Set(naive_dt),\n                updated_at: Set(utc_dt),\n                nullable_ts: NotSet,\n            },\n        ];\n\n        let batch =\n            chrono_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n        assert_eq!(batch.num_rows(), 2);\n\n        // Verify Date32\n        let date_arr = batch\n            .column_by_name(\"created_date\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Date32Array>()\n            .unwrap();\n        assert_eq!(date_arr.value(0), 19889); // 2024-06-15\n\n        // Verify Time64\n        let time_arr = batch\n            .column_by_name(\"created_time\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Time64MicrosecondArray>()\n            .unwrap();\n        let expected_time_us: i64 = 10 * 3_600_000_000 + 30 * 60_000_000;\n        assert_eq!(time_arr.value(0), expected_time_us);\n\n        // Verify Timestamp (naive)\n        let ts_arr = batch\n            .column_by_name(\"created_at\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<TimestampMicrosecondArray>()\n            .unwrap();\n        assert_eq!(ts_arr.value(0), 1_718_447_400_000_000);\n\n        // Verify Timestamp with timezone\n        let ts_utc_arr = batch\n            .column_by_name(\"updated_at\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<TimestampMicrosecondArray>()\n            .unwrap();\n        assert_eq!(ts_utc_arr.value(0), 1_718_447_400_000_000);\n\n        // Verify nullable timestamp: row 0 present, row 1 null\n        let nullable_arr = batch\n            .column_by_name(\"nullable_ts\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<TimestampMicrosecondArray>()\n            .unwrap();\n        assert!(!nullable_arr.is_null(0));\n        assert!(nullable_arr.is_null(1));\n\n        // Full roundtrip\n        let roundtripped =\n            chrono_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(roundtripped.len(), 2);\n        assert_eq!(roundtripped[0].id, Set(1));\n        assert_eq!(roundtripped[0].created_date, Set(date));\n        assert_eq!(roundtripped[0].created_time, Set(time));\n        assert_eq!(roundtripped[0].created_at, Set(naive_dt));\n        assert_eq!(roundtripped[0].updated_at, Set(utc_dt));\n        assert_eq!(roundtripped[0].nullable_ts, Set(Some(utc_dt)));\n        assert_eq!(roundtripped[1].nullable_ts, Set(None));\n    }\n\n    #[test]\n    fn test_to_arrow_chrono_nanosecond_schema() {\n        use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};\n\n        let date = NaiveDate::from_ymd_opt(2024, 6, 15).unwrap();\n        let time = NaiveTime::from_hms_nano_opt(10, 30, 0, 123_456_789).unwrap();\n        let naive_dt = NaiveDateTime::new(date, time);\n        let utc_dt: DateTime<Utc> = DateTime::from_timestamp_nanos(1_718_447_400_123_456_789);\n\n        let models = vec![chrono_entity::ActiveModel {\n            id: Set(1),\n            created_date: Set(date),\n            created_time: Set(time),\n            created_at: Set(naive_dt),\n            updated_at: Set(utc_dt),\n            nullable_ts: Set(Some(utc_dt)),\n        }];\n\n        // Use a nanosecond schema\n        let schema = Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"created_date\", DataType::Date32, false),\n            Field::new(\n                \"created_time\",\n                DataType::Time64(TimeUnit::Nanosecond),\n                false,\n            ),\n            Field::new(\n                \"created_at\",\n                DataType::Timestamp(TimeUnit::Nanosecond, None),\n                false,\n            ),\n            Field::new(\n                \"updated_at\",\n                DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into())),\n                false,\n            ),\n            Field::new(\n                \"nullable_ts\",\n                DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into())),\n                true,\n            ),\n        ]);\n\n        let batch =\n            chrono_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n\n        let time_arr = batch\n            .column_by_name(\"created_time\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Time64NanosecondArray>()\n            .unwrap();\n        let expected_time_ns: i64 = 10 * 3_600_000_000_000 + 30 * 60_000_000_000 + 123_456_789;\n        assert_eq!(time_arr.value(0), expected_time_ns);\n\n        let ts_arr = batch\n            .column_by_name(\"created_at\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<TimestampNanosecondArray>()\n            .unwrap();\n        assert_eq!(ts_arr.value(0), 1_718_447_400_123_456_789);\n    }\n\n    #[test]\n    fn test_from_arrow_chrono_timestamp_micros() {\n        use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};\n\n        // 2024-06-15 10:30:00 UTC\n        let epoch_us: i64 = 1_718_447_400_000_000;\n        // Date: days since 1970-01-01 for 2024-06-15\n        let epoch_days: i32 = 19889;\n        // Time: 10:30:00 as microseconds since midnight\n        let time_us: i64 = 10 * 3_600_000_000 + 30 * 60_000_000;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"created_date\", DataType::Date32, false),\n            Field::new(\n                \"created_time\",\n                DataType::Time64(TimeUnit::Microsecond),\n                false,\n            ),\n            Field::new(\n                \"created_at\",\n                DataType::Timestamp(TimeUnit::Microsecond, None),\n                false,\n            ),\n            Field::new(\n                \"updated_at\",\n                DataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into())),\n                false,\n            ),\n            Field::new(\n                \"nullable_ts\",\n                DataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into())),\n                true,\n            ),\n        ]));\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1, 2])),\n                Arc::new(Date32Array::from(vec![epoch_days, epoch_days])),\n                Arc::new(Time64MicrosecondArray::from(vec![time_us, time_us])),\n                Arc::new(TimestampMicrosecondArray::from(vec![epoch_us, epoch_us])),\n                Arc::new(\n                    TimestampMicrosecondArray::from(vec![epoch_us, epoch_us]).with_timezone(\"UTC\"),\n                ),\n                Arc::new(\n                    TimestampMicrosecondArray::from(vec![Some(epoch_us), None])\n                        .with_timezone(\"UTC\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = chrono_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 2);\n\n        let am = &ams[0];\n        assert_eq!(am.id, Set(1));\n        assert_eq!(\n            am.created_date,\n            Set(NaiveDate::from_ymd_opt(2024, 6, 15).expect(\"valid\"))\n        );\n        assert_eq!(\n            am.created_time,\n            Set(NaiveTime::from_hms_opt(10, 30, 0).expect(\"valid\"))\n        );\n        let expected_naive = NaiveDateTime::new(\n            NaiveDate::from_ymd_opt(2024, 6, 15).expect(\"valid\"),\n            NaiveTime::from_hms_opt(10, 30, 0).expect(\"valid\"),\n        );\n        assert_eq!(am.created_at, Set(expected_naive));\n        let expected_utc: DateTime<Utc> = DateTime::from_timestamp_micros(epoch_us).expect(\"valid\");\n        assert_eq!(am.updated_at, Set(expected_utc));\n        assert_eq!(am.nullable_ts, Set(Some(expected_utc)));\n\n        // Second row: nullable_ts should be None\n        let am = &ams[1];\n        assert_eq!(am.nullable_ts, Set(None));\n    }\n\n    #[test]\n    fn test_from_arrow_chrono_timestamp_seconds() {\n        use chrono::{DateTime, Utc};\n\n        // 2024-06-15 10:30:00 UTC as seconds\n        let epoch_s: i64 = 1_718_447_400;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"created_date\", DataType::Date32, false),\n            Field::new(\"created_time\", DataType::Time32(TimeUnit::Second), false),\n            Field::new(\n                \"created_at\",\n                DataType::Timestamp(TimeUnit::Second, None),\n                false,\n            ),\n            Field::new(\n                \"updated_at\",\n                DataType::Timestamp(TimeUnit::Second, None),\n                false,\n            ),\n            Field::new(\n                \"nullable_ts\",\n                DataType::Timestamp(TimeUnit::Second, None),\n                true,\n            ),\n        ]));\n\n        let time_secs: i32 = 10 * 3600 + 30 * 60; // 10:30:00\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1])),\n                Arc::new(Date32Array::from(vec![19889])),\n                Arc::new(Time32SecondArray::from(vec![time_secs])),\n                Arc::new(TimestampSecondArray::from(vec![epoch_s])),\n                Arc::new(TimestampSecondArray::from(vec![epoch_s])),\n                Arc::new(TimestampSecondArray::from(vec![Some(epoch_s)])),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = chrono_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 1);\n\n        let expected_utc: DateTime<Utc> = DateTime::from_timestamp(epoch_s, 0).expect(\"valid\");\n        assert_eq!(ams[0].updated_at, Set(expected_utc));\n    }\n\n    #[test]\n    fn test_from_arrow_chrono_timestamp_nanos() {\n        use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};\n\n        // 2024-06-15 10:30:00.123456789 UTC as nanoseconds\n        let epoch_ns: i64 = 1_718_447_400_123_456_789;\n        // Date: days since 1970-01-01 for 2024-06-15\n        let epoch_days: i32 = 19889;\n        // Time: 10:30:00.123456789 as nanoseconds since midnight\n        let time_ns: i64 = 10 * 3_600_000_000_000 + 30 * 60_000_000_000 + 123_456_789;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"created_date\", DataType::Date32, false),\n            Field::new(\n                \"created_time\",\n                DataType::Time64(TimeUnit::Nanosecond),\n                false,\n            ),\n            Field::new(\n                \"created_at\",\n                DataType::Timestamp(TimeUnit::Nanosecond, None),\n                false,\n            ),\n            Field::new(\n                \"updated_at\",\n                DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into())),\n                false,\n            ),\n            Field::new(\n                \"nullable_ts\",\n                DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into())),\n                true,\n            ),\n        ]));\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1, 2])),\n                Arc::new(Date32Array::from(vec![epoch_days, epoch_days])),\n                Arc::new(Time64NanosecondArray::from(vec![time_ns, time_ns])),\n                Arc::new(TimestampNanosecondArray::from(vec![epoch_ns, epoch_ns])),\n                Arc::new(\n                    TimestampNanosecondArray::from(vec![epoch_ns, epoch_ns]).with_timezone(\"UTC\"),\n                ),\n                Arc::new(\n                    TimestampNanosecondArray::from(vec![Some(epoch_ns), None]).with_timezone(\"UTC\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = chrono_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 2);\n\n        let am = &ams[0];\n        assert_eq!(am.id, Set(1));\n        assert_eq!(\n            am.created_date,\n            Set(NaiveDate::from_ymd_opt(2024, 6, 15).expect(\"valid\"))\n        );\n        assert_eq!(\n            am.created_time,\n            Set(NaiveTime::from_hms_nano_opt(10, 30, 0, 123_456_789).expect(\"valid\"))\n        );\n        let expected_naive = NaiveDateTime::new(\n            NaiveDate::from_ymd_opt(2024, 6, 15).expect(\"valid\"),\n            NaiveTime::from_hms_nano_opt(10, 30, 0, 123_456_789).expect(\"valid\"),\n        );\n        assert_eq!(am.created_at, Set(expected_naive));\n        let expected_utc: DateTime<Utc> = DateTime::from_timestamp_nanos(epoch_ns);\n        assert_eq!(am.updated_at, Set(expected_utc));\n        assert_eq!(am.nullable_ts, Set(Some(expected_utc)));\n\n        // Second row: nullable_ts should be None\n        let am = &ams[1];\n        assert_eq!(am.nullable_ts, Set(None));\n    }\n}\n\n/// time crate datetime tests\n#[cfg(feature = \"with-time\")]\nmod time_tests {\n    use super::*;\n\n    mod time_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[sea_orm::model]\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"test_time\", arrow_schema)]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            pub created_date: TimeDate,\n            pub created_time: TimeTime,\n            pub created_at: TimeDateTime,\n            pub updated_at: TimeDateTimeWithTimeZone,\n            pub nullable_ts: Option<TimeDateTimeWithTimeZone>,\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn test_from_arrow_time_crate() {\n        // 2024-06-15 10:30:00 UTC\n        let epoch_us: i64 = 1_718_447_400_000_000;\n        let epoch_days: i32 = 19889;\n        let time_us: i64 = 10 * 3_600_000_000 + 30 * 60_000_000;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"created_date\", DataType::Date32, false),\n            Field::new(\n                \"created_time\",\n                DataType::Time64(TimeUnit::Microsecond),\n                false,\n            ),\n            Field::new(\n                \"created_at\",\n                DataType::Timestamp(TimeUnit::Microsecond, None),\n                false,\n            ),\n            Field::new(\n                \"updated_at\",\n                DataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into())),\n                false,\n            ),\n            Field::new(\n                \"nullable_ts\",\n                DataType::Timestamp(TimeUnit::Microsecond, Some(\"UTC\".into())),\n                true,\n            ),\n        ]));\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1])),\n                Arc::new(Date32Array::from(vec![epoch_days])),\n                Arc::new(Time64MicrosecondArray::from(vec![time_us])),\n                Arc::new(TimestampMicrosecondArray::from(vec![epoch_us])),\n                Arc::new(TimestampMicrosecondArray::from(vec![epoch_us]).with_timezone(\"UTC\")),\n                Arc::new(\n                    TimestampMicrosecondArray::from(vec![Some(epoch_us)]).with_timezone(\"UTC\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = time_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 1);\n\n        let am = &ams[0];\n\n        let expected_date =\n            time::Date::from_calendar_date(2024, time::Month::June, 15).expect(\"valid\");\n        assert_eq!(am.created_date, Set(expected_date));\n\n        let expected_time = time::Time::from_hms(10, 30, 0).expect(\"valid\");\n        assert_eq!(am.created_time, Set(expected_time));\n\n        let expected_pdt = time::PrimitiveDateTime::new(expected_date, expected_time);\n        assert_eq!(am.created_at, Set(expected_pdt));\n\n        let expected_odt =\n            time::OffsetDateTime::from_unix_timestamp_nanos(epoch_us as i128 * 1_000)\n                .expect(\"valid\");\n        assert_eq!(am.updated_at, Set(expected_odt));\n        assert_eq!(am.nullable_ts, Set(Some(expected_odt)));\n    }\n\n    #[test]\n    fn test_from_arrow_time_crate_nanos() {\n        // 2024-06-15 10:30:00.123456789 UTC\n        let epoch_ns: i64 = 1_718_447_400_123_456_789;\n        let epoch_days: i32 = 19889;\n        let time_ns: i64 = 10 * 3_600_000_000_000 + 30 * 60_000_000_000 + 123_456_789;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"created_date\", DataType::Date32, false),\n            Field::new(\n                \"created_time\",\n                DataType::Time64(TimeUnit::Nanosecond),\n                false,\n            ),\n            Field::new(\n                \"created_at\",\n                DataType::Timestamp(TimeUnit::Nanosecond, None),\n                false,\n            ),\n            Field::new(\n                \"updated_at\",\n                DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into())),\n                false,\n            ),\n            Field::new(\n                \"nullable_ts\",\n                DataType::Timestamp(TimeUnit::Nanosecond, Some(\"UTC\".into())),\n                true,\n            ),\n        ]));\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1, 2])),\n                Arc::new(Date32Array::from(vec![epoch_days, epoch_days])),\n                Arc::new(Time64NanosecondArray::from(vec![time_ns, time_ns])),\n                Arc::new(TimestampNanosecondArray::from(vec![epoch_ns, epoch_ns])),\n                Arc::new(\n                    TimestampNanosecondArray::from(vec![epoch_ns, epoch_ns]).with_timezone(\"UTC\"),\n                ),\n                Arc::new(\n                    TimestampNanosecondArray::from(vec![Some(epoch_ns), None]).with_timezone(\"UTC\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = time_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 2);\n\n        let am = &ams[0];\n\n        let expected_date =\n            time::Date::from_calendar_date(2024, time::Month::June, 15).expect(\"valid\");\n        assert_eq!(am.created_date, Set(expected_date));\n\n        let expected_time = time::Time::from_hms_nano(10, 30, 0, 123_456_789).expect(\"valid\");\n        assert_eq!(am.created_time, Set(expected_time));\n\n        let expected_pdt = time::PrimitiveDateTime::new(expected_date, expected_time);\n        assert_eq!(am.created_at, Set(expected_pdt));\n\n        let expected_odt =\n            time::OffsetDateTime::from_unix_timestamp_nanos(epoch_ns as i128).expect(\"valid\");\n        assert_eq!(am.updated_at, Set(expected_odt));\n        assert_eq!(am.nullable_ts, Set(Some(expected_odt)));\n\n        // Second row: nullable_ts should be None\n        let am = &ams[1];\n        assert_eq!(am.nullable_ts, Set(None));\n    }\n\n    #[test]\n    fn test_to_arrow_time_crate_roundtrip() {\n        use sea_orm::ArrowSchema;\n\n        let schema = time_entity::Entity::arrow_schema();\n\n        let date = time::Date::from_calendar_date(2024, time::Month::June, 15).expect(\"valid\");\n        let time_val = time::Time::from_hms(10, 30, 0).expect(\"valid\");\n        let pdt = time::PrimitiveDateTime::new(date, time_val);\n        let odt = time::OffsetDateTime::from_unix_timestamp_nanos(1_718_447_400_000_000_000)\n            .expect(\"valid\");\n\n        let models = vec![\n            time_entity::ActiveModel {\n                id: Set(1),\n                created_date: Set(date),\n                created_time: Set(time_val),\n                created_at: Set(pdt),\n                updated_at: Set(odt),\n                nullable_ts: Set(Some(odt)),\n            },\n            time_entity::ActiveModel {\n                id: Set(2),\n                created_date: Set(date),\n                created_time: Set(time_val),\n                created_at: Set(pdt),\n                updated_at: Set(odt),\n                nullable_ts: NotSet,\n            },\n        ];\n\n        let batch = time_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n        assert_eq!(batch.num_rows(), 2);\n\n        // Verify Date32\n        let date_arr = batch\n            .column_by_name(\"created_date\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Date32Array>()\n            .unwrap();\n        assert_eq!(date_arr.value(0), 19889); // 2024-06-15\n\n        // Verify Time64\n        let time_arr = batch\n            .column_by_name(\"created_time\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Time64MicrosecondArray>()\n            .unwrap();\n        let expected_time_us: i64 = 10 * 3_600_000_000 + 30 * 60_000_000;\n        assert_eq!(time_arr.value(0), expected_time_us);\n\n        // Verify nullable: row 0 present, row 1 null\n        let nullable_arr = batch\n            .column_by_name(\"nullable_ts\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<TimestampMicrosecondArray>()\n            .unwrap();\n        assert!(!nullable_arr.is_null(0));\n        assert!(nullable_arr.is_null(1));\n\n        // Full roundtrip\n        let roundtripped = time_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(roundtripped.len(), 2);\n        assert_eq!(roundtripped[0].id, Set(1));\n        assert_eq!(roundtripped[0].created_date, Set(date));\n        assert_eq!(roundtripped[0].created_time, Set(time_val));\n        assert_eq!(roundtripped[0].created_at, Set(pdt));\n        assert_eq!(roundtripped[0].updated_at, Set(odt));\n        assert_eq!(roundtripped[0].nullable_ts, Set(Some(odt)));\n        assert_eq!(roundtripped[1].nullable_ts, Set(None));\n    }\n}\n\n/// rust_decimal type tests\n#[cfg(feature = \"with-rust_decimal\")]\nmod rust_decimal_tests {\n    use super::*;\n\n    mod decimal_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[sea_orm::model]\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"test_rust_decimal\", arrow_schema)]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(column_type = \"Decimal(Some((10, 2)))\")]\n            pub price: Decimal,\n            #[sea_orm(column_type = \"Decimal(Some((20, 4)))\")]\n            pub amount: Decimal,\n            #[sea_orm(column_type = \"Decimal(Some((10, 2)))\")]\n            pub nullable_decimal: Option<Decimal>,\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    fn test_from_arrow_decimal128_rust_decimal() {\n        use rust_decimal::Decimal;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"price\", DataType::Decimal128(10, 2), false),\n            Field::new(\"amount\", DataType::Decimal128(20, 4), false),\n            Field::new(\"nullable_decimal\", DataType::Decimal128(10, 2), true),\n        ]));\n\n        // Create test data: price=12345.67, amount=9876543.2109\n        let price_scaled = 1234567i128; // 12345.67 with scale 2\n        let amount_scaled = 98765432109i128; // 9876543.2109 with scale 4\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1, 2])),\n                Arc::new(\n                    Decimal128Array::from(vec![price_scaled, price_scaled])\n                        .with_precision_and_scale(10, 2)\n                        .expect(\"valid precision/scale\"),\n                ),\n                Arc::new(\n                    Decimal128Array::from(vec![amount_scaled, amount_scaled])\n                        .with_precision_and_scale(20, 4)\n                        .expect(\"valid precision/scale\"),\n                ),\n                Arc::new(\n                    Decimal128Array::from(vec![Some(price_scaled), None])\n                        .with_precision_and_scale(10, 2)\n                        .expect(\"valid precision/scale\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = decimal_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 2);\n\n        let am = &ams[0];\n        assert_eq!(am.id, Set(1));\n        assert_eq!(\n            am.price,\n            Set(Decimal::from_i128_with_scale(price_scaled, 2))\n        );\n        assert_eq!(\n            am.amount,\n            Set(Decimal::from_i128_with_scale(amount_scaled, 4))\n        );\n        assert_eq!(\n            am.nullable_decimal,\n            Set(Some(Decimal::from_i128_with_scale(price_scaled, 2)))\n        );\n\n        // Second row: nullable_decimal should be None\n        let am = &ams[1];\n        assert_eq!(am.nullable_decimal, Set(None));\n    }\n\n    #[test]\n    fn test_from_arrow_decimal128_edge_cases() {\n        use rust_decimal::Decimal;\n\n        // Test zero, negative, and large values\n        let zero = Decimal::from_i128_with_scale(0, 2);\n        let negative = Decimal::from_i128_with_scale(-123456, 2);\n        let large = Decimal::from_i128_with_scale(123456789012345678i128, 10);\n\n        assert_eq!(zero.to_string(), \"0.00\");\n        assert_eq!(negative.to_string(), \"-1234.56\");\n        assert!(large.to_string().contains(\"12345678.9012345678\"));\n    }\n\n    #[test]\n    fn test_to_arrow_rust_decimal_roundtrip() {\n        use rust_decimal::Decimal;\n        use sea_orm::ArrowSchema;\n\n        let schema = decimal_entity::Entity::arrow_schema();\n\n        let price = Decimal::new(1234567, 2); // 12345.67\n        let amount = Decimal::new(98765432109, 4); // 9876543.2109\n\n        let models = vec![\n            decimal_entity::ActiveModel {\n                id: Set(1),\n                price: Set(price),\n                amount: Set(amount),\n                nullable_decimal: Set(Some(price)),\n            },\n            decimal_entity::ActiveModel {\n                id: Set(2),\n                price: Set(price),\n                amount: Set(amount),\n                nullable_decimal: Set(None),\n            },\n        ];\n\n        let batch =\n            decimal_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n        assert_eq!(batch.num_rows(), 2);\n\n        // price has precision 10 (≤18), so it becomes Decimal64\n        let price_arr = batch\n            .column_by_name(\"price\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal64Array>()\n            .unwrap();\n        assert_eq!(price_arr.value(0), 1234567);\n        assert_eq!(price_arr.precision(), 10);\n        assert_eq!(price_arr.scale(), 2);\n\n        // nullable_decimal also has precision 10 → Decimal64\n        let nullable_arr = batch\n            .column_by_name(\"nullable_decimal\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal64Array>()\n            .unwrap();\n        assert!(!nullable_arr.is_null(0));\n        assert!(nullable_arr.is_null(1));\n\n        // Full roundtrip\n        let roundtripped =\n            decimal_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(roundtripped, models);\n    }\n\n    #[test]\n    fn test_to_arrow_rust_decimal_decimal128_roundtrip() {\n        use rust_decimal::Decimal;\n\n        let schema = Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, true),\n            Field::new(\"price\", DataType::Decimal128(10, 2), true),\n            Field::new(\"amount\", DataType::Decimal128(20, 4), true),\n            Field::new(\"nullable_decimal\", DataType::Decimal128(10, 2), true),\n        ]);\n\n        let price = Decimal::new(1234567, 2);\n        let amount = Decimal::new(98765432109, 4);\n\n        let models = vec![\n            decimal_entity::ActiveModel {\n                id: Set(1),\n                price: Set(price),\n                amount: Set(amount),\n                nullable_decimal: Set(Some(price)),\n            },\n            decimal_entity::ActiveModel {\n                id: Set(2),\n                price: Set(price),\n                amount: Set(amount),\n                nullable_decimal: Set(None),\n            },\n        ];\n\n        let batch =\n            decimal_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n        assert_eq!(batch.num_rows(), 2);\n\n        let price_arr = batch\n            .column_by_name(\"price\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal128Array>()\n            .unwrap();\n        assert_eq!(price_arr.value(0), 1234567);\n        assert_eq!(price_arr.precision(), 10);\n        assert_eq!(price_arr.scale(), 2);\n\n        let amount_arr = batch\n            .column_by_name(\"amount\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal128Array>()\n            .unwrap();\n        assert_eq!(amount_arr.value(0), 98765432109);\n        assert_eq!(amount_arr.precision(), 20);\n        assert_eq!(amount_arr.scale(), 4);\n\n        let nullable_arr = batch\n            .column_by_name(\"nullable_decimal\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal128Array>()\n            .unwrap();\n        assert!(!nullable_arr.is_null(0));\n        assert_eq!(nullable_arr.value(0), 1234567);\n        assert!(nullable_arr.is_null(1));\n\n        // Roundtrip through Decimal128\n        let roundtripped =\n            decimal_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(roundtripped, models);\n    }\n}\n\n/// bigdecimal type tests\n#[cfg(feature = \"with-bigdecimal\")]\nmod bigdecimal_tests {\n    use super::*;\n\n    mod decimal_entity {\n        use sea_orm::entity::prelude::*;\n\n        #[sea_orm::model]\n        #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"test_bigdecimal\", arrow_schema)]\n        pub struct Model {\n            #[sea_orm(primary_key)]\n            pub id: i32,\n            #[sea_orm(column_type = \"Decimal(Some((10, 2)))\")]\n            pub price: BigDecimal,\n            #[sea_orm(column_type = \"Decimal(Some((20, 4)))\")]\n            pub amount: BigDecimal,\n            #[sea_orm(column_type = \"Decimal(Some((10, 2)))\")]\n            pub nullable_decimal: Option<BigDecimal>,\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    #[test]\n    #[cfg(not(feature = \"with-rust_decimal\"))]\n    fn test_from_arrow_decimal128_bigdecimal() {\n        use bigdecimal::{BigDecimal, num_bigint::BigInt};\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"price\", DataType::Decimal128(10, 2), false),\n            Field::new(\"amount\", DataType::Decimal128(20, 4), false),\n            Field::new(\"nullable_decimal\", DataType::Decimal128(10, 2), true),\n        ]));\n\n        // Create test data: price=12345.67, amount=9876543.2109\n        let price_scaled = 1234567i128; // 12345.67 with scale 2\n        let amount_scaled = 98765432109i128; // 9876543.2109 with scale 4\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1, 2])),\n                Arc::new(\n                    Decimal128Array::from(vec![price_scaled, price_scaled])\n                        .with_precision_and_scale(10, 2)\n                        .expect(\"valid precision/scale\"),\n                ),\n                Arc::new(\n                    Decimal128Array::from(vec![amount_scaled, amount_scaled])\n                        .with_precision_and_scale(20, 4)\n                        .expect(\"valid precision/scale\"),\n                ),\n                Arc::new(\n                    Decimal128Array::from(vec![Some(price_scaled), None])\n                        .with_precision_and_scale(10, 2)\n                        .expect(\"valid precision/scale\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        let ams = decimal_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(ams.len(), 2);\n\n        let am = &ams[0];\n        assert_eq!(am.id, Set(1));\n        assert_eq!(\n            am.price,\n            Set(BigDecimal::new(BigInt::from(price_scaled), 2))\n        );\n        assert_eq!(\n            am.amount,\n            Set(BigDecimal::new(BigInt::from(amount_scaled), 4))\n        );\n        assert_eq!(\n            am.nullable_decimal,\n            Set(Some(BigDecimal::new(BigInt::from(price_scaled), 2)))\n        );\n\n        // Second row: nullable_decimal should be None\n        let am = &ams[1];\n        assert_eq!(am.nullable_decimal, Set(None));\n    }\n\n    #[test]\n    fn test_from_arrow_decimal256_bigdecimal() {\n        use sea_orm_arrow::arrow::datatypes::i256;\n\n        let schema = Arc::new(Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, false),\n            Field::new(\"large_value\", DataType::Decimal256(76, 20), false),\n            Field::new(\"nullable_large\", DataType::Decimal256(76, 20), true),\n        ]));\n\n        // Create a large i256 value\n        let large_val = i256::from_i128(123456789012345678i128);\n\n        let batch = RecordBatch::try_new(\n            schema,\n            vec![\n                Arc::new(Int32Array::from(vec![1, 2])),\n                Arc::new(\n                    Decimal256Array::from(vec![large_val, large_val])\n                        .with_precision_and_scale(76, 20)\n                        .expect(\"valid precision/scale\"),\n                ),\n                Arc::new(\n                    Decimal256Array::from(vec![Some(large_val), None])\n                        .with_precision_and_scale(76, 20)\n                        .expect(\"valid precision/scale\"),\n                ),\n            ],\n        )\n        .expect(\"Failed to create RecordBatch\");\n\n        // Test the batch was created correctly\n        assert_eq!(batch.num_rows(), 2);\n        assert_eq!(batch.num_columns(), 3);\n\n        // Test that we can read the decimal values\n        let arr = batch\n            .column(1)\n            .as_any()\n            .downcast_ref::<Decimal256Array>()\n            .expect(\"Expected Decimal256Array\");\n        assert_eq!(arr.value(0), large_val);\n        assert_eq!(arr.precision(), 76);\n        assert_eq!(arr.scale(), 20);\n    }\n\n    #[test]\n    #[cfg(not(feature = \"with-rust_decimal\"))]\n    fn test_to_arrow_bigdecimal_roundtrip() {\n        use bigdecimal::{BigDecimal, num_bigint::BigInt};\n        use sea_orm::ArrowSchema;\n\n        let schema = decimal_entity::Entity::arrow_schema();\n\n        let price = BigDecimal::new(BigInt::from(1234567i64), 2); // 12345.67\n        let amount = BigDecimal::new(BigInt::from(98765432109i64), 4); // 9876543.2109\n\n        let models = vec![\n            decimal_entity::ActiveModel {\n                id: Set(1),\n                price: Set(price.clone()),\n                amount: Set(amount.clone()),\n                nullable_decimal: Set(Some(price.clone())),\n            },\n            decimal_entity::ActiveModel {\n                id: Set(2),\n                price: Set(price.clone()),\n                amount: Set(amount.clone()),\n                nullable_decimal: Set(None),\n            },\n        ];\n\n        let batch =\n            decimal_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n        assert_eq!(batch.num_rows(), 2);\n\n        // price has precision 10 (≤18), so it becomes Decimal64\n        let price_arr = batch\n            .column_by_name(\"price\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal64Array>()\n            .unwrap();\n        assert_eq!(price_arr.value(0), 1234567);\n        assert_eq!(price_arr.precision(), 10);\n        assert_eq!(price_arr.scale(), 2);\n\n        // nullable_decimal also has precision 10 → Decimal64\n        let nullable_arr = batch\n            .column_by_name(\"nullable_decimal\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal64Array>()\n            .unwrap();\n        assert!(!nullable_arr.is_null(0));\n        assert!(nullable_arr.is_null(1));\n\n        // Full roundtrip\n        let roundtripped =\n            decimal_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(roundtripped, models);\n    }\n\n    #[test]\n    #[cfg(not(feature = \"with-rust_decimal\"))]\n    fn test_to_arrow_bigdecimal_decimal128_roundtrip() {\n        use bigdecimal::{BigDecimal, num_bigint::BigInt};\n\n        let schema = Schema::new(vec![\n            Field::new(\"id\", DataType::Int32, true),\n            Field::new(\"price\", DataType::Decimal128(10, 2), true),\n            Field::new(\"amount\", DataType::Decimal128(20, 4), true),\n            Field::new(\"nullable_decimal\", DataType::Decimal128(10, 2), true),\n        ]);\n\n        let price = BigDecimal::new(BigInt::from(1234567i64), 2);\n        let amount = BigDecimal::new(BigInt::from(98765432109i64), 4);\n\n        let models = vec![\n            decimal_entity::ActiveModel {\n                id: Set(1),\n                price: Set(price.clone()),\n                amount: Set(amount.clone()),\n                nullable_decimal: Set(Some(price.clone())),\n            },\n            decimal_entity::ActiveModel {\n                id: Set(2),\n                price: Set(price.clone()),\n                amount: Set(amount.clone()),\n                nullable_decimal: Set(None),\n            },\n        ];\n\n        let batch =\n            decimal_entity::ActiveModel::to_arrow(&models, &schema).expect(\"to_arrow failed\");\n        assert_eq!(batch.num_rows(), 2);\n\n        let price_arr = batch\n            .column_by_name(\"price\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal128Array>()\n            .unwrap();\n        assert_eq!(price_arr.value(0), 1234567);\n        assert_eq!(price_arr.precision(), 10);\n        assert_eq!(price_arr.scale(), 2);\n\n        let amount_arr = batch\n            .column_by_name(\"amount\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal128Array>()\n            .unwrap();\n        assert_eq!(amount_arr.value(0), 98765432109);\n        assert_eq!(amount_arr.precision(), 20);\n        assert_eq!(amount_arr.scale(), 4);\n\n        let nullable_arr = batch\n            .column_by_name(\"nullable_decimal\")\n            .unwrap()\n            .as_any()\n            .downcast_ref::<Decimal128Array>()\n            .unwrap();\n        assert!(!nullable_arr.is_null(0));\n        assert_eq!(nullable_arr.value(0), 1234567);\n        assert!(nullable_arr.is_null(1));\n\n        // Roundtrip through Decimal128\n        let roundtripped =\n            decimal_entity::ActiveModel::from_arrow(&batch).expect(\"from_arrow failed\");\n        assert_eq!(roundtripped, models);\n    }\n}\n"
  },
  {
    "path": "tests/basic.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use sea_orm::{Database, DbConn, entity::*, error::*, query::*, sea_query, tests_cfg::*};\n\n// DATABASE_URL=sqlite::memory: cargo test --features rusqlite --test basic\n// DATABASE_URL=sqlite::memory: cargo test --features sqlx-sqlite,runtime-tokio --test basic\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-sqlite\")]\nasync fn main() -> Result<(), DbErr> {\n    dotenv::from_filename(\".env.local\").ok();\n    dotenv::from_filename(\".env\").ok();\n\n    let base_url = std::env::var(\"DATABASE_URL\").unwrap_or_else(|_| \"sqlite::memory:\".to_owned());\n\n    let db: DbConn = Database::connect(&base_url).await?;\n    setup_schema(&db).await?;\n    crud_cake(&db).await?;\n\n    Ok(())\n}\n\n#[cfg(feature = \"sqlx-sqlite\")]\nasync fn setup_schema(db: &DbConn) -> Result<(), DbErr> {\n    use sea_query::*;\n\n    let stmt = sea_query::Table::create()\n        .table(cake::Entity)\n        .col(\n            ColumnDef::new(cake::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(cake::Column::Name).string())\n        .to_owned();\n\n    let result = db.execute(&stmt).await?;\n    println!(\"Create table cake: {result:?}\");\n\n    Ok(())\n}\n\n#[cfg(feature = \"sqlx-sqlite\")]\nasync fn crud_cake(db: &DbConn) -> Result<(), DbErr> {\n    let apple = cake::ActiveModel {\n        name: Set(\"Apple Pie\".to_owned()),\n        ..Default::default()\n    };\n\n    let mut apple = apple.save(db).await?;\n\n    println!();\n    println!(\"Inserted: {apple:?}\");\n\n    assert_eq!(\n        apple,\n        cake::ActiveModel {\n            id: Unchanged(1),\n            name: Unchanged(\"Apple Pie\".to_owned()),\n        }\n    );\n\n    apple.name = Set(\"Lemon Tart\".to_owned());\n\n    let apple = apple.save(db).await?;\n\n    println!();\n    println!(\"Updated: {apple:?}\");\n\n    let count = cake::Entity::find().count(db).await?;\n\n    println!();\n    println!(\"Count: {count:?}\");\n    assert_eq!(count, 1);\n\n    let apple = cake::Entity::find_by_id(1).one(db).await?;\n\n    assert_eq!(\n        Some(cake::Model {\n            id: 1,\n            name: \"Lemon Tart\".to_owned(),\n        }),\n        apple\n    );\n\n    let apple: cake::Model = apple.unwrap();\n\n    let result = apple.delete(db).await?;\n\n    println!();\n    println!(\"Deleted: {result:?}\");\n\n    let apple = cake::Entity::find_by_id(1).one(db).await?;\n\n    assert_eq!(None, apple);\n\n    let count = cake::Entity::find().count(db).await?;\n\n    println!();\n    println!(\"Count: {count:?}\");\n    assert_eq!(count, 0);\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/bits_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse common::features::*;\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-postgres\")]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = common::TestContext::new(\"bits_tests\").await;\n    create_bits_table(&ctx.db).await?;\n    create_and_update(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn create_and_update(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let bits = bits::Model {\n        id: 1,\n        bit0: 0,\n        bit1: 1,\n        bit8: 8,\n        bit16: 16,\n        bit32: 32,\n        bit64: 64,\n    };\n\n    let res = bits.clone().into_active_model().insert(db).await?;\n\n    let model = Bits::find().one(db).await?;\n    assert_eq!(model, Some(res));\n    assert_eq!(model, Some(bits.clone()));\n\n    let res = bits::ActiveModel {\n        bit32: Set(320),\n        bit64: Set(640),\n        ..bits.clone().into_active_model()\n    }\n    .update(db)\n    .await?;\n\n    let model = Bits::find().one(db).await?;\n    assert_eq!(model, Some(res));\n    assert_eq!(\n        model,\n        Some(bits::Model {\n            id: 1,\n            bit0: 0,\n            bit1: 1,\n            bit8: 8,\n            bit16: 16,\n            bit32: 320,\n            bit64: 640,\n        })\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/byte_primary_key_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"byte_primary_key_tests\").await;\n    create_byte_primary_key_table(&ctx.db).await?;\n    create_and_update(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn create_and_update(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use common::features::byte_primary_key::*;\n\n    let model = Model {\n        id: vec![1, 2, 3],\n        value: \"First Row\".to_owned(),\n    };\n\n    let res = Entity::insert(model.clone().into_active_model())\n        .exec(db)\n        .await?;\n\n    assert_eq!(Entity::find().one(db).await?, Some(model.clone()));\n\n    assert_eq!(res.last_insert_id, model.id);\n\n    let updated_active_model = ActiveModel {\n        value: Set(\"First Row (Updated)\".to_owned()),\n        ..model.clone().into_active_model()\n    };\n\n    let update_res = Entity::update(updated_active_model.clone())\n        .validate()?\n        .filter(Column::Id.eq(vec![1_u8, 2_u8, 4_u8])) // annotate it as Vec<u8> explicitly\n        .exec(db)\n        .await;\n\n    assert_eq!(update_res, Err(DbErr::RecordNotUpdated));\n\n    let update_res = Entity::update(updated_active_model)\n        .validate()?\n        .filter(Column::Id.eq(vec![1_u8, 2_u8, 3_u8])) // annotate it as Vec<u8> explicitly\n        .exec(db)\n        .await?;\n\n    assert_eq!(\n        update_res,\n        Model {\n            id: vec![1, 2, 3],\n            value: \"First Row (Updated)\".to_owned(),\n        }\n    );\n\n    assert_eq!(\n        Entity::find()\n            .filter(Column::Id.eq(vec![1_u8, 2_u8, 3_u8])) // annotate it as Vec<u8> explicitly\n            .one(db)\n            .await?,\n        Some(Model {\n            id: vec![1, 2, 3],\n            value: \"First Row (Updated)\".to_owned(),\n        })\n    );\n\n    assert_eq!(\n        Entity::find()\n            .filter(Column::Id.eq(vec![1_u8, 2_u8, 3_u8])) // annotate it as Vec<u8> explicitly\n            .into_values::<_, Column>()\n            .one(db)\n            .await?,\n        Some((vec![1_u8, 2_u8, 3_u8], \"First Row (Updated)\".to_owned(),))\n    );\n\n    assert_eq!(\n        Entity::find()\n            .filter(Column::Id.eq(vec![1_u8, 2_u8, 3_u8])) // annotate it as Vec<u8> explicitly\n            .into_tuple()\n            .one(db)\n            .await?,\n        Some((vec![1_u8, 2_u8, 3_u8], \"First Row (Updated)\".to_owned(),))\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/collection_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, DerivePartialModel, QueryOrder, entity::prelude::*, entity::*};\nuse serde_json::json;\n\n#[sea_orm_macros::test]\n#[cfg(all(feature = \"sqlx-postgres\", feature = \"postgres-array\"))]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"collection_tests\").await;\n    create_tea_enum(&ctx.db).await?;\n    create_collection_table(&ctx.db).await?;\n    insert_collection(&ctx.db).await?;\n    update_collection(&ctx.db).await?;\n    select_collection(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use collection::*;\n\n    let uuid = Uuid::new_v4();\n\n    assert_eq!(\n        Model {\n            id: 1,\n            name: \"Collection 1\".into(),\n            integers: vec![1, 2, 3],\n            integers_opt: Some(vec![1, 2, 3]),\n            teas: vec![Tea::BreakfastTea],\n            teas_opt: Some(vec![Tea::BreakfastTea]),\n            colors: vec![Color::Black],\n            colors_opt: Some(vec![Color::Black]),\n            uuid: vec![uuid],\n            uuid_hyphenated: vec![uuid.hyphenated()],\n        }\n        .into_active_model()\n        .insert(db)\n        .await?,\n        Model {\n            id: 1,\n            name: \"Collection 1\".into(),\n            integers: vec![1, 2, 3],\n            integers_opt: Some(vec![1, 2, 3]),\n            teas: vec![Tea::BreakfastTea],\n            teas_opt: Some(vec![Tea::BreakfastTea]),\n            colors: vec![Color::Black],\n            colors_opt: Some(vec![Color::Black]),\n            uuid: vec![uuid],\n            uuid_hyphenated: vec![uuid.hyphenated()],\n        }\n    );\n\n    assert_eq!(\n        Model {\n            id: 2,\n            name: \"Collection 2\".into(),\n            integers: vec![10, 9],\n            integers_opt: None,\n            teas: vec![Tea::BreakfastTea, Tea::AfternoonTea],\n            teas_opt: None,\n            colors: vec![Color::Black],\n            colors_opt: None,\n            uuid: vec![uuid],\n            uuid_hyphenated: vec![uuid.hyphenated()],\n        }\n        .into_active_model()\n        .insert(db)\n        .await?,\n        Model {\n            id: 2,\n            name: \"Collection 2\".into(),\n            integers: vec![10, 9],\n            integers_opt: None,\n            teas: vec![Tea::BreakfastTea, Tea::AfternoonTea],\n            teas_opt: None,\n            colors: vec![Color::Black],\n            colors_opt: None,\n            uuid: vec![uuid],\n            uuid_hyphenated: vec![uuid.hyphenated()],\n        }\n    );\n\n    assert_eq!(\n        Model {\n            id: 3,\n            name: \"Collection 3\".into(),\n            integers: vec![],\n            integers_opt: Some(vec![]),\n            teas: vec![],\n            teas_opt: Some(vec![]),\n            colors: vec![],\n            colors_opt: Some(vec![]),\n            uuid: vec![uuid],\n            uuid_hyphenated: vec![uuid.hyphenated()],\n        }\n        .into_active_model()\n        .insert(db)\n        .await?,\n        Model {\n            id: 3,\n            name: \"Collection 3\".into(),\n            integers: vec![],\n            integers_opt: Some(vec![]),\n            teas: vec![],\n            teas_opt: Some(vec![]),\n            colors: vec![],\n            colors_opt: Some(vec![]),\n            uuid: vec![uuid],\n            uuid_hyphenated: vec![uuid.hyphenated()],\n        }\n    );\n\n    assert_eq!(\n        Entity::find_by_id(1).into_json().one(db).await?,\n        Some(json!({\n            \"id\": 1,\n            \"name\": \"Collection 1\",\n            \"integers\": [1, 2, 3],\n            \"integers_opt\": [1, 2, 3],\n            \"teas\": [\"BreakfastTea\"],\n            \"teas_opt\": [\"BreakfastTea\"],\n            \"colors\": [0],\n            \"colors_opt\": [0],\n            \"uuid\": [uuid],\n            \"uuid_hyphenated\": [uuid.hyphenated()],\n        }))\n    );\n\n    assert_eq!(\n        Entity::find_by_id(2).into_json().one(db).await?,\n        Some(json!({\n            \"id\": 2,\n            \"name\": \"Collection 2\",\n            \"integers\": [10, 9],\n            \"integers_opt\": null,\n            \"teas\": [\"BreakfastTea\", \"AfternoonTea\"],\n            \"teas_opt\": null,\n            \"colors\": [0],\n            \"colors_opt\": null,\n            \"uuid\": [uuid],\n            \"uuid_hyphenated\": [uuid.hyphenated()],\n        }))\n    );\n\n    assert_eq!(\n        Entity::find_by_id(3).into_json().one(db).await?,\n        Some(json!({\n            \"id\": 3,\n            \"name\": \"Collection 3\",\n            \"integers\": [],\n            \"integers_opt\": [],\n            \"teas\": [],\n            \"teas_opt\": [],\n            \"colors\": [],\n            \"colors_opt\": [],\n            \"uuid\": [uuid],\n            \"uuid_hyphenated\": [uuid.hyphenated()],\n        }))\n    );\n\n    let found = Entity::find()\n        .filter(Entity::COLUMN.teas.contains(vec![Tea::BreakfastTea]))\n        .order_by_asc(Entity::COLUMN.id)\n        .all(db)\n        .await?;\n\n    assert_eq!(found.len(), 2);\n    assert_eq!(found[0].id, 1);\n    assert_eq!(found[1].id, 2);\n\n    let found = Entity::find()\n        .filter(Entity::COLUMN.teas.contains(vec![Tea::AfternoonTea]))\n        .order_by_asc(Entity::COLUMN.id)\n        .all(db)\n        .await?;\n\n    assert_eq!(found.len(), 1);\n    assert_eq!(found[0].id, 2);\n\n    let found = Entity::find()\n        .filter(\n            Entity::COLUMN\n                .teas\n                .overlap(vec![Tea::BreakfastTea, Tea::AfternoonTea]),\n        )\n        .order_by_asc(Entity::COLUMN.id)\n        .all(db)\n        .await?;\n\n    assert_eq!(found.len(), 2);\n    assert_eq!(found[0].id, 1);\n    assert_eq!(found[1].id, 2);\n\n    let found = Entity::find()\n        .filter(Entity::COLUMN.integers.contains(vec![10]))\n        .order_by_asc(Entity::COLUMN.id)\n        .all(db)\n        .await?;\n\n    assert_eq!(found.len(), 1);\n    assert_eq!(found[0].id, 2);\n\n    Ok(())\n}\n\npub async fn update_collection(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use collection::*;\n\n    let uuid = Uuid::new_v4();\n    let model = Entity::find_by_id(1).one(db).await?.unwrap();\n\n    ActiveModel {\n        integers: Set(vec![4, 5, 6]),\n        integers_opt: Set(Some(vec![4, 5, 6])),\n        teas: Set(vec![Tea::EverydayTea]),\n        teas_opt: Set(Some(vec![Tea::EverydayTea])),\n        colors: Set(vec![Color::White]),\n        colors_opt: Set(Some(vec![Color::White])),\n        ..model.into_active_model()\n    }\n    .update(db)\n    .await?;\n\n    ActiveModel {\n        id: Unchanged(3),\n        name: Set(\"Collection 3\".into()),\n        integers: Set(vec![3, 1, 4]),\n        integers_opt: Set(None),\n        teas: Set(vec![Tea::EverydayTea]),\n        teas_opt: Set(None),\n        colors: Set(vec![Color::White]),\n        colors_opt: Set(None),\n        uuid: Set(vec![uuid]),\n        uuid_hyphenated: Set(vec![uuid.hyphenated()]),\n    }\n    .update(db)\n    .await?;\n\n    Ok(())\n}\n\npub async fn select_collection(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use collection::*;\n\n    #[derive(DerivePartialModel, Debug, PartialEq)]\n    #[sea_orm(entity = \"Entity\")]\n    struct PartialSelectResult {\n        name: String,\n    }\n\n    let result = Entity::find_by_id(1)\n        .into_partial_model::<PartialSelectResult>()\n        .one(db)\n        .await?;\n\n    assert_eq!(\n        result,\n        Some(PartialSelectResult {\n            name: \"Collection 1\".into(),\n        })\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/common/bakery_chain/Readme.md",
    "content": "# Schema for SeaORM test suite\n\n![Entity Relation Diagram](bakery_chain_erd.png)\n\nERD generated by DataGrip."
  },
  {
    "path": "tests/common/bakery_chain/baker.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"baker\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub contact_details: Json,\n    pub bakery_id: Option<i32>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::bakery::Entity\",\n        from = \"Column::BakeryId\",\n        to = \"super::bakery::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"SetNull\"\n    )]\n    Bakery,\n}\n\nimpl Related<super::bakery::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bakery.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cakes_bakers::Relation::Cake.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cakes_bakers::Relation::Baker.def().rev())\n    }\n}\n\npub struct BakedForCustomer;\n\nimpl Linked for BakedForCustomer {\n    type FromEntity = Entity;\n\n    type ToEntity = super::customer::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![\n            super::cakes_bakers::Relation::Baker.def().rev(),\n            super::cakes_bakers::Relation::Cake.def(),\n            super::lineitem::Relation::Cake.def().rev(),\n            super::lineitem::Relation::Order.def(),\n            super::order::Relation::Customer.def(),\n        ]\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/bakery_chain/bakery.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bakery\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub profit_margin: f64,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::baker::Entity\")]\n    Baker,\n    #[sea_orm(has_many = \"super::order::Entity\")]\n    Order,\n    #[sea_orm(has_many = \"super::cake::Entity\")]\n    Cake,\n}\n\nimpl Related<super::baker::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Baker.def()\n    }\n}\n\nimpl Related<super::order::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Order.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\npub struct ToBaker;\n\nimpl Linked for ToBaker {\n    type FromEntity = Entity;\n    type ToEntity = super::baker::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::Baker.def()]\n    }\n}\n"
  },
  {
    "path": "tests/common/bakery_chain/cake.rs",
    "content": "use sea_orm::{ConnectionTrait, entity::prelude::*};\n\n#[sea_orm::compact_model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub price: Decimal,\n    pub bakery_id: Option<i32>,\n    pub gluten_free: bool,\n    pub serial: Uuid,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::bakery::Entity\",\n        from = \"Column::BakeryId\",\n        to = \"super::bakery::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"SetNull\"\n    )]\n    Bakery,\n    #[sea_orm(has_many = \"super::lineitem::Entity\")]\n    Lineitem,\n}\n\nimpl Related<super::bakery::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bakery.def()\n    }\n}\n\nimpl Related<super::baker::Entity> for Entity {\n    fn to() -> RelationDef {\n        super::cakes_bakers::Relation::Baker.def()\n    }\n\n    fn via() -> Option<RelationDef> {\n        Some(super::cakes_bakers::Relation::Cake.def().rev())\n    }\n}\n\nimpl Related<super::lineitem::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Lineitem.def()\n    }\n}\n\npub struct ToBakery;\nimpl Linked for ToBakery {\n    type FromEntity = super::cake::Entity;\n    type ToEntity = super::bakery::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::Bakery.def()]\n    }\n}\n\n#[async_trait::async_trait]\nimpl ActiveModelBehavior for ActiveModel {\n    fn new() -> Self {\n        use sea_orm::Set;\n        Self {\n            serial: Set(Uuid::new_v4()),\n            ..ActiveModelTrait::default()\n        }\n    }\n\n    async fn before_save<C>(self, _db: &C, insert: bool) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.price.as_ref() == &Decimal::ZERO {\n            Err(DbErr::Custom(format!(\n                \"[before_save] Invalid Price, insert: {insert}\"\n            )))\n        } else {\n            Ok(self)\n        }\n    }\n\n    async fn after_save<C>(model: Model, _db: &C, insert: bool) -> Result<Model, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if model.price < Decimal::ZERO {\n            Err(DbErr::Custom(format!(\n                \"[after_save] Invalid Price, insert: {insert}\"\n            )))\n        } else {\n            Ok(model)\n        }\n    }\n\n    async fn before_delete<C>(self, _db: &C) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.name.as_ref().contains(\"(err_on_before_delete)\") {\n            Err(DbErr::Custom(\n                \"[before_delete] Cannot be deleted\".to_owned(),\n            ))\n        } else {\n            Ok(self)\n        }\n    }\n\n    async fn after_delete<C>(self, _db: &C) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        if self.name.as_ref().contains(\"(err_on_after_delete)\") {\n            Err(DbErr::Custom(\"[after_delete] Cannot be deleted\".to_owned()))\n        } else {\n            Ok(self)\n        }\n    }\n}\n\n#[test]\nfn column_type_test() {\n    let _id: sea_orm::NumericColumn<Entity> = COLUMN.id;\n    let _name: sea_orm::StringColumn<Entity> = COLUMN.name;\n    let _price: sea_orm::NumericColumn<Entity> = COLUMN.price;\n    let _bakery_id: sea_orm::NumericColumnNullable<Entity> = COLUMN.bakery_id;\n    let _gluten_free: sea_orm::BoolColumn<Entity> = COLUMN.gluten_free;\n    let _serial: sea_orm::UuidColumn<Entity> = COLUMN.serial;\n}\n"
  },
  {
    "path": "tests/common/bakery_chain/cakes_bakers.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cakes_bakers\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key)]\n    pub baker_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Cake,\n    #[sea_orm(\n        belongs_to = \"super::baker::Entity\",\n        from = \"Column::BakerId\",\n        to = \"super::baker::Column::Id\"\n    )]\n    Baker,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/bakery_chain/customer.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"customer\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub notes: Option<String>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::order::Entity\")]\n    Order,\n}\n\nimpl Related<super::order::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Order.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/bakery_chain/lineitem.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"lineitem\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub price: Decimal,\n    pub quantity: i32,\n    #[sea_orm(unique_key = \"lineitem\")]\n    pub order_id: i32,\n    #[sea_orm(unique_key = \"lineitem\")]\n    pub cake_id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::order::Entity\",\n        from = \"Column::OrderId\",\n        to = \"super::order::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Order,\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\"\n    )]\n    Cake,\n}\n\nimpl Related<super::order::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Order.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/bakery_chain/mod.rs",
    "content": "pub mod baker;\npub mod bakery;\npub mod cake;\npub mod cakes_bakers;\npub mod customer;\npub mod lineitem;\npub mod order;\npub mod schema;\npub mod seed_data;\n\npub use baker::Entity as Baker;\npub use bakery::Entity as Bakery;\npub use cake::Entity as Cake;\npub use cakes_bakers::Entity as CakesBakers;\npub use customer::Entity as Customer;\npub use lineitem::Entity as Lineitem;\npub use order::Entity as Order;\npub use schema::*;\n"
  },
  {
    "path": "tests/common/bakery_chain/order.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"order\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub total: Decimal,\n    pub bakery_id: i32,\n    pub customer_id: i32,\n    pub placed_at: DateTimeUtc,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::bakery::Entity\",\n        from = \"Column::BakeryId\",\n        to = \"super::bakery::Column::Id\"\n    )]\n    Bakery,\n    #[sea_orm(\n        belongs_to = \"super::customer::Entity\",\n        from = \"Column::CustomerId\",\n        to = \"super::customer::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Customer,\n    #[sea_orm(has_many = \"super::lineitem::Entity\")]\n    Lineitem,\n}\n\nimpl Related<super::bakery::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Bakery.def()\n    }\n}\n\nimpl Related<super::customer::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Customer.def()\n    }\n}\n\nimpl Related<super::lineitem::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Lineitem.def()\n    }\n}\n\npub struct ToCustomer;\nimpl Linked for ToCustomer {\n    type FromEntity = Entity;\n    type ToEntity = super::customer::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::Customer.def()]\n    }\n}\n\npub struct ToLineitem;\nimpl Linked for ToLineitem {\n    type FromEntity = Entity;\n    type ToEntity = super::lineitem::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::Lineitem.def()]\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/bakery_chain/schema.rs",
    "content": "use super::*;\nuse crate::common::setup::{create_table, create_table_with_index};\nuse sea_orm::{\n    ConnectionTrait, DatabaseConnection, DbConn, ExecResult, Schema, error::*, sea_query,\n};\nuse sea_query::{ColumnDef, ForeignKey, ForeignKeyAction, Index, Table};\n\npub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> {\n    create_bakery_table(db).await?;\n    create_baker_table(db).await?;\n    create_customer_table(db).await?;\n    create_order_table(db).await?;\n    create_cake_table(db).await?;\n    create_cakes_bakers_table(db).await?;\n    create_lineitem_table(db).await?;\n    Ok(())\n}\n\npub async fn create_bakery_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(bakery::Entity)\n        .col(\n            ColumnDef::new(bakery::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(bakery::Column::Name).string().not_null())\n        .col(\n            ColumnDef::new(bakery::Column::ProfitMargin)\n                .double()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, Bakery).await\n}\n\npub async fn create_baker_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(baker::Entity)\n        .col(\n            ColumnDef::new(baker::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(baker::Column::Name).string().not_null())\n        .col(\n            ColumnDef::new(baker::Column::ContactDetails)\n                .json()\n                .not_null(),\n        )\n        .col(ColumnDef::new(baker::Column::BakeryId).integer())\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-baker-bakery_id\")\n                .from(baker::Entity, baker::Column::BakeryId)\n                .to(bakery::Entity, bakery::Column::Id)\n                .on_delete(ForeignKeyAction::SetNull)\n                .on_update(ForeignKeyAction::Cascade),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, Baker).await\n}\n\npub async fn create_customer_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(customer::Entity)\n        .col(\n            ColumnDef::new(customer::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(customer::Column::Name).string().not_null())\n        .col(ColumnDef::new(customer::Column::Notes).text())\n        .to_owned();\n\n    create_table(db, &stmt, Customer).await\n}\n\npub async fn create_order_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(order::Entity)\n        .col(\n            ColumnDef::new(order::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(order::Column::Total)\n                .decimal_len(16, 4)\n                .not_null(),\n        )\n        .col(ColumnDef::new(order::Column::BakeryId).integer().not_null())\n        .col(\n            ColumnDef::new(order::Column::CustomerId)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(order::Column::PlacedAt)\n                .timestamp_with_time_zone()\n                .not_null(),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-order-bakery_id\")\n                .from(order::Entity, order::Column::BakeryId)\n                .to(bakery::Entity, bakery::Column::Id),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-order-customer_id\")\n                .from(order::Entity, order::Column::CustomerId)\n                .to(customer::Entity, customer::Column::Id)\n                .on_delete(ForeignKeyAction::Cascade)\n                .on_update(ForeignKeyAction::Cascade),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, Order).await\n}\n\npub async fn create_lineitem_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(lineitem::Entity)\n        .col(\n            ColumnDef::new(lineitem::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(lineitem::Column::Price)\n                .decimal_len(16, 4)\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(lineitem::Column::Quantity)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(lineitem::Column::OrderId)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(lineitem::Column::CakeId)\n                .integer()\n                .not_null(),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-lineitem-order_id\")\n                .from(lineitem::Entity, lineitem::Column::OrderId)\n                .to(order::Entity, order::Column::Id)\n                .on_delete(ForeignKeyAction::Cascade)\n                .on_update(ForeignKeyAction::Cascade),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-lineitem-cake_id\")\n                .from(lineitem::Entity, lineitem::Column::CakeId)\n                .to(cake::Entity, cake::Column::Id),\n        )\n        .to_owned();\n\n    let backend = db.get_database_backend();\n    let stmts = Schema::new(backend).create_index_from_entity(lineitem::Entity);\n    assert_eq!(stmts.len(), 1);\n    assert_eq!(\n        backend.build(&stmts[0]),\n        backend.build(\n            Index::create()\n                .name(\"idx-lineitem-lineitem\")\n                .table(lineitem::Entity)\n                .col(lineitem::Column::OrderId)\n                .col(lineitem::Column::CakeId)\n                .unique()\n        )\n    );\n\n    create_table_with_index(db, &stmt, Lineitem).await\n}\n\npub async fn create_cakes_bakers_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(cakes_bakers::Entity)\n        .col(\n            ColumnDef::new(cakes_bakers::Column::CakeId)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(cakes_bakers::Column::BakerId)\n                .integer()\n                .not_null(),\n        )\n        .primary_key(\n            Index::create()\n                .name(\"pk-cakes_bakers\")\n                .col(cakes_bakers::Column::CakeId)\n                .col(cakes_bakers::Column::BakerId),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-cakes_bakers-cake_id\")\n                .from(cakes_bakers::Entity, cakes_bakers::Column::CakeId)\n                .to(cake::Entity, cake::Column::Id)\n                .on_delete(ForeignKeyAction::Cascade)\n                .on_update(ForeignKeyAction::Cascade),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-cakes_bakers-baker_id\")\n                .from(cakes_bakers::Entity, cakes_bakers::Column::BakerId)\n                .to(baker::Entity, baker::Column::Id),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, CakesBakers).await\n}\n\npub async fn create_cake_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(cake::Entity)\n        .col(\n            ColumnDef::new(cake::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(cake::Column::Name).string().not_null())\n        .col(\n            ColumnDef::new(cake::Column::Price)\n                .decimal_len(16, 4)\n                .not_null(),\n        )\n        .col(ColumnDef::new(cake::Column::BakeryId).integer())\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-cake-bakery_id\")\n                .from(cake::Entity, cake::Column::BakeryId)\n                .to(bakery::Entity, bakery::Column::Id)\n                .on_delete(ForeignKeyAction::SetNull)\n                .on_update(ForeignKeyAction::Cascade),\n        )\n        .col(\n            ColumnDef::new(cake::Column::GlutenFree)\n                .boolean()\n                .not_null(),\n        )\n        .col(ColumnDef::new(cake::Column::Serial).uuid().not_null())\n        .to_owned();\n\n    create_table(db, &stmt, Cake).await\n}\n"
  },
  {
    "path": "tests/common/bakery_chain/seed_data.rs",
    "content": "use super::*;\nuse crate::common::TestContext;\nuse sea_orm::{NotSet, Set, prelude::*};\n\npub async fn init_1(ctx: &TestContext, link: bool) {\n    bakery::Entity::insert(bakery::ActiveModel {\n        id: Set(42),\n        name: Set(\"cool little bakery\".to_string()),\n        profit_margin: Set(4.1),\n    })\n    .exec(&ctx.db)\n    .await\n    .expect(\"insert succeeds\");\n\n    cake::Entity::insert(cake::ActiveModel {\n        id: Set(13),\n        name: Set(\"Cheesecake\".to_owned()),\n        price: Set(2.into()),\n        bakery_id: Set(if link { Some(42) } else { None }),\n        gluten_free: Set(false),\n        ..Default::default()\n    })\n    .exec(&ctx.db)\n    .await\n    .expect(\"insert succeeds\");\n\n    cake::Entity::insert(cake::ActiveModel {\n        id: Set(15),\n        name: Set(\"Chocolate\".to_owned()),\n        price: Set(3.into()),\n        bakery_id: Set(if link { Some(42) } else { None }),\n        gluten_free: Set(true),\n        ..Default::default()\n    })\n    .exec(&ctx.db)\n    .await\n    .expect(\"insert succeeds\");\n\n    baker::Entity::insert(baker::ActiveModel {\n        id: Set(22),\n        name: Set(\"Master Baker\".to_owned()),\n        contact_details: Set(Json::Null),\n        bakery_id: Set(if link { Some(42) } else { None }),\n    })\n    .exec(&ctx.db)\n    .await\n    .expect(\"insert succeeds\");\n\n    if link {\n        cakes_bakers::Entity::insert(cakes_bakers::ActiveModel {\n            cake_id: Set(13),\n            baker_id: Set(22),\n        })\n        .exec(&ctx.db)\n        .await\n        .expect(\"insert succeeds\");\n\n        customer::Entity::insert(customer::ActiveModel {\n            id: Set(11),\n            name: Set(\"Bob\".to_owned()),\n            notes: Set(Some(\"Sweet tooth\".to_owned())),\n        })\n        .exec(&ctx.db)\n        .await\n        .expect(\"insert succeeds\");\n\n        order::Entity::insert(order::ActiveModel {\n            id: Set(101),\n            total: Set(10.into()),\n            bakery_id: Set(42),\n            customer_id: Set(11),\n            placed_at: Set(\"2020-01-01T00:00:00Z\".parse().unwrap()),\n        })\n        .exec(&ctx.db)\n        .await\n        .expect(\"insert succeeds\");\n\n        lineitem::Entity::insert(lineitem::ActiveModel {\n            id: NotSet,\n            price: Set(2.into()),\n            quantity: Set(2),\n            order_id: Set(101),\n            cake_id: Set(13),\n        })\n        .exec(&ctx.db)\n        .await\n        .expect(\"insert succeeds\");\n\n        lineitem::Entity::insert(lineitem::ActiveModel {\n            id: NotSet,\n            price: Set(3.into()),\n            quantity: Set(2),\n            order_id: Set(101),\n            cake_id: Set(15),\n        })\n        .exec(&ctx.db)\n        .await\n        .expect(\"insert succeeds\");\n    }\n}\n\npub async fn init_2(ctx: &TestContext) -> Result<(), DbErr> {\n    let db = &ctx.db;\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let sea = Bakery::insert(bakery).exec(db).await?.last_insert_id;\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"LakeSide Bakery\".to_owned()),\n        profit_margin: Set(5.8),\n        ..Default::default()\n    };\n    let lake = Bakery::insert(bakery).exec(db).await?.last_insert_id;\n\n    let alice = baker::ActiveModel {\n        name: Set(\"Alice\".to_owned()),\n        contact_details: Set(\"+44 15273388\".into()),\n        bakery_id: Set(Some(sea)),\n        ..Default::default()\n    };\n    let alice = Baker::insert(alice).exec(db).await?.last_insert_id;\n\n    let bob = baker::ActiveModel {\n        name: Set(\"Bob\".to_owned()),\n        contact_details: Set(\"+852 12345678\".into()),\n        bakery_id: Set(Some(lake)),\n        ..Default::default()\n    };\n    let bob = Baker::insert(bob).exec(db).await?.last_insert_id;\n\n    let cake = cake::ActiveModel {\n        name: Set(\"Chocolate Cake\".to_owned()),\n        price: Set(\"10.25\".parse().unwrap()),\n        gluten_free: Set(false),\n        bakery_id: Set(Some(sea)),\n        ..Default::default()\n    };\n    let choco = Cake::insert(cake).exec(db).await?.last_insert_id;\n\n    let cake = cake::ActiveModel {\n        name: Set(\"Double Chocolate\".to_owned()),\n        price: Set(\"12.5\".parse().unwrap()),\n        gluten_free: Set(false),\n        bakery_id: Set(Some(sea)),\n        ..Default::default()\n    };\n    let double_1 = Cake::insert(cake.clone()).exec(db).await?.last_insert_id;\n\n    let mut cake = cake::ActiveModel {\n        name: Set(\"Lemon Cake\".to_owned()),\n        price: Set(\"8.8\".parse().unwrap()),\n        gluten_free: Set(true),\n        bakery_id: Set(Some(sea)),\n        ..Default::default()\n    };\n    let lemon_1 = Cake::insert(cake.clone()).exec(db).await?.last_insert_id;\n    cake.bakery_id = Set(Some(lake));\n    let _lemon_2 = Cake::insert(cake).exec(db).await?.last_insert_id;\n\n    let cake = cake::ActiveModel {\n        name: Set(\"Strawberry Cake\".to_owned()),\n        price: Set(\"9.9\".parse().unwrap()),\n        gluten_free: Set(false),\n        bakery_id: Set(Some(lake)),\n        ..Default::default()\n    };\n    let straw_2 = Cake::insert(cake).exec(db).await?.last_insert_id;\n\n    let cake = cake::ActiveModel {\n        name: Set(\"Orange Cake\".to_owned()),\n        price: Set(\"6.5\".parse().unwrap()),\n        gluten_free: Set(true),\n        bakery_id: Set(Some(lake)),\n        ..Default::default()\n    };\n    let orange = Cake::insert(cake).exec(db).await?.last_insert_id;\n\n    let mut cake = cake::ActiveModel {\n        name: Set(\"New York Cheese\".to_owned()),\n        price: Set(\"12.5\".parse().unwrap()),\n        gluten_free: Set(false),\n        bakery_id: Set(Some(sea)),\n        ..Default::default()\n    };\n    let cheese_1 = Cake::insert(cake.clone()).exec(db).await?.last_insert_id;\n    cake.bakery_id = Set(Some(lake));\n    let cheese_2 = Cake::insert(cake).exec(db).await?.last_insert_id;\n\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(choco),\n        baker_id: Set(alice),\n    };\n    CakesBakers::insert(rel).exec(db).await?;\n\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(double_1),\n        baker_id: Set(alice),\n    };\n    CakesBakers::insert(rel).exec(db).await?;\n\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(lemon_1),\n        baker_id: Set(alice),\n    };\n    CakesBakers::insert(rel).exec(db).await?;\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(lemon_1),\n        baker_id: Set(bob),\n    };\n    CakesBakers::insert(rel).exec(db).await?;\n\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(straw_2),\n        baker_id: Set(bob),\n    };\n    CakesBakers::insert(rel).exec(db).await?;\n\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(orange),\n        baker_id: Set(bob),\n    };\n    CakesBakers::insert(rel).exec(db).await?;\n\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(cheese_1),\n        baker_id: Set(alice),\n    };\n    CakesBakers::insert(rel).exec(db).await?;\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(cheese_1),\n        baker_id: Set(bob),\n    };\n    CakesBakers::insert(rel).exec(db).await?;\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(cheese_2),\n        baker_id: Set(alice),\n    };\n    CakesBakers::insert(rel).exec(db).await?;\n    let rel = cakes_bakers::ActiveModel {\n        cake_id: Set(cheese_2),\n        baker_id: Set(bob),\n    };\n    CakesBakers::insert(rel).exec(db).await?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/common/bakery_dense/NOTES.md",
    "content": "To regenerate entities, run at project root:\n```sh\nDATABASE_URL=\"postgres://sea:sea@localhost/bakery_chain_schema_crud_tests\" cargo run --manifest-path sea-orm-cli/Cargo.toml -- generate entity -o tests/common/bakery_dense --entity-format dense --er-diagram\n```"
  },
  {
    "path": "tests/common/bakery_dense/baker.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"baker\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub contact_details: Json,\n    pub bakery_id: Option<i32>,\n    #[sea_orm(\n        belongs_to,\n        from = \"bakery_id\",\n        to = \"id\",\n        on_update = \"Cascade\",\n        on_delete = \"SetNull\"\n    )]\n    pub bakery: HasOne<super::bakery::Entity>,\n    #[sea_orm(has_many, via = \"cakes_bakers::Baker\")]\n    pub cakes: HasMany<super::cake::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/bakery_dense/bakery.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bakery\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(column_type = \"Double\")]\n    pub profit_margin: f64,\n    #[sea_orm(has_many)]\n    pub bakers: HasMany<super::baker::Entity>,\n    #[sea_orm(has_many)]\n    pub cakes: HasMany<super::cake::Entity>,\n    #[sea_orm(has_many)]\n    pub orders: HasMany<super::order::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/bakery_dense/cake.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cake\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(unique)]\n    pub name: String,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub price: Decimal,\n    pub bakery_id: Option<i32>,\n    pub gluten_free: bool,\n    pub serial: Uuid,\n    #[sea_orm(belongs_to, from = \"BakeryId\", to = \"Id\")]\n    pub bakery: HasOne<super::bakery::Entity>,\n    #[sea_orm(has_many)]\n    pub lineitems: HasMany<super::lineitem::Entity>,\n    #[sea_orm(has_many, via = \"cakes_bakers\")]\n    pub bakers: HasMany<super::baker::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {\n    fn new() -> Self {\n        use sea_orm::Set;\n        Self {\n            serial: Set(Uuid::new_v4()),\n            ..ActiveModelTrait::default()\n        }\n    }\n}\n\n/* // Following will be generated\n\npub struct EntityLoader {\n    select: sea_orm::Select<Entity>,\n    with: EntityLoaderWith,\n}\n\n#[derive(Debug, Default)]\nstruct EntityLoaderWith {\n    bakery: bool,\n    baker: bool,\n}\n\nimpl sea_orm::QueryFilter for EntityLoader {\n    type QueryStatement = <sea_orm::Select<Entity> as sea_orm::QueryFilter>::QueryStatement;\n\n    fn query(&mut self) -> &mut Self::QueryStatement {\n        sea_orm::QueryFilter::query(&mut self.select)\n    }\n}\n\nimpl sea_orm::QueryOrder for EntityLoader {\n    type QueryStatement = <sea_orm::Select<Entity> as sea_orm::QueryOrder>::QueryStatement;\n\n    fn query(&mut self) -> &mut Self::QueryStatement {\n        sea_orm::QueryOrder::query(&mut self.select)\n    }\n}\n\nimpl sea_orm::compound::EntityLoaderTrait<Entity> for EntityLoader {}\n\nimpl Entity {\n    pub fn load() -> EntityLoader {\n        EntityLoader {\n            select: Entity::find(),\n            with: Default::default(),\n        }\n    }\n}\n\nimpl EntityLoader {\n    pub async fn one<C: sea_orm::ConnectionTrait>(\n        mut self,\n        db: &C,\n    ) -> Result<Option<Model>, DbErr> {\n        use sea_orm::QuerySelect;\n\n        self.select = self.select.limit(1);\n        Ok(self.all(db).await?.into_iter().next())\n    }\n\n    pub fn with<R>(mut self, entity: R) -> Self\n    where\n        R: EntityTrait,\n        Entity: Related<R>,\n    {\n        if entity.table_ref() == super::bakery::Entity.table_ref() {\n            self.with.bakery = true;\n        }\n        if entity.table_ref() == super::baker::Entity.table_ref() {\n            self.with.baker = true;\n        }\n        self\n    }\n\n    pub async fn load<C: sea_orm::ConnectionTrait>(Vec<Model>, with: &EntityLoaderWith, nest: &EntityLoaderNest, db: &C) -> Result<Vec<Model>, DbErr> {\n        if self.with.baker {\n            let bakers = cakes.load_many(super::baker::Entity, db).await?;\n            super::baker::EntityLoader::load_nest_nest(bakers, &nest.baker).await?;\n\n            for (cake, bakers) in cakes.iter_mut().zip(bakers) {\n                cake.bakers.set(bakers);\n            }\n        }\n    }\n\n    pub async fn all<C: sea_orm::ConnectionTrait>(mut self, db: &C) -> Result<Vec<Model>, DbErr> {\n        let select = if self.with.bakery {\n            self.with.bakery = false;\n            self.select.find_also(Entity, super::bakery::Entity)\n        } else {\n            // select also but without join\n            self.select.select_also_fake(super::bakery::Entity)\n        };\n\n        let models = select.all(db).await?;\n\n        let mut cakes = Vec::new();\n\n        for (mut cake, bakery) in models {\n            cake.bakery.set(bakery);\n            cakes.push(cake);\n        }\n\n        let cakes = Self::load(cakes, &self.with, db).await?;\n\n        Ok(cakes)\n    }\n}\n\n*/\n"
  },
  {
    "path": "tests/common/bakery_dense/cakes_bakers.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"cakes_bakers\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub cake_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub baker_id: i32,\n    #[sea_orm(belongs_to, from = \"baker_id\", to = \"id\")]\n    pub baker: Option<super::baker::Entity>,\n    #[sea_orm(belongs_to, from = \"cake_id\", to = \"id\")]\n    pub cake: Option<super::cake::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/bakery_dense/customer.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"customer\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(column_type = \"Text\", nullable)]\n    pub notes: Option<String>,\n    #[sea_orm(has_many)]\n    pub orders: HasMany<super::order::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/bakery_dense/entities.mermaid",
    "content": "erDiagram\n    baker {\n        int id PK\n        varchar name\n        json contact_details\n        int bakery_id FK\n    }\n    bakery {\n        int id PK\n        varchar name\n        double profit_margin\n    }\n    cake {\n        int id PK\n        varchar name\n        decimal price\n        int bakery_id FK\n        bool gluten_free\n        uuid serial\n    }\n    cakes_bakers {\n        int cake_id PK,FK\n        int baker_id PK,FK\n    }\n    customer {\n        int id PK\n        varchar name\n        text notes\n    }\n    lineitem {\n        int id PK\n        decimal price\n        int quantity\n        int order_id FK,UK\n        int cake_id FK,UK\n    }\n    order {\n        int id PK\n        decimal total\n        int bakery_id FK\n        int customer_id FK\n        timestamptz placed_at\n    }\n    baker }o--|| bakery : \"bakery_id\"\n    baker }o--o{ cake : \"[cakes_bakers]\"\n    cake }o--|| bakery : \"bakery_id\"\n    cakes_bakers }o--|| baker : \"baker_id\"\n    cakes_bakers }o--|| cake : \"cake_id\"\n    lineitem }o--|| cake : \"cake_id\"\n    lineitem }o--|| order : \"order_id\"\n    order }o--|| bakery : \"bakery_id\"\n    order }o--|| customer : \"customer_id\"\n"
  },
  {
    "path": "tests/common/bakery_dense/lineitem.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::compact_model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"lineitem\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub price: Decimal,\n    pub quantity: i32,\n    pub order_id: i32,\n    pub cake_id: i32,\n    pub order: Option<super::order::Entity>,\n    pub cake: Option<super::cake::Entity>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        belongs_to = \"super::order::Entity\",\n        from = \"Column::OrderId\",\n        to = \"super::order::Column::Id\",\n        on_update = \"Cascade\",\n        on_delete = \"Cascade\"\n    )]\n    Order,\n    #[sea_orm(\n        belongs_to = \"super::cake::Entity\",\n        from = \"Column::CakeId\",\n        to = \"super::cake::Column::Id\"\n    )]\n    Cake,\n}\n\nimpl Related<super::order::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Order.def()\n    }\n}\n\nimpl Related<super::cake::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::Cake.def()\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/bakery_dense/mod.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n// DATABASE_URL=sqlite://bakery.db cargo run --manifest-path sea-orm-cli/Cargo.toml -- generate entity --output-dir tests/common/bakery_dense --entity-format dense\n\npub mod prelude;\n\npub mod baker;\npub mod bakery;\npub mod cake;\npub mod cakes_bakers;\npub mod customer;\npub mod lineitem;\npub mod order;\n"
  },
  {
    "path": "tests/common/bakery_dense/order.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.9\n\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"order\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Decimal(Some((16, 4)))\")]\n    pub total: Decimal,\n    pub bakery_id: i32,\n    pub customer_id: i32,\n    pub placed_at: DateTimeWithTimeZone,\n    #[sea_orm(belongs_to, from = \"bakery_id\", to = \"id\")]\n    pub bakery: HasOne<super::bakery::Entity>,\n    #[sea_orm(belongs_to, from = \"customer_id\", to = \"id\")]\n    pub customer: HasOne<super::customer::Entity>,\n    #[sea_orm(has_many)]\n    pub lineitems: HasMany<super::lineitem::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/bakery_dense/prelude.rs",
    "content": "//! `SeaORM` Entity, @generated by sea-orm-codegen 2.0.0-rc.16\n\npub use super::baker::Entity as Baker;\npub use super::bakery::Entity as Bakery;\npub use super::cake::Entity as Cake;\npub use super::cakes_bakers::Entity as CakesBakers;\npub use super::customer::Entity as Customer;\npub use super::lineitem::Entity as Lineitem;\npub use super::order::Entity as Order;\n"
  },
  {
    "path": "tests/common/blogger/attachment.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"attachment\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub post_id: Option<i32>,\n    pub file: String,\n    #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n    pub post: HasOne<super::post::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/blogger/comment.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"comment\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub comment: String,\n    pub user_id: i32,\n    pub post_id: i32,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub user: HasOne<super::user::Entity>,\n    #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n    pub post: HasOne<super::post::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/blogger/mod.rs",
    "content": "pub mod attachment;\npub mod comment;\npub mod post;\npub mod post_tag;\npub mod profile;\npub mod tag;\npub mod user;\npub mod user_follower;\npub mod user_mono;\n"
  },
  {
    "path": "tests/common/blogger/post.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"post\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub user_id: i32,\n    pub title: String,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub author: HasOne<super::user::Entity>,\n    #[sea_orm(has_many)]\n    pub comments: HasMany<super::comment::Entity>,\n    #[sea_orm(has_many)]\n    pub attachments: HasMany<super::attachment::Entity>,\n    #[sea_orm(has_many, via = \"post_tag\")]\n    pub tags: HasMany<super::tag::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/blogger/post_tag.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n#[sea_orm(table_name = \"post_tag\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub post_id: i32,\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub tag_id: i32,\n    #[sea_orm(belongs_to, from = \"post_id\", to = \"id\")]\n    pub post: Option<super::post::Entity>,\n    #[sea_orm(belongs_to, from = \"tag_id\", to = \"id\")]\n    pub tag: Option<super::tag::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/blogger/profile.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"profile\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub picture: String,\n    #[sea_orm(unique)]\n    pub user_id: i32,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub user: HasOne<super::user::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/blogger/tag.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"tag\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub tag: String,\n    #[sea_orm(has_many, via = \"post_tag\")]\n    pub posts: HasMany<super::post::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/blogger/user.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"user\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(unique)]\n    pub email: String,\n    #[sea_orm(has_one)]\n    pub profile: HasOne<super::profile::Entity>,\n    #[sea_orm(has_many)]\n    pub posts: HasMany<super::post::Entity>,\n    #[sea_orm(self_ref, via = \"user_follower\", from = \"User\", to = \"Follower\")]\n    pub followers: HasMany<Entity>,\n    #[sea_orm(self_ref, via = \"user_follower\", reverse)]\n    pub following: HasMany<Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\npub use super::user_follower::Entity as Follower;\n// the name `EntityReverse` is still subject to change\npub use super::user_follower::EntityReverse as Following;\n\n// the following trait impl will be generated by the marco:\n// impl RelatedSelfVia<super::user_follower::Entity> for Entity {\n//     fn to() -> RelationDef {\n//         super::user_follower::Relation::Follower.def()\n//     }\n//     fn via() -> RelationDef {\n//         super::user_follower::Relation::User.def().rev()\n//     }\n// }\n"
  },
  {
    "path": "tests/common/blogger/user_follower.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]\n#[sea_orm(table_name = \"user_follower\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub user_id: i32,\n    #[sea_orm(primary_key)]\n    pub follower_id: i32,\n    #[sea_orm(belongs_to, from = \"user_id\", to = \"id\")]\n    pub user: Option<super::user::Entity>,\n    #[sea_orm(\n        belongs_to,\n        relation_enum = \"Follower\",\n        from = \"follower_id\",\n        to = \"id\"\n    )]\n    pub follower: Option<super::user::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/blogger/user_mono.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"user\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(unique)]\n    pub email: String,\n    #[sea_orm(self_ref, via = \"user_follower\", from = \"User\", to = \"Follower\")]\n    pub followers: HasMany<Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/active_enum.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"sqlx-postgres\", sea_orm(schema_name = \"public\"))]\n#[sea_orm(table_name = \"active_enum\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub category: Option<Category>,\n    pub color: Option<Color>,\n    pub tea: Option<Tea>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(has_many = \"super::active_enum_child::Entity\")]\n    ActiveEnumChild,\n}\n\nimpl Related<super::active_enum_child::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::ActiveEnumChild.def()\n    }\n}\n\npub struct ActiveEnumChildLink;\n\nimpl Linked for ActiveEnumChildLink {\n    type FromEntity = Entity;\n\n    type ToEntity = super::active_enum_child::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::ActiveEnumChild.def()]\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/active_enum_child.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"sqlx-postgres\", sea_orm(schema_name = \"public\"))]\n#[sea_orm(table_name = \"active_enum_child\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub parent_id: i32,\n    pub category: Option<Category>,\n    pub color: Option<Color>,\n    pub tea: Option<Tea>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {\n    #[sea_orm(\n        fk_name = \"fk-active_enum_child-active_enum\",\n        belongs_to = \"super::active_enum::Entity\",\n        from = \"Column::ParentId\",\n        to = \"super::active_enum::Column::Id\"\n    )]\n    ActiveEnum,\n}\n\nimpl Related<super::active_enum::Entity> for Entity {\n    fn to() -> RelationDef {\n        Relation::ActiveEnum.def()\n    }\n}\n\npub struct ActiveEnumLink;\n\nimpl Linked for ActiveEnumLink {\n    type FromEntity = Entity;\n\n    type ToEntity = super::active_enum::Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::ActiveEnum.def()]\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/active_enum_vec.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[cfg_attr(feature = \"sqlx-postgres\", sea_orm(schema_name = \"public\"))]\n#[sea_orm(table_name = \"active_enum\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub categories: Option<Vec<Category>>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/applog.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"applog\", comment = \"app logs\")]\npub struct Model {\n    #[sea_orm(primary_key, comment = \"ID\")]\n    pub id: i32,\n    #[sea_orm(comment = \"action\")]\n    pub action: String,\n    #[sea_orm(comment = \"action data\")]\n    pub json: Json,\n    #[sea_orm(comment = \"create time\")]\n    pub created_at: DateTimeWithTimeZone,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/binary.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"binary\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Binary(1)\")]\n    pub binary: Vec<u8>,\n    #[sea_orm(column_type = \"Binary(10)\")]\n    pub binary_10: Vec<u8>,\n    #[sea_orm(column_type = \"VarBinary(StringLen::N(16))\")]\n    pub var_binary_16: Vec<u8>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/bits.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bits\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(\n        column_type = r#\"custom(\"BIT\")\"#,\n        select_as = \"BIGINT\",\n        save_as = \"BIT\"\n    )]\n    pub bit0: i64,\n    #[sea_orm(\n        column_type = r#\"custom(\"BIT(1)\")\"#,\n        select_as = \"BIGINT\",\n        save_as = \"BIT(1)\"\n    )]\n    pub bit1: i64,\n    #[sea_orm(\n        column_type = r#\"custom(\"BIT(8)\")\"#,\n        select_as = \"BIGINT\",\n        save_as = \"BIT(8)\"\n    )]\n    pub bit8: i64,\n    #[sea_orm(\n        column_type = r#\"custom(\"BIT(16)\")\"#,\n        select_as = \"BIGINT\",\n        save_as = \"BIT(16)\"\n    )]\n    pub bit16: i64,\n    #[sea_orm(\n        column_type = r#\"custom(\"BIT(32)\")\"#,\n        select_as = \"BIGINT\",\n        save_as = \"BIT(32)\"\n    )]\n    pub bit32: i64,\n    #[sea_orm(\n        column_type = r#\"custom(\"BIT(64)\")\"#,\n        select_as = \"BIGINT\",\n        save_as = \"BIT(64)\"\n    )]\n    pub bit64: i64,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/byte_primary_key.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"byte_primary_key\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id: Vec<u8>,\n    pub value: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/categories.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"categories\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id: i32,\n    pub categories: Option<Vec<Category>>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/collection.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm::compact_model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"collection\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(\n        column_type = r#\"custom(\"citext\")\"#,\n        select_as = \"text\",\n        save_as = \"citext\"\n    )]\n    pub name: String,\n    pub integers: Vec<i32>,\n    pub integers_opt: Option<Vec<i32>>,\n    pub teas: Vec<Tea>,\n    pub teas_opt: Option<Vec<Tea>>,\n    pub colors: Vec<Color>,\n    pub colors_opt: Option<Vec<Color>>,\n    pub uuid: Vec<Uuid>,\n    pub uuid_hyphenated: Vec<uuid::fmt::Hyphenated>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/collection_expanded.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity;\n\nimpl EntityName for Entity {\n    fn schema_name(&self) -> Option<&str> {\n        Some(\"schema_name\")\n    }\n\n    fn table_name(&self) -> &'static str {\n        \"collection\"\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, DeriveModel, DeriveActiveModel, Eq)]\npub struct Model {\n    pub id: i32,\n    pub integers: Vec<i32>,\n    pub integers_opt: Option<Vec<i32>>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Integers,\n    IntegersOpt,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Integers => ColumnType::Array(RcOrArc::new(ColumnType::Integer)).def(),\n            Self::IntegersOpt => ColumnType::Array(RcOrArc::new(ColumnType::Integer))\n                .def()\n                .null(),\n        }\n    }\n}\n\nimpl RelationTrait for Relation {\n    fn def(&self) -> RelationDef {\n        panic!(\"No RelationDef\")\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/custom_active_model.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\nuse sea_orm::{ActiveValue, IntoActiveValue};\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[cfg_attr(feature = \"sqlx-postgres\", sea_orm(schema_name = \"public\"))]\n#[sea_orm(table_name = \"custom_active_model\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub age: i32,\n    pub weight: Option<f32>,\n    pub amount: Option<i32>,\n    pub tea: Tea,\n    pub category: Option<Category>,\n    pub color: Option<Color>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[derive(Clone, Debug, PartialEq, DeriveIntoActiveModel)]\npub struct CustomActiveModel {\n    pub age: Option<i32>,\n    pub weight: Option<f32>,\n    pub amount: Option<Option<i32>>,\n    pub tea: Option<Tea>,\n    pub category: Option<Category>,\n    pub color: Option<Option<Color>>,\n}\n"
  },
  {
    "path": "tests/common/features/dyn_table_name.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Copy, Clone, Default, Debug, DeriveEntity)]\npub struct Entity {\n    pub table_name: u32,\n}\n\nimpl EntityName for Entity {\n    fn table_name(&self) -> &'static str {\n        match self.table_name {\n            1 => \"dyn_table_1\",\n            2 => \"dyn_table_2\",\n            _ => \"\",\n        }\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)]\npub struct Model {\n    pub id: i32,\n    pub name: String,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\npub enum Column {\n    Id,\n    Name,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)]\npub enum PrimaryKey {\n    Id,\n}\n\nimpl PrimaryKeyTrait for PrimaryKey {\n    type ValueType = i32;\n\n    fn auto_increment() -> bool {\n        true\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ColumnTrait for Column {\n    type EntityName = Entity;\n\n    fn def(&self) -> ColumnDef {\n        match self {\n            Self::Id => ColumnType::Integer.def(),\n            Self::Name => ColumnType::String(StringLen::None).def(),\n        }\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/edit_log.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"edit_log\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub action: String,\n    pub values: Json,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/embedding.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"embedding\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id: i32,\n    pub embedding: PgVector,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/event_trigger.rs",
    "content": "use sea_orm::entity::prelude::*;\nuse sea_orm::{\n    TryGetError, TryGetable,\n    sea_query::{ArrayType, ColumnType, ValueType},\n};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"event_trigger\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub events: Events,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Event(pub String);\n\n#[derive(Clone, Debug, PartialEq, Eq)]\npub struct Events(pub Vec<Event>);\n\nimpl From<Events> for Value {\n    fn from(events: Events) -> Self {\n        let Events(events) = events;\n        let vec: Vec<String> = events.into_iter().map(|Event(s)| s).collect();\n        vec.into()\n    }\n}\n\nimpl TryGetable for Events {\n    fn try_get_by<I: sea_orm::ColIdx>(res: &QueryResult, idx: I) -> Result<Self, TryGetError> {\n        let vec: Vec<String> = res.try_get_by(idx).map_err(TryGetError::DbErr)?;\n        Ok(Events(vec.into_iter().map(Event).collect()))\n    }\n}\n\nimpl ValueType for Events {\n    fn try_from(v: Value) -> Result<Self, sea_query::ValueTypeErr> {\n        let value: Option<Vec<String>> =\n            v.expect(\"This Value::Array should consist of Value::String\");\n        let vec = match value {\n            Some(v) => v.into_iter().map(Event).collect(),\n            None => vec![],\n        };\n        Ok(Events(vec))\n    }\n\n    fn type_name() -> String {\n        stringify!(Events).to_owned()\n    }\n\n    fn array_type() -> ArrayType {\n        ArrayType::String\n    }\n\n    fn column_type() -> ColumnType {\n        ColumnType::Array(RcOrArc::new(ColumnType::String(StringLen::None)))\n    }\n}\n"
  },
  {
    "path": "tests/common/features/host_network.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"host_network\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub hostname: String,\n    pub ipaddress: IpNetwork,\n    #[sea_orm(column_type = \"Cidr\")]\n    pub network: IpNetwork,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/insert_default.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"insert_default\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/json_struct.rs",
    "content": "use sea_orm::FromJsonQueryResult;\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize, Serializer};\n\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"json_struct\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub json: Json,\n    pub json_value: KeyValue,\n    pub json_value_opt: Option<KeyValue>,\n    pub json_non_serializable: Option<NonSerializableStruct>,\n}\n\n#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, FromJsonQueryResult)]\npub struct KeyValue {\n    pub id: i32,\n    pub name: String,\n    pub price: f32,\n    pub notes: Option<String>,\n}\n\n#[derive(Clone, Debug, PartialEq, Deserialize, FromJsonQueryResult)]\npub struct NonSerializableStruct;\n\nimpl Serialize for NonSerializableStruct {\n    fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>\n    where\n        S: Serializer,\n    {\n        Err(serde::ser::Error::custom(\n            \"intentionally failing serialization\",\n        ))\n    }\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/json_vec.rs",
    "content": "use sea_orm::TryGetableFromJson;\nuse sea_orm::entity::prelude::*;\nuse serde::{Deserialize, Serialize};\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"json_vec\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub str_vec: Option<StringVec>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n\n#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]\npub struct StringVec(pub Vec<String>);\n\nimpl TryGetableFromJson for StringVec {}\n\nimpl From<StringVec> for Value {\n    fn from(source: StringVec) -> Self {\n        sea_orm::Value::Json(serde_json::to_value(source).ok().map(std::boxed::Box::new))\n    }\n}\n\nimpl sea_query::ValueType for StringVec {\n    fn try_from(v: Value) -> Result<Self, sea_query::ValueTypeErr> {\n        match v {\n            sea_orm::Value::Json(Some(json)) => {\n                Ok(serde_json::from_value(*json).map_err(|_| sea_orm::sea_query::ValueTypeErr)?)\n            }\n            _ => Err(sea_orm::sea_query::ValueTypeErr),\n        }\n    }\n\n    fn type_name() -> String {\n        stringify!(StringVec).to_owned()\n    }\n\n    fn array_type() -> sea_orm::sea_query::ArrayType {\n        sea_orm::sea_query::ArrayType::Json\n    }\n\n    fn column_type() -> sea_query::ColumnType {\n        sea_query::ColumnType::Json\n    }\n}\n\nimpl sea_orm::sea_query::Nullable for StringVec {\n    fn null() -> sea_orm::Value {\n        sea_orm::Value::Json(None)\n    }\n}\n"
  },
  {
    "path": "tests/common/features/json_vec_derive.rs",
    "content": "pub mod json_string_vec {\n    use sea_orm::FromJsonQueryResult;\n    use sea_orm::entity::prelude::*;\n    use serde::{Deserialize, Serialize};\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"json_string_vec\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub str_vec: Option<StringVec>,\n    }\n\n    #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, FromJsonQueryResult)]\n    pub struct StringVec(pub Vec<String>);\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod json_struct_vec {\n    use sea_orm::entity::prelude::*;\n    use sea_orm_macros::FromJsonQueryResult;\n    use serde::{Deserialize, Serialize};\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"json_struct_vec\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_type = \"JsonBinary\")]\n        pub struct_vec: Vec<JsonColumn>,\n    }\n\n    #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, FromJsonQueryResult)]\n    pub struct JsonColumn {\n        pub value: String,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n"
  },
  {
    "path": "tests/common/features/metadata.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"metadata\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub uuid: Uuid,\n    #[sea_orm(column_name = \"type\", enum_name = \"Type\")]\n    pub ty: String,\n    pub key: String,\n    pub value: String,\n    #[sea_orm(column_type = \"var_binary(32)\")]\n    pub bytes: Vec<u8>,\n    pub date: Option<Date>,\n    pub time: Option<Time>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/mod.rs",
    "content": "pub mod active_enum;\npub mod active_enum_child;\npub mod active_enum_vec;\npub mod applog;\npub mod binary;\npub mod bits;\npub mod byte_primary_key;\npub mod categories;\npub mod collection;\npub mod collection_expanded;\npub mod custom_active_model;\npub mod dyn_table_name;\npub mod edit_log;\n#[cfg(feature = \"postgres-vector\")]\npub mod embedding;\npub mod event_trigger;\n#[cfg(feature = \"with-ipnetwork\")]\npub mod host_network;\npub mod insert_default;\npub mod json_struct;\npub mod json_vec;\npub mod json_vec_derive;\npub mod metadata;\n#[cfg(feature = \"with-bigdecimal\")]\npub mod pi;\npub mod repository;\npub mod satellite;\npub mod schema;\npub mod sea_orm_active_enums;\npub mod self_join;\npub mod teas;\npub mod transaction_log;\npub mod uuid_fmt;\npub mod value_type;\n\npub use active_enum::Entity as ActiveEnum;\npub use active_enum_child::Entity as ActiveEnumChild;\npub use active_enum_vec::Entity as ActiveEnumVec;\npub use applog::Entity as Applog;\npub use binary::Entity as Binary;\npub use bits::Entity as Bits;\npub use byte_primary_key::Entity as BytePrimaryKey;\npub use categories::Entity as Categories;\npub use collection::Entity as Collection;\npub use collection_expanded::Entity as CollectionExpanded;\npub use dyn_table_name::Entity as DynTableName;\npub use edit_log::Entity as EditLog;\n#[cfg(feature = \"postgres-vector\")]\npub use embedding::Entity as Embedding;\npub use event_trigger::Entity as EventTrigger;\npub use insert_default::Entity as InsertDefault;\npub use json_struct::Entity as JsonStruct;\npub use json_vec::Entity as JsonVec;\npub use json_vec_derive::json_string_vec::Entity as JsonStringVec;\npub use json_vec_derive::json_struct_vec::Entity as JsonStructVec;\npub use metadata::Entity as Metadata;\npub use repository::Entity as Repository;\npub use satellite::Entity as Satellite;\npub use schema::*;\npub use sea_orm_active_enums::*;\npub use self_join::Entity as SelfJoin;\npub use teas::Entity as Teas;\npub use transaction_log::Entity as TransactionLog;\npub use uuid_fmt::Entity as UuidFmt;\n"
  },
  {
    "path": "tests/common/features/pi.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"pi\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    #[sea_orm(column_type = \"Decimal(Some((11, 10)))\")]\n    pub decimal: Decimal,\n    #[sea_orm(column_type = \"Decimal(Some((11, 10)))\")]\n    pub big_decimal: BigDecimal,\n    #[sea_orm(column_type = \"Decimal(Some((11, 10)))\")]\n    pub decimal_opt: Option<Decimal>,\n    #[sea_orm(column_type = \"Decimal(Some((11, 10)))\")]\n    pub big_decimal_opt: Option<BigDecimal>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/repository.rs",
    "content": "use super::edit_log;\nuse sea_orm::{ConnectionTrait, Set, TryIntoModel, entity::prelude::*};\nuse serde::Serialize;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize)]\n#[sea_orm(table_name = \"repository\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id: String,\n    pub owner: String,\n    pub name: String,\n    pub description: Option<String>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\n#[async_trait::async_trait]\nimpl ActiveModelBehavior for ActiveModel {\n    async fn before_save<C>(self, db: &C, _: bool) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let model = self.clone().try_into_model()?;\n        insert_edit_log(\"before_save\", &model, db).await?;\n        Ok(self)\n    }\n\n    async fn after_save<C>(model: Model, db: &C, _: bool) -> Result<Model, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        insert_edit_log(\"after_save\", &model, db).await?;\n        Ok(model)\n    }\n\n    async fn before_delete<C>(self, db: &C) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let model = self.clone().try_into_model()?;\n        insert_edit_log(\"before_delete\", &model, db).await?;\n        Ok(self)\n    }\n\n    async fn after_delete<C>(self, db: &C) -> Result<Self, DbErr>\n    where\n        C: ConnectionTrait,\n    {\n        let model = self.clone().try_into_model()?;\n        insert_edit_log(\"after_delete\", &model, db).await?;\n        Ok(self)\n    }\n}\n\nasync fn insert_edit_log<T, M, C>(action: T, model: &M, db: &C) -> Result<(), DbErr>\nwhere\n    T: Into<String>,\n    M: Serialize,\n    C: ConnectionTrait,\n{\n    edit_log::ActiveModel {\n        action: Set(action.into()),\n        values: Set(serde_json::json!(model)),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/common/features/satellite.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"satellite\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub satellite_name: String,\n    #[sea_orm(default_value = \"2022-01-26 16:24:00\")]\n    pub launch_date: DateTimeUtc,\n    #[sea_orm(default_value = \"2022-01-26 16:24:00\")]\n    pub deployment_date: DateTimeLocal,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/schema.rs",
    "content": "use super::*;\nuse crate::common::setup::{\n    create_enum, create_table, create_table_from_entity, create_table_without_asserts,\n};\nuse sea_orm::{\n    ConnectionTrait, DatabaseConnection, DbBackend, DbConn, EntityName, ExecResult, Schema,\n    error::*, sea_query,\n};\nuse sea_query::{\n    Alias, ColumnDef, ColumnType, ForeignKeyCreateStatement, IntoIden, IntoTableRef, StringLen,\n    extension::postgres::Type,\n};\n\npub async fn create_tea_enum(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let db_backend = db.get_database_backend();\n    let create_enum_stmts = match db_backend {\n        DbBackend::MySql | DbBackend::Sqlite => Vec::new(),\n        DbBackend::Postgres => {\n            let schema = Schema::new(db_backend);\n            let enum_create_stmt = Type::create()\n                .as_enum(\"tea\")\n                .values([\"EverydayTea\", \"BreakfastTea\", \"AfternoonTea\"])\n                .to_owned();\n            assert_eq!(\n                db_backend.build(&enum_create_stmt),\n                db_backend.build(&schema.create_enum_from_active_enum::<Tea>().unwrap())\n            );\n            vec![enum_create_stmt]\n        }\n        db => {\n            return Err(DbErr::BackendNotSupported {\n                db: db.as_str(),\n                ctx: \"create_tea_enum\",\n            });\n        }\n    };\n    create_enum(db, &create_enum_stmts, ActiveEnum).await?;\n    Ok(())\n}\n\npub async fn create_log_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(applog::Entity)\n        .comment(\"app logs\")\n        .col(\n            ColumnDef::new(applog::Column::Id)\n                .integer()\n                .not_null()\n                .comment(\"ID\")\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(applog::Column::Action)\n                .string()\n                .not_null()\n                .comment(\"action\"),\n        )\n        .col(\n            ColumnDef::new(applog::Column::Json)\n                .json()\n                .not_null()\n                .comment(\"action data\"),\n        )\n        .col(\n            ColumnDef::new(applog::Column::CreatedAt)\n                .timestamp_with_time_zone()\n                .not_null()\n                .comment(\"create time\"),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, Applog).await\n}\n\npub async fn create_metadata_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(metadata::Entity)\n        .col(\n            ColumnDef::new(metadata::Column::Uuid)\n                .uuid()\n                .not_null()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(metadata::Column::Type).string().not_null())\n        .col(ColumnDef::new(metadata::Column::Key).string().not_null())\n        .col(ColumnDef::new(metadata::Column::Value).string().not_null())\n        .col(\n            ColumnDef::new_with_type(\n                metadata::Column::Bytes,\n                ColumnType::VarBinary(StringLen::N(32)),\n            )\n            .not_null(),\n        )\n        .col(ColumnDef::new(metadata::Column::Date).date())\n        .col(ColumnDef::new(metadata::Column::Time).time())\n        .to_owned();\n\n    create_table(db, &stmt, Metadata).await\n}\n\npub async fn create_repository_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(repository::Entity)\n        .col(\n            ColumnDef::new(repository::Column::Id)\n                .string()\n                .not_null()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(repository::Column::Owner)\n                .string()\n                .not_null(),\n        )\n        .col(ColumnDef::new(repository::Column::Name).string().not_null())\n        .col(ColumnDef::new(repository::Column::Description).string())\n        .to_owned();\n\n    create_table(db, &stmt, Repository).await\n}\n\npub async fn create_self_join_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(self_join::Entity)\n        .col(\n            ColumnDef::new(self_join::Column::Uuid)\n                .uuid()\n                .not_null()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(self_join::Column::UuidRef).uuid())\n        .col(ColumnDef::new(self_join::Column::Time).time())\n        .foreign_key(\n            ForeignKeyCreateStatement::new()\n                .name(\"fk-self_join-uuid_ref\")\n                .from_tbl(SelfJoin)\n                .from_col(self_join::Column::UuidRef)\n                .to_tbl(SelfJoin)\n                .to_col(self_join::Column::Uuid),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, SelfJoin).await\n}\n\npub async fn create_byte_primary_key_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let mut primary_key_col = ColumnDef::new(byte_primary_key::Column::Id);\n    match db.get_database_backend() {\n        DbBackend::MySql => primary_key_col.binary_len(3),\n        DbBackend::Sqlite | DbBackend::Postgres => primary_key_col.binary(),\n        db => {\n            return Err(DbErr::BackendNotSupported {\n                db: db.as_str(),\n                ctx: \"create_byte_primary_key_table\",\n            });\n        }\n    };\n\n    let stmt = sea_query::Table::create()\n        .table(byte_primary_key::Entity)\n        .col(primary_key_col.not_null().primary_key())\n        .col(\n            ColumnDef::new(byte_primary_key::Column::Value)\n                .string()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table_without_asserts(db, &stmt).await\n}\n\npub async fn create_active_enum_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(active_enum::Entity.table_ref())\n        .col(\n            ColumnDef::new(active_enum::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(active_enum::Column::Category).string_len(1))\n        .col(ColumnDef::new(active_enum::Column::Color).integer())\n        .col(ColumnDef::new(active_enum::Column::Tea).enumeration(\n            TeaEnum,\n            [\n                TeaVariant::EverydayTea,\n                TeaVariant::BreakfastTea,\n                TeaVariant::AfternoonTea,\n            ],\n        ))\n        .to_owned();\n\n    create_table(db, &create_table_stmt, ActiveEnum).await\n}\n\npub async fn create_active_enum_child_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(active_enum_child::Entity.table_ref())\n        .col(\n            ColumnDef::new(active_enum_child::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(active_enum_child::Column::ParentId)\n                .integer()\n                .not_null(),\n        )\n        .col(ColumnDef::new(active_enum_child::Column::Category).string_len(1))\n        .col(ColumnDef::new(active_enum_child::Column::Color).integer())\n        .col(ColumnDef::new(active_enum_child::Column::Tea).enumeration(\n            TeaEnum,\n            [\n                TeaVariant::EverydayTea,\n                TeaVariant::BreakfastTea,\n                TeaVariant::AfternoonTea,\n            ],\n        ))\n        .foreign_key(\n            ForeignKeyCreateStatement::new()\n                .name(\"fk-active_enum_child-active_enum\")\n                .from_tbl(ActiveEnumChild)\n                .from_col(active_enum_child::Column::ParentId)\n                .to_tbl(if cfg!(feature = \"sqlx-postgres\") {\n                    (\"public\", ActiveEnum).into_table_ref()\n                } else {\n                    ActiveEnum.into_table_ref()\n                })\n                .to_col(active_enum::Column::Id),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, ActiveEnumChild).await\n}\n\npub async fn create_satellites_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(satellite::Entity)\n        .col(\n            ColumnDef::new(satellite::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(satellite::Column::SatelliteName)\n                .string()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(satellite::Column::LaunchDate)\n                .timestamp_with_time_zone()\n                .not_null()\n                .default(\"2022-01-26 16:24:00\"),\n        )\n        .col(\n            ColumnDef::new(satellite::Column::DeploymentDate)\n                .timestamp_with_time_zone()\n                .not_null()\n                .default(\"2022-01-26 16:24:00\"),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, Satellite).await\n}\n\npub async fn create_transaction_log_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(transaction_log::Entity)\n        .col(\n            ColumnDef::new(transaction_log::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(transaction_log::Column::Date)\n                .date()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(transaction_log::Column::Time)\n                .time()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(transaction_log::Column::DateTime)\n                .date_time()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(transaction_log::Column::DateTimeTz)\n                .timestamp_with_time_zone()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, TransactionLog).await\n}\n\npub async fn create_insert_default_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(insert_default::Entity.table_ref())\n        .col(\n            ColumnDef::new(insert_default::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, InsertDefault).await\n}\n\npub async fn create_json_vec_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(json_vec::Entity.table_ref())\n        .col(\n            ColumnDef::new(json_vec::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(json_vec::Column::StrVec).json())\n        .to_owned();\n\n    create_table(db, &create_table_stmt, JsonVec).await\n}\n\npub async fn create_json_struct_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(json_struct::Entity)\n        .col(\n            ColumnDef::new(json_struct::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(json_struct::Column::Json).json().not_null())\n        .col(\n            ColumnDef::new(json_struct::Column::JsonValue)\n                .json()\n                .not_null(),\n        )\n        .col(ColumnDef::new(json_struct::Column::JsonValueOpt).json())\n        .col(ColumnDef::new(json_struct::Column::JsonNonSerializable).json())\n        .to_owned();\n\n    create_table(db, &stmt, JsonStruct).await\n}\n\npub async fn create_json_string_vec_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(JsonStringVec.table_ref())\n        .col(\n            ColumnDef::new(json_vec_derive::json_string_vec::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(json_vec_derive::json_string_vec::Column::StrVec).json())\n        .to_owned();\n\n    create_table(db, &create_table_stmt, JsonStringVec).await\n}\n\npub async fn create_json_struct_vec_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(JsonStructVec.table_ref())\n        .col(\n            ColumnDef::new(json_vec_derive::json_struct_vec::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(json_vec_derive::json_struct_vec::Column::StructVec)\n                .json_binary()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, JsonStructVec).await\n}\n\npub async fn create_collection_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    db.execute_raw(sea_orm::Statement::from_string(\n        db.get_database_backend(),\n        \"CREATE EXTENSION IF NOT EXISTS citext\",\n    ))\n    .await?;\n\n    let stmt = sea_query::Table::create()\n        .table(collection::Entity)\n        .col(\n            ColumnDef::new(collection::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(collection::Column::Name)\n                .custom(\"citext\")\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(collection::Column::Integers)\n                .array(sea_query::ColumnType::Integer)\n                .not_null(),\n        )\n        .col(ColumnDef::new(collection::Column::IntegersOpt).array(sea_query::ColumnType::Integer))\n        .col(\n            ColumnDef::new(collection::Column::Teas)\n                .array(sea_query::ColumnType::Enum {\n                    name: TeaEnum.into_iden(),\n                    variants: vec![\n                        TeaVariant::EverydayTea.into_iden(),\n                        TeaVariant::BreakfastTea.into_iden(),\n                        TeaVariant::AfternoonTea.into_iden(),\n                    ],\n                })\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(collection::Column::TeasOpt).array(sea_query::ColumnType::Enum {\n                name: TeaEnum.into_iden(),\n                variants: vec![\n                    TeaVariant::EverydayTea.into_iden(),\n                    TeaVariant::BreakfastTea.into_iden(),\n                    TeaVariant::AfternoonTea.into_iden(),\n                ],\n            }),\n        )\n        .col(\n            ColumnDef::new(collection::Column::Colors)\n                .array(sea_query::ColumnType::Integer)\n                .not_null(),\n        )\n        .col(ColumnDef::new(collection::Column::ColorsOpt).array(sea_query::ColumnType::Integer))\n        .col(\n            ColumnDef::new(collection::Column::Uuid)\n                .array(sea_query::ColumnType::Uuid)\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(collection::Column::UuidHyphenated)\n                .array(sea_query::ColumnType::Uuid)\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, Collection).await\n}\n\n#[cfg(feature = \"with-ipnetwork\")]\npub async fn create_host_network_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(host_network::Entity)\n        .col(\n            ColumnDef::new(host_network::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(host_network::Column::Hostname)\n                .string()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(host_network::Column::Ipaddress)\n                .inet()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(host_network::Column::Network)\n                .cidr()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, host_network::Entity).await\n}\n\n#[cfg(feature = \"with-bigdecimal\")]\npub async fn create_pi_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(pi::Entity)\n        .col(\n            ColumnDef::new(pi::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(pi::Column::Decimal)\n                .decimal_len(11, 10)\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(pi::Column::BigDecimal)\n                .decimal_len(11, 10)\n                .not_null(),\n        )\n        .col(ColumnDef::new(pi::Column::DecimalOpt).decimal_len(11, 10))\n        .col(ColumnDef::new(pi::Column::BigDecimalOpt).decimal_len(11, 10))\n        .to_owned();\n\n    create_table(db, &stmt, pi::Entity).await\n}\n\npub async fn create_event_trigger_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(event_trigger::Entity)\n        .col(\n            ColumnDef::new(event_trigger::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(event_trigger::Column::Events)\n                .array(sea_query::ColumnType::String(StringLen::None))\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, EventTrigger).await\n}\n\npub async fn create_uuid_fmt_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(uuid_fmt::Entity)\n        .col(\n            ColumnDef::new(uuid_fmt::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(uuid_fmt::Column::Uuid).uuid().not_null())\n        .col(\n            ColumnDef::new(uuid_fmt::Column::UuidBraced)\n                .uuid()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(uuid_fmt::Column::UuidHyphenated)\n                .uuid()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(uuid_fmt::Column::UuidSimple)\n                .uuid()\n                .not_null(),\n        )\n        .col(ColumnDef::new(uuid_fmt::Column::UuidUrn).uuid().not_null())\n        .to_owned();\n\n    create_table(db, &stmt, UuidFmt).await\n}\n\npub async fn create_edit_log_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = sea_query::Table::create()\n        .table(edit_log::Entity)\n        .col(\n            ColumnDef::new(edit_log::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(edit_log::Column::Action).string().not_null())\n        .col(ColumnDef::new(edit_log::Column::Values).json().not_null())\n        .to_owned();\n\n    create_table(db, &stmt, EditLog).await\n}\n\npub async fn create_teas_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(teas::Entity.table_ref())\n        .col(\n            ColumnDef::new(teas::Column::Id)\n                .enumeration(\n                    TeaEnum,\n                    [\n                        TeaVariant::EverydayTea,\n                        TeaVariant::BreakfastTea,\n                        TeaVariant::AfternoonTea,\n                    ],\n                )\n                .not_null()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(teas::Column::Category).string_len(1))\n        .col(ColumnDef::new(teas::Column::Color).integer())\n        .to_owned();\n\n    create_table(db, &create_table_stmt, Teas).await\n}\n\npub async fn create_categories_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(categories::Entity.table_ref())\n        .col(\n            ColumnDef::new(categories::Column::Id)\n                .integer()\n                .not_null()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(categories::Column::Categories)\n                .array(ColumnType::String(StringLen::N(1))),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, Categories).await\n}\n\n#[cfg(feature = \"postgres-vector\")]\npub async fn create_embedding_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    db.execute(sea_orm::Statement::from_string(\n        db.get_database_backend(),\n        \"CREATE EXTENSION IF NOT EXISTS vector\",\n    ))\n    .await?;\n\n    let create_table_stmt = sea_query::Table::create()\n        .table(embedding::Entity.table_ref())\n        .col(\n            ColumnDef::new(embedding::Column::Id)\n                .integer()\n                .not_null()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(embedding::Column::Embedding)\n                .vector(None)\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, Embedding).await\n}\n\npub async fn create_binary_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(binary::Entity.table_ref())\n        .col(\n            ColumnDef::new(binary::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(binary::Column::Binary).binary().not_null())\n        .col(\n            ColumnDef::new(binary::Column::Binary10)\n                .binary_len(10)\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(binary::Column::VarBinary16)\n                .var_binary(16)\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, Binary).await\n}\n\npub async fn create_bits_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let create_table_stmt = sea_query::Table::create()\n        .table(bits::Entity.table_ref())\n        .col(\n            ColumnDef::new(bits::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(bits::Column::Bit0).custom(\"BIT\").not_null())\n        .col(\n            ColumnDef::new(bits::Column::Bit1)\n                .custom(\"BIT(1)\")\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(bits::Column::Bit8)\n                .custom(\"BIT(8)\")\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(bits::Column::Bit16)\n                .custom(\"BIT(16)\")\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(bits::Column::Bit32)\n                .custom(\"BIT(32)\")\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(bits::Column::Bit64)\n                .custom(\"BIT(64)\")\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &create_table_stmt, Bits).await\n}\n\npub async fn create_dyn_table_name_lazy_static_table(db: &DbConn) -> Result<(), DbErr> {\n    use dyn_table_name::*;\n\n    let entities = [Entity { table_name: 1 }, Entity { table_name: 2 }];\n    for entity in entities {\n        let create_table_stmt = sea_query::Table::create()\n            .table(entity.table_ref())\n            .col(\n                ColumnDef::new(Column::Id)\n                    .integer()\n                    .not_null()\n                    .auto_increment()\n                    .primary_key(),\n            )\n            .col(ColumnDef::new(Column::Name).string().not_null())\n            .to_owned();\n\n        create_table(db, &create_table_stmt, entity).await?;\n    }\n\n    Ok(())\n}\n\npub async fn create_value_type_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let general_stmt = sea_query::Table::create()\n        .table(value_type::value_type_general::Entity)\n        .col(\n            ColumnDef::new(value_type::value_type_general::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(value_type::value_type_general::Column::Number)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(value_type::value_type_general::Column::Tag1)\n                .string()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(value_type::value_type_general::Column::Tag2)\n                .text()\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &general_stmt, value_type::value_type_general::Entity).await?;\n    create_table_from_entity(db, value_type::value_type_pk::Entity).await\n}\n\npub async fn create_value_type_postgres_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let postgres_stmt = sea_query::Table::create()\n        .table(value_type::value_type_pg::Entity)\n        .col(\n            ColumnDef::new(value_type::value_type_pg::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(\n            ColumnDef::new(value_type::value_type_pg::Column::Number)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(value_type::value_type_pg::Column::StrVec)\n                .array(sea_query::ColumnType::String(StringLen::None))\n                .not_null(),\n        )\n        .to_owned();\n\n    create_table(db, &postgres_stmt, value_type::value_type_pg::Entity).await\n}\n"
  },
  {
    "path": "tests/common/features/sea_orm_active_enums.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"String\", db_type = \"String(StringLen::N(1))\")]\npub enum Category {\n    #[sea_orm(string_value = \"B\")]\n    Big,\n    #[sea_orm(string_value = \"S\")]\n    Small,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum)]\n#[sea_orm(rs_type = \"i32\", db_type = \"Integer\")]\npub enum Color {\n    #[sea_orm(num_value = 0)]\n    Black,\n    #[sea_orm(num_value = 1)]\n    White,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n#[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"tea\")]\npub enum Tea {\n    #[sea_orm(string_value = \"EverydayTea\")]\n    EverydayTea,\n    #[sea_orm(string_value = \"BreakfastTea\")]\n    BreakfastTea,\n    #[sea_orm(string_value = \"AfternoonTea\")]\n    AfternoonTea,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Copy)]\n#[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"media_type\")]\npub enum MediaType {\n    #[sea_orm(string_value = \"UNKNOWN\")]\n    Unknown,\n    #[sea_orm(string_value = \"BITMAP\")]\n    Bitmap,\n    #[sea_orm(string_value = \"DRAWING\")]\n    Drawing,\n    #[sea_orm(string_value = \"AUDIO\")]\n    Audio,\n    #[sea_orm(string_value = \"VIDEO\")]\n    Video,\n    #[sea_orm(string_value = \"MULTIMEDIA\")]\n    Multimedia,\n    #[sea_orm(string_value = \"OFFICE\")]\n    Office,\n    #[sea_orm(string_value = \"TEXT\")]\n    Text,\n    #[sea_orm(string_value = \"EXECUTABLE\")]\n    Executable,\n    #[sea_orm(string_value = \"ARCHIVE\")]\n    Archive,\n    #[sea_orm(string_value = \"3D\")]\n    _3D,\n}\n\n#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, DeriveDisplay)]\n#[sea_orm(rs_type = \"String\", db_type = \"Enum\", enum_name = \"tea\")]\npub enum DisplayTea {\n    #[sea_orm(string_value = \"EverydayTea\", display_value = \"Everyday\")]\n    EverydayTea,\n    #[sea_orm(string_value = \"BreakfastTea\", display_value = \"Breakfast\")]\n    BreakfastTea,\n}\n"
  },
  {
    "path": "tests/common/features/self_join.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"self_join\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub uuid: Uuid,\n    pub uuid_ref: Option<Uuid>,\n    pub time: Option<Time>,\n    #[sea_orm(self_ref, relation_enum = \"SelfRef\", from = \"uuid_ref\", to = \"uuid\")]\n    pub other: HasOne<Entity>,\n}\n\npub struct SelfReferencingLink;\n\nimpl Linked for SelfReferencingLink {\n    type FromEntity = Entity;\n\n    type ToEntity = Entity;\n\n    fn link(&self) -> Vec<RelationDef> {\n        vec![Relation::SelfRef.def()]\n    }\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/teas.rs",
    "content": "use super::sea_orm_active_enums::*;\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"teas\")]\npub struct Model {\n    #[sea_orm(primary_key, auto_increment = false)]\n    pub id: Tea,\n    pub category: Option<Category>,\n    pub color: Option<Color>,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/transaction_log.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"transaction_log\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub date: TimeDate,\n    pub time: TimeTime,\n    pub date_time: TimeDateTime,\n    pub date_time_tz: TimeDateTimeWithTimeZone,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/uuid_fmt.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"uuid_fmt\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub uuid: Uuid,\n    pub uuid_braced: uuid::fmt::Braced,\n    pub uuid_hyphenated: uuid::fmt::Hyphenated,\n    pub uuid_simple: uuid::fmt::Simple,\n    pub uuid_urn: uuid::fmt::Urn,\n}\n\n#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\npub enum Relation {}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/common/features/value_type.rs",
    "content": "pub mod value_type_general {\n    use super::*;\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"value_type\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub number: MyInteger,\n        pub tag_1: Tag1,\n        pub tag_2: Tag2,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod value_type_pg {\n    use super::*;\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"value_type_postgres\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub number: MyInteger,\n        pub str_vec: StringVec,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod value_type_pk {\n    use super::*;\n    use sea_orm::entity::prelude::*;\n\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"value_type_pk\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: MyInteger,\n        pub val: MyInteger,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nuse sea_orm::entity::prelude::*;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveValueType)]\npub struct MyInteger(pub i32);\n\nimpl<T> From<T> for MyInteger\nwhere\n    T: Into<i32>,\n{\n    fn from(v: T) -> MyInteger {\n        MyInteger(v.into())\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveValueType)]\npub struct StringVec(pub Vec<String>);\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(value_type = \"String\")]\npub enum Tag1 {\n    Hard,\n    Soft,\n}\n\nimpl std::fmt::Display for Tag1 {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(\n            f,\n            \"{}\",\n            match self {\n                Self::Hard => \"hard\",\n                Self::Soft => \"soft\",\n            }\n        )\n    }\n}\n\nimpl std::str::FromStr for Tag1 {\n    type Err = sea_query::ValueTypeErr;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        Ok(match s {\n            \"hard\" => Self::Hard,\n            \"soft\" => Self::Soft,\n            _ => return Err(sea_query::ValueTypeErr),\n        })\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(\n    value_type = \"String\",\n    from_str = \"Tag2::from_str\",\n    to_str = \"Tag2::to_str\",\n    column_type = \"Text\"\n)]\npub enum Tag2 {\n    Color,\n    Grey,\n}\n\nimpl Tag2 {\n    fn to_str(&self) -> &'static str {\n        match self {\n            Self::Color => \"color\",\n            Self::Grey => \"grey\",\n        }\n    }\n\n    fn from_str(s: &str) -> Result<Self, sea_query::ValueTypeErr> {\n        Ok(match s {\n            \"color\" => Self::Color,\n            \"grey\" => Self::Grey,\n            _ => return Err(sea_query::ValueTypeErr),\n        })\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(value_type = \"String\")]\npub struct Tag3 {\n    pub i: i64,\n}\n\nimpl std::fmt::Display for Tag3 {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", self.i)\n    }\n}\n\nimpl std::str::FromStr for Tag3 {\n    type Err = std::num::ParseIntError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        let i: i64 = s.parse()?;\n        Ok(Self { i })\n    }\n}\n\n#[derive(Copy, Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(value_type = \"String\")]\npub struct Tag4(pub i64);\n\nimpl std::fmt::Display for Tag4 {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", self.0)\n    }\n}\n\nimpl std::str::FromStr for Tag4 {\n    type Err = std::num::ParseIntError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        let i: i64 = s.parse()?;\n        Ok(Self(i))\n    }\n}\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(value_type = \"String\")]\n// Test with inner type that doesn't implement ToString/FromStr\npub struct Tag5(pub std::path::PathBuf);\n\nimpl std::fmt::Display for Tag5 {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"{}\", self.0.display())\n    }\n}\n\nimpl std::str::FromStr for Tag5 {\n    type Err = std::num::ParseIntError;\n\n    fn from_str(s: &str) -> Result<Self, Self::Err> {\n        Ok(Self(std::path::PathBuf::from(s)))\n    }\n}\n\n// Test for try_from_u64 attribute with type alias\ntype UserId = i32;\n\n#[derive(Clone, Debug, PartialEq, Eq, DeriveValueType)]\n#[sea_orm(try_from_u64)]\npub struct MyUserId(pub UserId);\n"
  },
  {
    "path": "tests/common/film_store.rs",
    "content": "pub mod film {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"film\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub title: String,\n        #[sea_orm(has_many, via = \"film_actor\")]\n        pub actors: HasMany<super::actor::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod actor {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"actor\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub name: String,\n        #[sea_orm(has_many, via = \"film_actor\")]\n        pub films: HasMany<super::film::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod film_actor {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"film_actor\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique_key = \"film_actor\")]\n        pub film_id: i32,\n        #[sea_orm(unique_key = \"film_actor\")]\n        pub actor_id: i32,\n        #[sea_orm(belongs_to, from = \"film_id\", to = \"id\")]\n        pub film: HasOne<super::film::Entity>,\n        #[sea_orm(belongs_to, from = \"actor_id\", to = \"id\")]\n        pub actor: HasOne<super::actor::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod staff {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"staff\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n        pub reports_to_id: Option<i32>,\n        #[sea_orm(\n            self_ref,\n            relation_enum = \"ReportsTo\",\n            relation_reverse = \"Manages\",\n            from = \"reports_to_id\",\n            to = \"id\"\n        )]\n        pub reports_to: HasOne<Entity>,\n        #[sea_orm(self_ref, relation_enum = \"Manages\", relation_reverse = \"ReportsTo\")]\n        pub manages: HasMany<Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod staff_mono {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"staff\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n        pub reports_to_id: Option<i32>,\n        #[sea_orm(\n            self_ref,\n            relation_enum = \"ReportsTo\",\n            from = \"reports_to_id\",\n            to = \"id\"\n        )]\n        pub reports_to: HasOne<Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub mod staff_compact {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::compact_model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"staff\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub name: String,\n        pub reports_to_id: Option<i32>,\n        #[sea_orm(self_ref, relation_enum = \"ReportsTo\")]\n        pub reports_to: HasOne<Entity>,\n        #[sea_orm(self_ref, relation_enum = \"Manages\")]\n        pub manages: HasMany<Entity>,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {\n        #[sea_orm(belongs_to = \"Entity\", from = \"Column::ReportsToId\", to = \"Column::Id\")]\n        ReportsTo,\n        #[sea_orm(has_many = \"Entity\", via_rel = \"Relation::ReportsTo\")]\n        Manages,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n"
  },
  {
    "path": "tests/common/mod.rs",
    "content": "pub mod bakery_chain;\npub mod bakery_dense;\npub mod blogger;\npub mod features;\npub mod film_store;\n#[cfg(not(feature = \"sync\"))]\npub mod runtime;\npub mod setup;\n\nuse sea_orm::DatabaseConnection;\n\npub struct TestContext {\n    base_url: String,\n    db_name: String,\n    pub db: DatabaseConnection,\n}\n\nimpl TestContext {\n    pub async fn new(test_name: &str) -> Self {\n        dotenv::from_filename(\".env.local\").ok();\n        dotenv::from_filename(\".env\").ok();\n\n        let base_url =\n            std::env::var(\"DATABASE_URL\").expect(\"Environment variable 'DATABASE_URL' not set\");\n        let db: DatabaseConnection = setup::setup(&base_url, test_name).await;\n\n        Self {\n            base_url,\n            db_name: test_name.to_string(),\n            db,\n        }\n    }\n\n    pub async fn delete(&self) {\n        setup::tear_down(&self.base_url, &self.db_name).await;\n    }\n}\n"
  },
  {
    "path": "tests/common/runtime.rs",
    "content": "#[cfg(feature = \"runtime-async-std\")]\n#[macro_export]\nmacro_rules! block_on {\n    ($($expr:tt)*) => {\n        ::async_std::task::block_on( $($expr)* )\n    };\n}\n\n#[cfg(feature = \"runtime-tokio\")]\n#[macro_export]\nmacro_rules! block_on {\n    ($($expr:tt)*) => {\n        ::tokio::runtime::Runtime::new()\n            .unwrap()\n            .block_on( $($expr)* )\n    };\n}\n"
  },
  {
    "path": "tests/common/sakila/NOTES.md",
    "content": "To re-generate diagram, run at project root:\n```sh\nDATABASE_URL=\"postgres://sea:sea@localhost/sakila\" cargo run --manifest-path sea-orm-cli/Cargo.toml -- generate entity -o tests/common/sakila --entity-format dense --er-diagram\n```"
  },
  {
    "path": "tests/common/sakila/entities.mermaid",
    "content": "erDiagram\n    actor {\n        int actor_id PK\n        varchar first_name\n        varchar last_name\n        datetime last_update\n    }\n    address {\n        int address_id PK\n        varchar address\n        varchar address2\n        varchar district\n        int city_id FK\n        varchar postal_code\n        varchar phone\n        datetime last_update\n    }\n    category {\n        int category_id PK\n        varchar name\n        datetime last_update\n    }\n    city {\n        int city_id PK\n        varchar city\n        int country_id FK\n        datetime last_update\n    }\n    country {\n        int country_id PK\n        varchar country\n        datetime last_update\n    }\n    customer {\n        int customer_id PK\n        int store_id FK\n        varchar first_name\n        varchar last_name\n        varchar email\n        int address_id FK\n        bool activebool\n        date create_date\n        datetime last_update\n        int active\n    }\n    film {\n        int film_id PK\n        varchar title\n        text description\n        int release_year\n        int language_id FK\n        int original_language_id FK\n        int rental_duration\n        decimal rental_rate\n        int length\n        decimal replacement_cost\n        enum rating\n        datetime last_update\n        array special_features\n        custom fulltext\n        json metadata\n    }\n    film_actor {\n        int actor_id PK,FK\n        int film_id PK,FK\n        datetime last_update\n    }\n    film_category {\n        int film_id PK,FK\n        int category_id PK,FK\n        datetime last_update\n    }\n    inventory {\n        int inventory_id PK\n        int film_id FK\n        int store_id FK\n        datetime last_update\n    }\n    language {\n        int language_id PK\n        char name\n        datetime last_update\n    }\n    payment {\n        int payment_id PK\n        int customer_id FK\n        int staff_id FK\n        int rental_id FK\n        decimal amount\n        datetime payment_date\n    }\n    rental {\n        int rental_id PK\n        datetime rental_date UK\n        int inventory_id FK,UK\n        int customer_id FK,UK\n        datetime return_date\n        int staff_id FK\n        datetime last_update\n    }\n    staff {\n        int staff_id PK\n        varchar first_name\n        varchar last_name\n        int address_id FK\n        int reports_to_id FK\n        varchar email\n        int store_id FK\n        bool active\n        varchar username\n        varchar password\n        datetime last_update\n        blob picture\n    }\n    store {\n        int store_id PK\n        int manager_staff_id FK,UK\n        int address_id FK\n        datetime last_update\n    }\n    actor }o--o{ film : \"[film_actor]\"\n    address }o--|| city : \"city_id\"\n    category }o--o{ film : \"[film_category]\"\n    city }o--|| country : \"country_id\"\n    customer }o--|| address : \"address_id\"\n    customer }o--|| store : \"store_id\"\n    film }o--|| language : \"language_id\"\n    film }o--|| language : \"original_language_id\"\n    film_actor }o--|| actor : \"actor_id\"\n    film_actor }o--|| film : \"film_id\"\n    film_category }o--|| category : \"category_id\"\n    film_category }o--|| film : \"film_id\"\n    inventory }o--|| film : \"film_id\"\n    inventory }o--|| store : \"store_id\"\n    payment }o--|| customer : \"customer_id\"\n    payment }o--|| rental : \"rental_id\"\n    payment }o--|| staff : \"staff_id\"\n    rental }o--|| customer : \"customer_id\"\n    rental }o--|| inventory : \"inventory_id\"\n    rental }o--|| staff : \"staff_id\"\n    staff }o--|| address : \"address_id\"\n    staff }o--|| staff : \"reports_to_id\"\n    staff }o--|| store : \"store_id\"\n    store }o--|| address : \"address_id\"\n    store }o--|| staff : \"manager_staff_id\"\n"
  },
  {
    "path": "tests/common/setup/mod.rs",
    "content": "use pretty_assertions::assert_eq;\nuse sea_orm::{\n    ColumnTrait, ColumnType, ConnectOptions, ConnectionTrait, Database, DatabaseBackend,\n    DatabaseConnection, DbBackend, DbConn, DbErr, EntityTrait, ExecResult, Iterable, Schema,\n    Statement,\n};\nuse sea_query::{\n    SeaRc, Table, TableCreateStatement,\n    extension::postgres::{Type, TypeCreateStatement},\n};\n\npub async fn setup(base_url: &str, db_name: &str) -> DatabaseConnection {\n    if cfg!(feature = \"sqlx-mysql\") {\n        let url = format!(\"{base_url}/mysql\");\n        let db = Database::connect(&url).await.unwrap();\n        let _drop_db_result = db\n            .execute_raw(Statement::from_string(\n                DatabaseBackend::MySql,\n                format!(\"DROP DATABASE IF EXISTS `{db_name}`;\"),\n            ))\n            .await;\n\n        let _create_db_result = db\n            .execute_raw(Statement::from_string(\n                DatabaseBackend::MySql,\n                format!(\"CREATE DATABASE `{db_name}`;\"),\n            ))\n            .await;\n\n        let url = format!(\"{base_url}/{db_name}\");\n        let mut options: ConnectOptions = url.into();\n        options.sqlx_logging(false);\n        Database::connect(options).await.unwrap()\n    } else if cfg!(feature = \"sqlx-postgres\") {\n        let url = format!(\"{base_url}/postgres\");\n        let db = Database::connect(&url).await.unwrap();\n        let _drop_db_result = db\n            .execute_raw(Statement::from_string(\n                DatabaseBackend::Postgres,\n                format!(\"DROP DATABASE IF EXISTS \\\"{db_name}\\\";\"),\n            ))\n            .await;\n\n        let _create_db_result = db\n            .execute_raw(Statement::from_string(\n                DatabaseBackend::Postgres,\n                format!(\"CREATE DATABASE \\\"{db_name}\\\";\"),\n            ))\n            .await;\n\n        let url = format!(\"{base_url}/{db_name}\");\n        let mut options: ConnectOptions = url.into();\n        options.sqlx_logging(false);\n        Database::connect(options).await.unwrap()\n    } else {\n        let mut options: ConnectOptions = base_url.into();\n        options.sqlx_logging(false);\n        Database::connect(options).await.unwrap()\n    }\n}\n\npub async fn tear_down(base_url: &str, db_name: &str) {\n    if cfg!(feature = \"sqlx-mysql\") {\n        let url = format!(\"{base_url}/mysql\");\n        let db = Database::connect(&url).await.unwrap();\n        let _ = db\n            .execute_raw(Statement::from_string(\n                DatabaseBackend::MySql,\n                format!(\"DROP DATABASE IF EXISTS \\\"{db_name}\\\";\"),\n            ))\n            .await;\n    } else if cfg!(feature = \"sqlx-postgres\") {\n        let url = format!(\"{base_url}/postgres\");\n        let db = Database::connect(&url).await.unwrap();\n        let _ = db\n            .execute_raw(Statement::from_string(\n                DatabaseBackend::Postgres,\n                format!(\"DROP DATABASE IF EXISTS \\\"{db_name}\\\";\"),\n            ))\n            .await;\n    };\n}\n\npub async fn create_enum<E>(\n    db: &DbConn,\n    creates: &[TypeCreateStatement],\n    entity: E,\n) -> Result<(), DbErr>\nwhere\n    E: EntityTrait,\n{\n    let builder = db.get_database_backend();\n    if builder == DbBackend::Postgres {\n        for col in E::Column::iter() {\n            let col_def = col.def();\n            let col_type = col_def.get_column_type();\n            if !matches!(col_type, ColumnType::Enum { .. }) {\n                continue;\n            }\n            let name = match col_type {\n                ColumnType::Enum { name, .. } => name,\n                _ => unreachable!(),\n            };\n            db.execute(Type::drop().name(name.clone()).if_exists().cascade())\n                .await?;\n        }\n    }\n\n    let expect_stmts: Vec<Statement> = creates.iter().map(|stmt| builder.build(stmt)).collect();\n    let schema = Schema::new(builder);\n    let create_from_entity_stmts: Vec<Statement> = schema\n        .create_enum_from_entity(entity)\n        .iter()\n        .map(|stmt| builder.build(stmt))\n        .collect();\n\n    assert_eq!(expect_stmts, create_from_entity_stmts);\n\n    for stmt in creates.iter() {\n        db.execute(stmt).await?;\n    }\n\n    Ok(())\n}\n\npub async fn create_table<E>(\n    db: &DbConn,\n    create: &TableCreateStatement,\n    entity: E,\n) -> Result<ExecResult, DbErr>\nwhere\n    E: EntityTrait,\n{\n    let builder = db.get_database_backend();\n    let schema = Schema::new(builder);\n    assert_eq!(\n        builder.build(&schema.create_table_from_entity(entity)),\n        builder.build(create)\n    );\n\n    create_table_without_asserts(db, create).await\n}\n\npub async fn create_table_with_index<E>(\n    db: &DbConn,\n    create: &TableCreateStatement,\n    entity: E,\n) -> Result<ExecResult, DbErr>\nwhere\n    E: EntityTrait,\n{\n    let res = create_table(db, create, entity).await?;\n    let backend = db.get_database_backend();\n    for stmt in Schema::new(backend).create_index_from_entity(entity) {\n        db.execute(&stmt).await?;\n    }\n    Ok(res)\n}\n\npub async fn create_table_from_entity<E>(db: &DbConn, entity: E) -> Result<ExecResult, DbErr>\nwhere\n    E: EntityTrait,\n{\n    let builder = db.get_database_backend();\n    let schema = Schema::new(builder);\n    let stmt = schema.create_table_from_entity(entity);\n\n    db.execute(&stmt).await\n}\n\npub async fn create_table_without_asserts(\n    db: &DbConn,\n    create: &TableCreateStatement,\n) -> Result<ExecResult, DbErr> {\n    let builder = db.get_database_backend();\n    if builder != DbBackend::Sqlite {\n        let stmt = Table::drop()\n            .table(create.get_table_name().unwrap().clone())\n            .if_exists()\n            .cascade()\n            .take();\n        db.execute(&stmt).await?;\n    }\n    db.execute(create).await\n}\n\npub fn rust_dec<T: ToString>(v: T) -> rust_decimal::Decimal {\n    use std::str::FromStr;\n    rust_decimal::Decimal::from_str(&v.to_string()).unwrap()\n}\n"
  },
  {
    "path": "tests/connection_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::prelude::*;\n\n#[sea_orm_macros::test]\npub async fn connection_ping() {\n    let ctx = TestContext::new(\"connection_ping\").await;\n\n    ctx.db.ping().await.unwrap();\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-mysql\")]\npub async fn connection_ping_closed_mysql() {\n    let ctx = std::rc::Rc::new(Box::new(TestContext::new(\"connection_ping_closed\").await));\n    let ctx_ping = std::rc::Rc::clone(&ctx);\n\n    ctx.db.get_mysql_connection_pool().close().await;\n    assert_eq!(\n        ctx_ping.db.ping().await,\n        Err(DbErr::ConnectionAcquire(ConnAcquireErr::ConnectionClosed))\n    );\n\n    let base_url = std::env::var(\"DATABASE_URL\").unwrap();\n    let mut opt = sea_orm::ConnectOptions::new(format!(\"{base_url}/connection_ping_closed\"));\n    opt\n        // The connection pool has a single connection only\n        .max_connections(1)\n        // A controlled connection acquire timeout\n        .acquire_timeout(std::time::Duration::from_secs(2));\n\n    let db = sea_orm::Database::connect(opt).await.unwrap();\n\n    async fn transaction_blocked(db: &DatabaseConnection) {\n        let _txn = sea_orm::TransactionTrait::begin(db).await.unwrap();\n        // Occupy the only connection, thus forcing others fail to acquire connection\n        tokio::time::sleep(std::time::Duration::from_secs(3)).await;\n    }\n\n    async fn transaction(db: &DatabaseConnection) {\n        // Should fail to acquire\n        let txn = sea_orm::TransactionTrait::begin(db).await;\n        assert_eq!(\n            txn.expect_err(\"should be a time out\"),\n            crate::DbErr::ConnectionAcquire(ConnAcquireErr::Timeout)\n        )\n    }\n\n    tokio::join!(transaction_blocked(&db), transaction(&db));\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\n#[cfg(all(feature = \"sqlx-sqlite\", not(feature = \"sync\")))]\npub async fn connection_ping_closed_sqlite() {\n    let ctx = std::rc::Rc::new(Box::new(TestContext::new(\"connection_ping_closed\").await));\n    let ctx_ping = std::rc::Rc::clone(&ctx);\n\n    ctx.db.get_sqlite_connection_pool().close().await;\n    assert_eq!(\n        ctx_ping.db.ping().await,\n        Err(DbErr::ConnectionAcquire(ConnAcquireErr::ConnectionClosed))\n    );\n\n    let base_url = std::env::var(\"DATABASE_URL\").unwrap();\n    let mut opt = sea_orm::ConnectOptions::new(base_url);\n    opt\n        // The connection pool has a single connection only\n        .max_connections(1)\n        // A controlled connection acquire timeout\n        .acquire_timeout(std::time::Duration::from_secs(2));\n\n    let db = sea_orm::Database::connect(opt).await.unwrap();\n\n    async fn transaction_blocked(db: &DatabaseConnection) {\n        let _txn = sea_orm::TransactionTrait::begin(db).await.unwrap();\n        // Occupy the only connection, thus forcing others fail to acquire connection\n        tokio::time::sleep(std::time::Duration::from_secs(3)).await;\n    }\n\n    async fn transaction(db: &DatabaseConnection) {\n        // Should fail to acquire\n        let txn = sea_orm::TransactionTrait::begin(db).await;\n        assert_eq!(\n            txn.expect_err(\"should be a time out\"),\n            crate::DbErr::ConnectionAcquire(ConnAcquireErr::Timeout)\n        )\n    }\n\n    tokio::join!(transaction_blocked(&db), transaction(&db));\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-postgres\")]\npub async fn connection_ping_closed_postgres() {\n    let ctx = std::rc::Rc::new(Box::new(TestContext::new(\"connection_ping_closed\").await));\n    let ctx_ping = std::rc::Rc::clone(&ctx);\n\n    ctx.db.get_postgres_connection_pool().close().await;\n    assert_eq!(\n        ctx_ping.db.ping().await,\n        Err(DbErr::ConnectionAcquire(ConnAcquireErr::ConnectionClosed))\n    );\n\n    let base_url = std::env::var(\"DATABASE_URL\").unwrap();\n    let mut opt = sea_orm::ConnectOptions::new(format!(\"{base_url}/connection_ping_closed\"));\n    opt\n        // The connection pool has a single connection only\n        .max_connections(1)\n        // A controlled connection acquire timeout\n        .acquire_timeout(std::time::Duration::from_secs(2));\n\n    let db = sea_orm::Database::connect(opt).await.unwrap();\n\n    async fn transaction_blocked(db: &DatabaseConnection) {\n        let _txn = sea_orm::TransactionTrait::begin(db).await.unwrap();\n        // Occupy the only connection, thus forcing others fail to acquire connection\n        tokio::time::sleep(std::time::Duration::from_secs(3)).await;\n    }\n\n    async fn transaction(db: &DatabaseConnection) {\n        // Should fail to acquire\n        let txn = sea_orm::TransactionTrait::begin(db).await;\n        assert_eq!(\n            txn.expect_err(\"should be a time out\"),\n            crate::DbErr::ConnectionAcquire(ConnAcquireErr::Timeout)\n        )\n    }\n\n    tokio::join!(transaction_blocked(&db), transaction(&db));\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-postgres\")]\npub async fn connection_with_search_path_postgres() {\n    let ctx = TestContext::new(\"connection_with_search_path\").await;\n\n    let base_url = std::env::var(\"DATABASE_URL\").unwrap();\n    let mut opt = sea_orm::ConnectOptions::new(format!(\"{base_url}/connection_with_search_path\"));\n    opt\n        // The connection pool has a single connection only\n        .max_connections(1)\n        // A controlled connection acquire timeout\n        .acquire_timeout(std::time::Duration::from_secs(2))\n        .set_schema_search_path(\"schema-with-special-characters\");\n\n    let db = sea_orm::Database::connect(opt).await;\n    assert!(db.is_ok());\n\n    ctx.delete().await;\n}\n"
  },
  {
    "path": "tests/crud/create_baker.rs",
    "content": "pub use super::*;\nuse serde::{Deserialize, Serialize};\n\npub async fn test_create_baker(db: &DbConn) {\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .await\n        .expect(\"could not insert bakery\");\n\n    #[derive(Serialize, Deserialize)]\n    struct ContactDetails {\n        mobile: String,\n        home: String,\n        address: String,\n    }\n\n    let baker_bob_contact = ContactDetails {\n        mobile: \"+61424000000\".to_owned(),\n        home: \"0395555555\".to_owned(),\n        address: \"12 Test St, Testville, Vic, Australia\".to_owned(),\n    };\n    let baker_bob = baker::ActiveModel {\n        name: Set(\"Baker Bob\".to_owned()),\n        contact_details: Set(serde_json::json!(baker_bob_contact)),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n    let res = Baker::insert(baker_bob)\n        .exec(db)\n        .await\n        .expect(\"could not insert baker\");\n\n    let baker: Option<baker::Model> = Baker::find_by_id(res.last_insert_id)\n        .one(db)\n        .await\n        .expect(\"could not find baker\");\n\n    assert!(baker.is_some());\n    let baker_model = baker.unwrap();\n    assert_eq!(baker_model.name, \"Baker Bob\");\n    assert_eq!(\n        baker_model.contact_details[\"mobile\"],\n        baker_bob_contact.mobile\n    );\n    assert_eq!(baker_model.contact_details[\"home\"], baker_bob_contact.home);\n    assert_eq!(\n        baker_model.contact_details[\"address\"],\n        baker_bob_contact.address\n    );\n    assert_eq!(\n        baker_model\n            .find_related(Bakery)\n            .one(db)\n            .await\n            .expect(\"Bakery not found\")\n            .unwrap()\n            .name,\n        \"SeaSide Bakery\"\n    );\n\n    let bakery: Option<bakery::Model> = Bakery::find_by_id(bakery_insert_res.last_insert_id)\n        .one(db)\n        .await\n        .unwrap();\n\n    let related_bakers: Vec<baker::Model> = bakery\n        .unwrap()\n        .find_related(Baker)\n        .all(db)\n        .await\n        .expect(\"could not find related bakers\");\n    assert_eq!(related_bakers.len(), 1);\n    assert_eq!(related_bakers[0].name, \"Baker Bob\")\n}\n"
  },
  {
    "path": "tests/crud/create_cake.rs",
    "content": "pub use super::*;\nuse uuid::Uuid;\n\npub async fn test_create_cake(db: &DbConn) {\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .await\n        .expect(\"could not insert bakery\");\n\n    let baker_bob = baker::ActiveModel {\n        name: Set(\"Baker Bob\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n    let baker_insert_res = Baker::insert(baker_bob)\n        .exec(db)\n        .await\n        .expect(\"could not insert baker\");\n    let uuid = Uuid::new_v4();\n\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(-10.25)),\n        gluten_free: Set(false),\n        serial: Set(uuid),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n\n    let cake_insert_res = Cake::insert(mud_cake)\n        .exec(db)\n        .await\n        .expect(\"could not insert cake\");\n\n    let cake: Option<cake::Model> = Cake::find_by_id(cake_insert_res.last_insert_id)\n        .one(db)\n        .await\n        .expect(\"could not find cake\");\n\n    let cake_baker = cakes_bakers::ActiveModel {\n        cake_id: Set(cake_insert_res.last_insert_id),\n        baker_id: Set(baker_insert_res.last_insert_id),\n    };\n    let cake_baker_res = CakesBakers::insert(cake_baker.clone())\n        .exec(db)\n        .await\n        .expect(\"could not insert cake_baker\");\n    assert_eq!(\n        cake_baker_res.last_insert_id,\n        (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())\n    );\n\n    assert!(cake.is_some());\n    let cake_model = cake.unwrap();\n    assert_eq!(cake_model.name, \"Mud Cake\");\n    assert_eq!(cake_model.price, rust_dec(-10.25));\n    assert!(!cake_model.gluten_free);\n    assert_eq!(\n        cake_model\n            .find_related(Bakery)\n            .one(db)\n            .await\n            .expect(\"Bakery not found\")\n            .unwrap()\n            .name,\n        \"SeaSide Bakery\"\n    );\n    assert_eq!(cake_model.serial, uuid);\n\n    let related_bakers: Vec<baker::Model> = cake_model\n        .find_related(Baker)\n        .all(db)\n        .await\n        .expect(\"could not find related bakers\");\n    assert_eq!(related_bakers.len(), 1);\n    assert_eq!(related_bakers[0].name, \"Baker Bob\");\n\n    let baker: Option<baker::Model> = Baker::find_by_id(baker_insert_res.last_insert_id)\n        .one(db)\n        .await\n        .expect(\"could not find baker\");\n\n    let related_cakes: Vec<cake::Model> = baker\n        .unwrap()\n        .find_related(Cake)\n        .all(db)\n        .await\n        .expect(\"could not find related cakes\");\n    assert_eq!(related_cakes.len(), 1);\n    assert_eq!(related_cakes[0].name, \"Mud Cake\")\n}\n"
  },
  {
    "path": "tests/crud/create_lineitem.rs",
    "content": "pub use super::*;\nuse sea_orm::entity::prelude::{ChronoUtc, Uuid};\n\npub async fn test_create_lineitem(db: &DbConn) {\n    // Bakery\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .await\n        .expect(\"could not insert bakery\");\n\n    // Baker\n    let baker_bob = baker::ActiveModel {\n        name: Set(\"Baker Bob\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n    let baker_insert_res = Baker::insert(baker_bob)\n        .exec(db)\n        .await\n        .expect(\"could not insert baker\");\n\n    // Cake\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n\n    let cake_insert_res = Cake::insert(mud_cake)\n        .exec(db)\n        .await\n        .expect(\"could not insert cake\");\n\n    // Cake_Baker\n    let cake_baker = cakes_bakers::ActiveModel {\n        cake_id: Set(cake_insert_res.last_insert_id),\n        baker_id: Set(baker_insert_res.last_insert_id),\n    };\n    let cake_baker_res = CakesBakers::insert(cake_baker.clone())\n        .exec(db)\n        .await\n        .expect(\"could not insert cake_baker\");\n    assert_eq!(\n        cake_baker_res.last_insert_id,\n        (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())\n    );\n\n    // Customer\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        notes: Set(Some(\"Loves cheese cake\".to_owned())),\n        ..Default::default()\n    };\n    let customer_insert_res = Customer::insert(customer_kate)\n        .exec(db)\n        .await\n        .expect(\"could not insert customer\");\n\n    // Order\n    let order_1 = order::ActiveModel {\n        bakery_id: Set(bakery_insert_res.last_insert_id),\n        customer_id: Set(customer_insert_res.last_insert_id),\n        total: Set(rust_dec(7.55)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    };\n    let order_insert_res = Order::insert(order_1)\n        .exec(db)\n        .await\n        .expect(\"could not insert order\");\n\n    // Lineitem\n    let lineitem_1 = lineitem::ActiveModel {\n        cake_id: Set(cake_insert_res.last_insert_id),\n        order_id: Set(order_insert_res.last_insert_id),\n        price: Set(rust_dec(7.55)),\n        quantity: Set(1),\n        ..Default::default()\n    };\n    let lineitem_insert_res = Lineitem::insert(lineitem_1)\n        .exec(db)\n        .await\n        .expect(\"could not insert lineitem\");\n\n    let lineitem: Option<lineitem::Model> =\n        Lineitem::find_by_id(lineitem_insert_res.last_insert_id)\n            .one(db)\n            .await\n            .expect(\"could not find lineitem\");\n\n    assert!(lineitem.is_some());\n    let lineitem_model = lineitem.unwrap();\n\n    assert_eq!(lineitem_model.price, rust_dec(7.55));\n\n    let cake: Option<cake::Model> = Cake::find_by_id(lineitem_model.cake_id)\n        .one(db)\n        .await\n        .expect(\"could not find cake\");\n\n    let cake_model = cake.unwrap();\n    assert_eq!(cake_model.name, \"Mud Cake\");\n\n    let order: Option<order::Model> = Order::find_by_id(lineitem_model.order_id)\n        .one(db)\n        .await\n        .expect(\"could not find order\");\n\n    let order_model = order.unwrap();\n    assert_eq!(order_model.customer_id, customer_insert_res.last_insert_id);\n}\n"
  },
  {
    "path": "tests/crud/create_order.rs",
    "content": "pub use super::*;\nuse sea_orm::entity::prelude::{ChronoUtc, Uuid};\n\npub async fn test_create_order(db: &DbConn) {\n    // Bakery\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .await\n        .expect(\"could not insert bakery\");\n\n    // Baker\n    let baker_bob = baker::ActiveModel {\n        name: Set(\"Baker Bob\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n    let baker_insert_res = Baker::insert(baker_bob)\n        .exec(db)\n        .await\n        .expect(\"could not insert baker\");\n\n    // Cake\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n\n    let cake_insert_res = Cake::insert(mud_cake)\n        .exec(db)\n        .await\n        .expect(\"could not insert cake\");\n\n    // Cake_Baker\n    let cake_baker = cakes_bakers::ActiveModel {\n        cake_id: Set(cake_insert_res.last_insert_id),\n        baker_id: Set(baker_insert_res.last_insert_id),\n    };\n    let cake_baker_res = CakesBakers::insert(cake_baker.clone())\n        .exec(db)\n        .await\n        .expect(\"could not insert cake_baker\");\n    assert_eq!(\n        cake_baker_res.last_insert_id,\n        (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())\n    );\n\n    // Customer\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        notes: Set(Some(\"Loves cheese cake\".to_owned())),\n        ..Default::default()\n    };\n    let customer_insert_res = Customer::insert(customer_kate)\n        .exec(db)\n        .await\n        .expect(\"could not insert customer\");\n\n    // Order\n    let order_1 = order::ActiveModel {\n        bakery_id: Set(bakery_insert_res.last_insert_id),\n        customer_id: Set(customer_insert_res.last_insert_id),\n        total: Set(rust_dec(15.10)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    };\n    let order_insert_res = Order::insert(order_1)\n        .exec(db)\n        .await\n        .expect(\"could not insert order\");\n\n    // Lineitem\n    let lineitem_1 = lineitem::ActiveModel {\n        cake_id: Set(cake_insert_res.last_insert_id),\n        order_id: Set(order_insert_res.last_insert_id),\n        price: Set(rust_dec(7.55)),\n        quantity: Set(2),\n        ..Default::default()\n    };\n    let _lineitem_insert_res = Lineitem::insert(lineitem_1)\n        .exec(db)\n        .await\n        .expect(\"could not insert lineitem\");\n\n    let order: Option<order::Model> = Order::find_by_id(order_insert_res.last_insert_id)\n        .one(db)\n        .await\n        .expect(\"could not find order\");\n\n    assert!(order.is_some());\n    let order_model = order.unwrap();\n    assert_eq!(order_model.total, rust_dec(15.10));\n\n    let customer: Option<customer::Model> = Customer::find_by_id(order_model.customer_id)\n        .one(db)\n        .await\n        .expect(\"could not find customer\");\n\n    let customer_model = customer.unwrap();\n    assert_eq!(customer_model.name, \"Kate\");\n\n    let bakery: Option<bakery::Model> = Bakery::find_by_id(order_model.bakery_id)\n        .one(db)\n        .await\n        .expect(\"could not find bakery\");\n\n    let bakery_model = bakery.unwrap();\n    assert_eq!(bakery_model.name, \"SeaSide Bakery\");\n\n    let related_lineitems: Vec<lineitem::Model> = order_model\n        .find_related(Lineitem)\n        .all(db)\n        .await\n        .expect(\"could not find related lineitems\");\n    assert_eq!(related_lineitems.len(), 1);\n    assert_eq!(related_lineitems[0].price, rust_dec(7.55));\n    assert_eq!(related_lineitems[0].quantity, 2);\n}\n"
  },
  {
    "path": "tests/crud/deletes.rs",
    "content": "pub use super::*;\nuse uuid::Uuid;\n\npub async fn test_delete_cake(db: &DbConn) {\n    let initial_cakes = Cake::find().all(db).await.unwrap().len();\n\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .await\n        .expect(\"could not insert bakery\");\n\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n\n    let cake = mud_cake.save(db).await.expect(\"could not insert cake\");\n\n    let cakes = Cake::find().all(db).await.unwrap();\n    assert_eq!(cakes.len(), initial_cakes + 1);\n\n    let _result = cake.delete(db).await.expect(\"failed to delete cake\");\n\n    let cakes = Cake::find().all(db).await.unwrap();\n    assert_eq!(cakes.len(), initial_cakes);\n}\n\npub async fn test_delete_bakery(db: &DbConn) {\n    let initial_bakeries = Bakery::find().all(db).await.unwrap().len();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    assert_eq!(\n        Bakery::find().all(db).await.unwrap().len(),\n        initial_bakeries + 1\n    );\n\n    let _result = bakery.delete(db).await.expect(\"failed to delete bakery\");\n\n    assert_eq!(\n        Bakery::find().all(db).await.unwrap().len(),\n        initial_bakeries\n    );\n}\n"
  },
  {
    "path": "tests/crud/error.rs",
    "content": "pub use super::*;\nuse sea_orm::error::*;\n#[cfg(any(\n    feature = \"sqlx-mysql\",\n    feature = \"sqlx-sqlite\",\n    feature = \"sqlx-postgres\"\n))]\nuse sqlx::Error;\nuse uuid::Uuid;\n\npub async fn test_cake_error_sqlx(db: &DbConn) {\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Moldy Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(None),\n        ..Default::default()\n    };\n\n    let cake = mud_cake.save(db).await.expect(\"could not insert cake\");\n\n    #[allow(unused_variables)]\n    let error: DbErr = cake\n        .into_active_model()\n        .insert(db)\n        .await\n        .expect_err(\"inserting should fail due to duplicate primary key\");\n\n    check_error(&error);\n}\n\nfn check_error(error: &DbErr) {\n    #[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-sqlite\"))]\n    match error {\n        DbErr::Exec(RuntimeErr::SqlxError(error)) => match std::ops::Deref::deref(error) {\n            Error::Database(e) => {\n                #[cfg(feature = \"sqlx-mysql\")]\n                assert_eq!(e.code().unwrap(), \"23000\");\n                #[cfg(feature = \"sqlx-sqlite\")]\n                assert_eq!(e.code().unwrap(), \"1555\");\n            }\n            _ => panic!(\"Unexpected sqlx-error kind\"),\n        },\n        #[cfg(all(feature = \"sqlx-sqlite\", feature = \"sqlite-use-returning-for-3_35\"))]\n        DbErr::Query(RuntimeErr::SqlxError(error)) => match std::ops::Deref::deref(error) {\n            Error::Database(e) => assert_eq!(e.code().unwrap(), \"1555\"),\n            _ => panic!(\"Unexpected sqlx-error kind\"),\n        },\n        _ => panic!(\"Unexpected Error kind\"),\n    }\n    #[cfg(feature = \"sqlx-postgres\")]\n    match error {\n        DbErr::Query(RuntimeErr::SqlxError(error)) => match std::ops::Deref::deref(error) {\n            Error::Database(e) => assert_eq!(e.code().unwrap(), \"23505\"),\n            _ => panic!(\"Unexpected sqlx-error kind\"),\n        },\n        _ => panic!(\"Unexpected Error kind\"),\n    }\n}\n"
  },
  {
    "path": "tests/crud/mod.rs",
    "content": "pub mod create_baker;\npub mod create_cake;\npub mod create_lineitem;\npub mod create_order;\npub mod deletes;\npub mod error;\npub mod updates;\n\npub use create_baker::*;\npub use create_cake::*;\npub use create_lineitem::*;\npub use create_order::*;\npub use deletes::*;\npub use error::*;\npub use updates::*;\n\npub use super::common::bakery_chain::*;\npub use crate::common::setup::rust_dec;\nuse sea_orm::{DbConn, entity::*};\n\npub async fn test_create_bakery(db: &DbConn) {\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .await\n        .expect(\"could not insert bakery\");\n\n    let bakery: Option<bakery::Model> = Bakery::find_by_id(res.last_insert_id)\n        .one(db)\n        .await\n        .expect(\"could not find bakery\");\n\n    assert!(bakery.is_some());\n    let bakery_model = bakery.unwrap();\n    assert_eq!(bakery_model.name, \"SeaSide Bakery\");\n    assert!((bakery_model.profit_margin - 10.4).abs() < f64::EPSILON);\n}\n\npub async fn test_create_customer(db: &DbConn) {\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        notes: Set(Some(\"Loves cheese cake\".to_owned())),\n        ..Default::default()\n    };\n    let res = Customer::insert(customer_kate)\n        .exec(db)\n        .await\n        .expect(\"could not insert customer\");\n\n    let customer: Option<customer::Model> = Customer::find_by_id(res.last_insert_id)\n        .one(db)\n        .await\n        .expect(\"could not find customer\");\n\n    assert!(customer.is_some());\n    let customer_model = customer.unwrap();\n    assert_eq!(customer_model.name, \"Kate\");\n    assert_eq!(customer_model.notes, Some(\"Loves cheese cake\".to_owned()));\n}\n"
  },
  {
    "path": "tests/crud/updates.rs",
    "content": "pub use super::*;\nuse sea_orm::{DbErr, query::*};\nuse uuid::Uuid;\n\npub async fn test_update_cake(db: &DbConn) {\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .await\n        .expect(\"could not insert bakery\");\n\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(bakery_insert_res.last_insert_id)),\n        ..Default::default()\n    };\n\n    let cake_insert_res = Cake::insert(mud_cake)\n        .exec(db)\n        .await\n        .expect(\"could not insert cake\");\n\n    let cake: Option<cake::Model> = Cake::find_by_id(cake_insert_res.last_insert_id)\n        .one(db)\n        .await\n        .expect(\"could not find cake\");\n\n    assert!(cake.is_some());\n    let cake_model = cake.unwrap();\n    assert_eq!(cake_model.name, \"Mud Cake\");\n    assert_eq!(cake_model.price, rust_dec(10.25));\n    assert!(!cake_model.gluten_free);\n\n    let large_number = \"1234_5678_9012.3456\".parse().unwrap();\n\n    let mut cake_am: cake::ActiveModel = cake_model.into();\n    cake_am.name = Set(\"Extra chocolate mud cake\".to_owned());\n    cake_am.price = Set(large_number);\n\n    let _cake_update_res: cake::Model = cake_am.update(db).await.expect(\"could not update cake\");\n\n    let cake: Option<cake::Model> = Cake::find_by_id(cake_insert_res.last_insert_id)\n        .one(db)\n        .await\n        .expect(\"could not find cake\");\n    let cake_model = cake.unwrap();\n    assert_eq!(cake_model.name, \"Extra chocolate mud cake\");\n    assert_eq!(cake_model.price, large_number);\n    assert!(!cake_model.gluten_free);\n}\n\npub async fn test_update_bakery(db: &DbConn) {\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let bakery_insert_res = Bakery::insert(seaside_bakery)\n        .exec(db)\n        .await\n        .expect(\"could not insert bakery\");\n\n    let bakery: Option<bakery::Model> = Bakery::find_by_id(bakery_insert_res.last_insert_id)\n        .one(db)\n        .await\n        .expect(\"could not find bakery\");\n\n    assert!(bakery.is_some());\n    let bakery_model = bakery.unwrap();\n    assert_eq!(bakery_model.name, \"SeaSide Bakery\");\n    assert!((bakery_model.profit_margin - 10.40).abs() < f64::EPSILON);\n\n    let mut bakery_am: bakery::ActiveModel = bakery_model.into();\n    bakery_am.name = Set(\"SeaBreeze Bakery\".to_owned());\n    bakery_am.profit_margin = Set(12.00);\n\n    let _bakery_update_res: bakery::Model =\n        bakery_am.update(db).await.expect(\"could not update bakery\");\n\n    let bakery: Option<bakery::Model> = Bakery::find_by_id(bakery_insert_res.last_insert_id)\n        .one(db)\n        .await\n        .expect(\"could not find bakery\");\n    let bakery_model = bakery.unwrap();\n    assert_eq!(bakery_model.name, \"SeaBreeze Bakery\");\n    assert!((bakery_model.profit_margin - 12.00).abs() < f64::EPSILON);\n}\n\npub async fn test_update_deleted_customer(db: &DbConn) {\n    let init_n_customers = Customer::find().count(db).await.unwrap();\n\n    let customer = customer::ActiveModel {\n        name: Set(\"John\".to_owned()),\n        notes: Set(None),\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert customer\");\n\n    assert_eq!(\n        Customer::find().count(db).await.unwrap(),\n        init_n_customers + 1\n    );\n\n    let customer_id = customer.id.clone().unwrap();\n\n    let _ = customer.delete(db).await;\n    assert_eq!(Customer::find().count(db).await.unwrap(), init_n_customers);\n\n    let customer = customer::ActiveModel {\n        id: Set(customer_id),\n        name: Set(\"John 2\".to_owned()),\n        ..Default::default()\n    };\n\n    let customer_update_res = customer.update(db).await;\n\n    assert_eq!(customer_update_res, Err(DbErr::RecordNotUpdated));\n\n    assert_eq!(Customer::find().count(db).await.unwrap(), init_n_customers);\n\n    let customer: Option<customer::Model> = Customer::find_by_id(customer_id)\n        .one(db)\n        .await\n        .expect(\"could not find customer\");\n\n    assert_eq!(customer, None);\n}\n"
  },
  {
    "path": "tests/crud_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\nmod crud;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\npub use crud::*;\nuse sea_orm::DatabaseConnection;\n\n// Run the test locally:\n// DATABASE_URL=\"sqlite::memory:\" cargo test --features rusqlite --test crud_tests\n// DATABASE_URL=\"sqlite::memory:\" cargo test --features sqlx-sqlite,runtime-tokio --test crud_tests\n// DATABASE_URL=\"mysql://sea:sea@localhost\" cargo test --features sqlx-mysql,runtime-tokio-native-tls --test crud_tests\n// DATABASE_URL=\"postgres://sea:sea@localhost\" cargo test --features sqlx-postgres,runtime-tokio-native-tls --test crud_tests\n#[sea_orm_macros::test]\nasync fn main() {\n    let ctx = TestContext::new(\"bakery_chain_schema_crud_tests\").await;\n    create_tables(&ctx.db).await.unwrap();\n    create_entities(&ctx.db).await;\n    ctx.delete().await;\n}\n\npub async fn create_entities(db: &DatabaseConnection) {\n    test_create_bakery(db).await;\n    test_create_baker(db).await;\n    test_create_customer(db).await;\n    test_create_cake(db).await;\n    test_create_lineitem(db).await;\n    test_create_order(db).await;\n\n    test_update_cake(db).await;\n    test_update_bakery(db).await;\n    test_update_deleted_customer(db).await;\n\n    test_delete_cake(db).await;\n    test_cake_error_sqlx(db).await;\n    test_delete_bakery(db).await;\n}\n"
  },
  {
    "path": "tests/cursor_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DerivePartialModel, FromQueryResult, QuerySelect, Set, entity::prelude::*};\nuse sea_query::ExprTrait;\nuse serde_json::json;\n\n#[sea_orm_macros::test]\nasync fn cursor_tests() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"cursor_tests\").await;\n    create_insert_default_table(&ctx.db).await?;\n    create_insert_default(&ctx.db).await?;\n    cursor_pagination(&ctx.db).await?;\n    bakery_chain_schema::create_bakery_table(&ctx.db).await?;\n    bakery_chain_schema::create_baker_table(&ctx.db).await?;\n    bakery_chain_schema::create_cake_table(&ctx.db).await?;\n    bakery_chain_schema::create_cakes_bakers_table(&ctx.db).await?;\n    create_baker_cake(&ctx.db).await?;\n    cursor_related_pagination(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    for _ in 0..10 {\n        ActiveModel {\n            ..Default::default()\n        }\n        .insert(db)\n        .await?;\n    }\n\n    assert_eq!(\n        Entity::find().all(db).await?,\n        [\n            Model { id: 1 },\n            Model { id: 2 },\n            Model { id: 3 },\n            Model { id: 4 },\n            Model { id: 5 },\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    Ok(())\n}\n\npub async fn cursor_pagination(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    // Before 5, i.e. id < 5\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.before(5);\n\n    assert_eq!(\n        cursor.first(4).all(db).await?,\n        [\n            Model { id: 1 },\n            Model { id: 2 },\n            Model { id: 3 },\n            Model { id: 4 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(5).all(db).await?,\n        [\n            Model { id: 1 },\n            Model { id: 2 },\n            Model { id: 3 },\n            Model { id: 4 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(4).all(db).await?,\n        [\n            Model { id: 1 },\n            Model { id: 2 },\n            Model { id: 3 },\n            Model { id: 4 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(5).all(db).await?,\n        [\n            Model { id: 1 },\n            Model { id: 2 },\n            Model { id: 3 },\n            Model { id: 4 },\n        ]\n    );\n\n    // Before 5 DESC, i.e. id > 5\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.before(5).desc();\n\n    assert_eq!(\n        cursor.first(4).all(db).await?,\n        [\n            Model { id: 10 },\n            Model { id: 9 },\n            Model { id: 8 },\n            Model { id: 7 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(5).all(db).await?,\n        [\n            Model { id: 10 },\n            Model { id: 9 },\n            Model { id: 8 },\n            Model { id: 7 },\n            Model { id: 6 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(4).all(db).await?,\n        [\n            Model { id: 9 },\n            Model { id: 8 },\n            Model { id: 7 },\n            Model { id: 6 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(5).all(db).await?,\n        [\n            Model { id: 10 },\n            Model { id: 9 },\n            Model { id: 8 },\n            Model { id: 7 },\n            Model { id: 6 },\n        ]\n    );\n\n    // After 5, i.e. id > 5\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(5);\n\n    assert_eq!(\n        cursor.first(4).all(db).await?,\n        [\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(5).all(db).await?,\n        [\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(6).all(db).await?,\n        [\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(4).all(db).await?,\n        [\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(5).all(db).await?,\n        [\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(6).all(db).await?,\n        [\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    // After 5 DESC, i.e. id < 5\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(5).desc();\n\n    assert_eq!(\n        cursor.first(3).all(db).await?,\n        [Model { id: 4 }, Model { id: 3 }, Model { id: 2 },]\n    );\n\n    assert_eq!(\n        cursor.first(4).all(db).await?,\n        [\n            Model { id: 4 },\n            Model { id: 3 },\n            Model { id: 2 },\n            Model { id: 1 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(5).all(db).await?,\n        [\n            Model { id: 4 },\n            Model { id: 3 },\n            Model { id: 2 },\n            Model { id: 1 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(3).all(db).await?,\n        [Model { id: 3 }, Model { id: 2 }, Model { id: 1 },]\n    );\n\n    assert_eq!(\n        cursor.last(4).all(db).await?,\n        [\n            Model { id: 4 },\n            Model { id: 3 },\n            Model { id: 2 },\n            Model { id: 1 },\n        ]\n    );\n\n    assert_eq!(\n        cursor.last(5).all(db).await?,\n        [\n            Model { id: 4 },\n            Model { id: 3 },\n            Model { id: 2 },\n            Model { id: 1 },\n        ]\n    );\n\n    // Between 5 and 8, i.e. id > 5 AND id < 8\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(5).before(8);\n\n    assert_eq!(cursor.first(1).all(db).await?, [Model { id: 6 }]);\n\n    assert_eq!(\n        cursor.first(2).all(db).await?,\n        [Model { id: 6 }, Model { id: 7 }]\n    );\n\n    assert_eq!(\n        cursor.first(3).all(db).await?,\n        [Model { id: 6 }, Model { id: 7 }]\n    );\n\n    assert_eq!(cursor.last(1).all(db).await?, [Model { id: 7 }]);\n\n    assert_eq!(\n        cursor.last(2).all(db).await?,\n        [Model { id: 6 }, Model { id: 7 }]\n    );\n\n    assert_eq!(\n        cursor.last(3).all(db).await?,\n        [Model { id: 6 }, Model { id: 7 }]\n    );\n\n    // Between 8 and 5 DESC, i.e. id < 8 AND id > 5\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(8).before(5).desc();\n\n    assert_eq!(cursor.first(1).all(db).await?, [Model { id: 7 }]);\n\n    assert_eq!(\n        cursor.first(2).all(db).await?,\n        [Model { id: 7 }, Model { id: 6 }]\n    );\n\n    assert_eq!(\n        cursor.first(3).all(db).await?,\n        [Model { id: 7 }, Model { id: 6 }]\n    );\n\n    assert_eq!(cursor.last(1).all(db).await?, [Model { id: 6 }]);\n\n    assert_eq!(\n        cursor.last(2).all(db).await?,\n        [Model { id: 7 }, Model { id: 6 }]\n    );\n\n    assert_eq!(\n        cursor.last(3).all(db).await?,\n        [Model { id: 7 }, Model { id: 6 }]\n    );\n\n    // Ensure asc/desc order can be changed\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.first(2);\n\n    assert_eq!(cursor.all(db).await?, [Model { id: 1 }, Model { id: 2 },]);\n\n    assert_eq!(\n        cursor.asc().all(db).await?,\n        [Model { id: 1 }, Model { id: 2 },]\n    );\n\n    assert_eq!(\n        cursor.desc().all(db).await?,\n        [Model { id: 10 }, Model { id: 9 },]\n    );\n\n    assert_eq!(\n        cursor.asc().all(db).await?,\n        [Model { id: 1 }, Model { id: 2 },]\n    );\n\n    assert_eq!(\n        cursor.desc().all(db).await?,\n        [Model { id: 10 }, Model { id: 9 },]\n    );\n\n    // Fetch custom struct\n\n    #[derive(FromQueryResult, Debug, PartialEq, Clone)]\n    struct Row {\n        id: i32,\n    }\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(5).before(8);\n\n    let mut cursor = cursor.into_model::<Row>();\n\n    assert_eq!(\n        cursor.first(2).all(db).await?,\n        [Row { id: 6 }, Row { id: 7 }]\n    );\n\n    assert_eq!(\n        cursor.first(3).all(db).await?,\n        [Row { id: 6 }, Row { id: 7 }]\n    );\n\n    // Fetch custom struct desc\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(8).before(5).desc();\n\n    let mut cursor = cursor.into_model::<Row>();\n\n    assert_eq!(\n        cursor.first(2).all(db).await?,\n        [Row { id: 7 }, Row { id: 6 }]\n    );\n\n    assert_eq!(\n        cursor.first(3).all(db).await?,\n        [Row { id: 7 }, Row { id: 6 }]\n    );\n\n    // Fetch JSON value\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(5).before(8);\n\n    let mut cursor = cursor.into_json();\n\n    assert_eq!(\n        cursor.first(2).all(db).await?,\n        [json!({ \"id\": 6 }), json!({ \"id\": 7 })]\n    );\n\n    assert_eq!(\n        cursor.first(3).all(db).await?,\n        [json!({ \"id\": 6 }), json!({ \"id\": 7 })]\n    );\n\n    #[derive(DerivePartialModel, Debug, PartialEq, Clone)]\n    #[sea_orm(entity = \"Entity\")]\n    struct PartialRow {\n        #[sea_orm(from_col = \"id\")]\n        id: i32,\n        #[sea_orm(from_expr = \"sea_query::Expr::col(Column::Id).add(1000)\")]\n        id_shifted: i32,\n    }\n\n    let mut cursor = cursor.into_partial_model::<PartialRow>();\n\n    assert_eq!(\n        cursor.first(2).all(db).await?,\n        [\n            PartialRow {\n                id: 6,\n                id_shifted: 1006,\n            },\n            PartialRow {\n                id: 7,\n                id_shifted: 1007,\n            }\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(3).all(db).await?,\n        [\n            PartialRow {\n                id: 6,\n                id_shifted: 1006,\n            },\n            PartialRow {\n                id: 7,\n                id_shifted: 1007,\n            }\n        ]\n    );\n\n    // Fetch JSON value desc\n\n    let mut cursor = Entity::find().cursor_by(Column::Id);\n\n    cursor.after(8).before(5).desc();\n\n    let mut cursor = cursor.into_json();\n\n    assert_eq!(\n        cursor.first(2).all(db).await?,\n        [json!({ \"id\": 7 }), json!({ \"id\": 6 })]\n    );\n\n    assert_eq!(\n        cursor.first(3).all(db).await?,\n        [json!({ \"id\": 7 }), json!({ \"id\": 6 })]\n    );\n\n    let mut cursor = cursor.into_partial_model::<PartialRow>();\n\n    assert_eq!(\n        cursor.first(2).all(db).await?,\n        [\n            PartialRow {\n                id: 7,\n                id_shifted: 1007,\n            },\n            PartialRow {\n                id: 6,\n                id_shifted: 1006,\n            }\n        ]\n    );\n\n    assert_eq!(\n        cursor.first(3).all(db).await?,\n        [\n            PartialRow {\n                id: 7,\n                id_shifted: 1007,\n            },\n            PartialRow {\n                id: 6,\n                id_shifted: 1006,\n            },\n        ]\n    );\n\n    Ok(())\n}\n\nuse common::bakery_chain::{\n    Baker, Bakery, Cake, CakesBakers, baker, bakery, cake, cakes_bakers,\n    schema as bakery_chain_schema,\n};\n\nfn bakery(i: i32) -> bakery::Model {\n    bakery::Model {\n        name: i.to_string(),\n        profit_margin: 10.4,\n        id: i,\n    }\n}\n\nfn baker(c: char) -> baker::Model {\n    baker::Model {\n        name: c.clone().to_string(),\n        contact_details: serde_json::json!({\n            \"mobile\": \"+61424000000\",\n        }),\n        bakery_id: Some((c as i32 - 65) % 10 + 1),\n        id: c as i32 - 64,\n    }\n}\n\n#[derive(Debug, FromQueryResult, PartialEq)]\npub struct CakeBakerlite {\n    pub cake_name: String,\n    pub cake_id: i32,\n    pub baker_name: String,\n}\n\nfn cakebaker(cake: char, baker: char) -> CakeBakerlite {\n    CakeBakerlite {\n        cake_name: cake.to_string(),\n        cake_id: cake as i32 - 96,\n        baker_name: baker.to_string(),\n    }\n}\n\npub async fn create_baker_cake(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let mut bakeries: Vec<bakery::ActiveModel> = vec![];\n    // bakeries named from 1 to 10\n    for i in 1..=10 {\n        bakeries.push(bakery::ActiveModel {\n            name: Set(i.to_string()),\n            profit_margin: Set(10.4),\n            ..Default::default()\n        });\n    }\n    let _ = Bakery::insert_many(bakeries).exec(db).await?;\n\n    let mut bakers: Vec<baker::ActiveModel> = vec![];\n    let mut cakes: Vec<cake::ActiveModel> = vec![];\n    let mut cakes_bakers: Vec<cakes_bakers::ActiveModel> = vec![];\n    // baker and cakes named from \"A\" to \"Z\" and from \"a\" to \"z\"\n    for c in 'A'..='Z' {\n        bakers.push(baker::ActiveModel {\n            name: Set(c.clone().to_string()),\n            contact_details: Set(serde_json::json!({\n                \"mobile\": \"+61424000000\",\n            })),\n            bakery_id: Set(Some((c as i32 - 65) % 10 + 1)),\n            ..Default::default()\n        });\n        cakes.push(cake::ActiveModel {\n            name: Set(c.to_ascii_lowercase().to_string()),\n            price: Set(rust_dec(10.25)),\n            gluten_free: Set(false),\n            serial: Set(Uuid::new_v4()),\n            bakery_id: Set(Some((c as i32 - 65) % 10 + 1)),\n            ..Default::default()\n        });\n        cakes_bakers.push(cakes_bakers::ActiveModel {\n            cake_id: Set(c as i32 - 64),\n            baker_id: Set(c as i32 - 64),\n        })\n    }\n    cakes_bakers.append(\n        vec![\n            cakes_bakers::ActiveModel {\n                cake_id: Set(2),\n                baker_id: Set(1),\n            },\n            cakes_bakers::ActiveModel {\n                cake_id: Set(1),\n                baker_id: Set(2),\n            },\n        ]\n        .as_mut(),\n    );\n    Baker::insert_many(bakers).exec(db).await?;\n    Cake::insert_many(cakes).exec(db).await?;\n    CakesBakers::insert_many(cakes_bakers).exec(db).await?;\n\n    Ok(())\n}\n\npub async fn cursor_related_pagination(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use common::bakery_chain::*;\n\n    assert_eq!(\n        bakery::Entity::find()\n            .cursor_by(bakery::Column::Id)\n            .before(5)\n            .first(4)\n            .all(db)\n            .await?,\n        [bakery(1), bakery(2), bakery(3), bakery(4),]\n    );\n\n    assert_eq!(\n        bakery::Entity::find()\n            .cursor_by(bakery::Column::Id)\n            .before(5)\n            .first(4)\n            .desc()\n            .all(db)\n            .await?,\n        [bakery(10), bakery(9), bakery(8), bakery(7),]\n    );\n\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Id)\n            .before(5)\n            .first(20)\n            .all(db)\n            .await?,\n        [\n            (bakery(1), Some(baker('A'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(2), Some(baker('B'))),\n            (bakery(2), Some(baker('L'))),\n            (bakery(2), Some(baker('V'))),\n            (bakery(3), Some(baker('C'))),\n            (bakery(3), Some(baker('M'))),\n            (bakery(3), Some(baker('W'))),\n            (bakery(4), Some(baker('D'))),\n            (bakery(4), Some(baker('N'))),\n            (bakery(4), Some(baker('X'))),\n        ]\n    );\n\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Id)\n            .after(5)\n            .last(20)\n            .desc()\n            .all(db)\n            .await?,\n        [\n            (bakery(4), Some(baker('X'))),\n            (bakery(4), Some(baker('N'))),\n            (bakery(4), Some(baker('D'))),\n            (bakery(3), Some(baker('W'))),\n            (bakery(3), Some(baker('M'))),\n            (bakery(3), Some(baker('C'))),\n            (bakery(2), Some(baker('V'))),\n            (bakery(2), Some(baker('L'))),\n            (bakery(2), Some(baker('B'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('A'))),\n        ]\n    );\n\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Id)\n            .before(5)\n            .first(4)\n            .all(db)\n            .await?,\n        [\n            (bakery(1), Some(baker('A'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(2), Some(baker('B'))),\n        ]\n    );\n\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Id)\n            .after(5)\n            .last(4)\n            .desc()\n            .all(db)\n            .await?,\n        [\n            (bakery(2), Some(baker('B'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('A'))),\n        ]\n    );\n\n    // since \"10\" is before \"2\" lexicologically, it return that first\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Name)\n            .after(\"3\")\n            .last(4)\n            .desc()\n            .all(db)\n            .await?,\n        [\n            (bakery(10), Some(baker('J'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('A'))),\n        ]\n    );\n\n    // since \"10\" is before \"2\" lexicologically, it return that first\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Name)\n            .before(\"3\")\n            .first(4)\n            .all(db)\n            .await?,\n        [\n            (bakery(1), Some(baker('A'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(10), Some(baker('J'))),\n        ]\n    );\n\n    // since \"10\" is before \"2\" lexicologically, it return that first\n    assert_eq!(\n        bakery::Entity::find()\n            .find_also_related(Baker)\n            .cursor_by(bakery::Column::Name)\n            .after(\"3\")\n            .last(4)\n            .desc()\n            .all(db)\n            .await?,\n        [\n            (bakery(10), Some(baker('J'))),\n            (bakery(1), Some(baker('U'))),\n            (bakery(1), Some(baker('K'))),\n            (bakery(1), Some(baker('A'))),\n        ]\n    );\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]\n    enum QueryAs {\n        CakeId,\n        CakeName,\n        BakerName,\n    }\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by(cake::Column::Name)\n            .before(\"e\")\n            .first(4)\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)\n            .await?,\n        vec![\n            cakebaker('a', 'A'),\n            cakebaker('a', 'B'),\n            cakebaker('b', 'A'),\n            cakebaker('b', 'B')\n        ]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by(cake::Column::Name)\n            .after(\"e\")\n            .last(4)\n            .desc()\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)\n            .await?,\n        vec![\n            cakebaker('b', 'B'),\n            cakebaker('b', 'A'),\n            cakebaker('a', 'B'),\n            cakebaker('a', 'A')\n        ]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by(cake::Column::Name)\n            .before(\"b\")\n            .first(4)\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)\n            .await?,\n        vec![cakebaker('a', 'A'), cakebaker('a', 'B')]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by(cake::Column::Name)\n            .after(\"b\")\n            .last(4)\n            .desc()\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)\n            .await?,\n        vec![cakebaker('a', 'B'), cakebaker('a', 'A')]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by_other(baker::Column::Name)\n            .before(\"B\")\n            .first(4)\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)\n            .await?,\n        vec![cakebaker('a', 'A'), cakebaker('b', 'A'),]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by_other(baker::Column::Name)\n            .after(\"B\")\n            .last(4)\n            .desc()\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)\n            .await?,\n        vec![cakebaker('b', 'A'), cakebaker('a', 'A'),]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by_other(baker::Column::Name)\n            .before(\"E\")\n            .first(20)\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)\n            .await?,\n        vec![\n            cakebaker('a', 'A'),\n            cakebaker('b', 'A'),\n            cakebaker('a', 'B'),\n            cakebaker('b', 'B'),\n            cakebaker('c', 'C'),\n            cakebaker('d', 'D'),\n        ]\n    );\n\n    assert_eq!(\n        cake::Entity::find()\n            .find_also_related(Baker)\n            .select_only()\n            .column_as(cake::Column::Id, QueryAs::CakeId)\n            .column_as(cake::Column::Name, QueryAs::CakeName)\n            .column_as(baker::Column::Name, QueryAs::BakerName)\n            .cursor_by_other(baker::Column::Name)\n            .after(\"E\")\n            .last(20)\n            .desc()\n            .clone()\n            .into_model::<CakeBakerlite>()\n            .all(db)\n            .await?,\n        vec![\n            cakebaker('d', 'D'),\n            cakebaker('c', 'C'),\n            cakebaker('b', 'B'),\n            cakebaker('a', 'B'),\n            cakebaker('b', 'A'),\n            cakebaker('a', 'A'),\n        ]\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/database_executor_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseExecutor, IntoDatabaseExecutor, Set, TransactionTrait, prelude::*};\n\n#[sea_orm_macros::test]\npub async fn connection_or_transaction_from_connection() {\n    let ctx = TestContext::new(\"connection_or_transaction_from_connection\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let cot = DatabaseExecutor::from(&ctx.db);\n\n    bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&cot)\n    .await\n    .unwrap();\n\n    let bakeries = Bakery::find().all(&cot).await.unwrap();\n    assert_eq!(bakeries.len(), 1);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn connection_or_transaction_from_transaction() {\n    let ctx = TestContext::new(\"connection_or_transaction_from_transaction\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let txn = ctx.db.begin().await.unwrap();\n    let cot = DatabaseExecutor::from(&txn);\n\n    bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&cot)\n    .await\n    .unwrap();\n\n    let bakeries = Bakery::find().all(&cot).await.unwrap();\n    assert_eq!(bakeries.len(), 1);\n\n    txn.commit().await.unwrap();\n\n    let bakeries = Bakery::find().all(&ctx.db).await.unwrap();\n    assert_eq!(bakeries.len(), 1);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn connection_or_transaction_begin() {\n    let ctx = TestContext::new(\"connection_or_transaction_begin\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let cot = DatabaseExecutor::from(&ctx.db);\n    let txn = cot.begin().await.unwrap();\n\n    bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&txn)\n    .await\n    .unwrap();\n\n    let bakeries = Bakery::find().all(&txn).await.unwrap();\n    assert_eq!(bakeries.len(), 1);\n\n    txn.commit().await.unwrap();\n\n    let bakeries = Bakery::find().all(&ctx.db).await.unwrap();\n    assert_eq!(bakeries.len(), 1);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn connection_or_transaction_nested() {\n    let ctx = TestContext::new(\"connection_or_transaction_nested\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let txn = ctx.db.begin().await.unwrap();\n    let cot = DatabaseExecutor::from(&txn);\n\n    bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&cot)\n    .await\n    .unwrap();\n\n    // Begin nested transaction from DatabaseExecutor\n    let nested_txn = cot.begin().await.unwrap();\n\n    bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&nested_txn)\n    .await\n    .unwrap();\n\n    let bakeries = Bakery::find().all(&nested_txn).await.unwrap();\n    assert_eq!(bakeries.len(), 2);\n\n    nested_txn.commit().await.unwrap();\n    txn.commit().await.unwrap();\n\n    let bakeries = Bakery::find().all(&ctx.db).await.unwrap();\n    assert_eq!(bakeries.len(), 2);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn connection_or_transaction_rollback() {\n    let ctx = TestContext::new(\"connection_or_transaction_rollback\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    {\n        let txn = ctx.db.begin().await.unwrap();\n        let cot = DatabaseExecutor::from(&txn);\n\n        bakery::ActiveModel {\n            name: Set(\"SeaSide Bakery\".to_owned()),\n            profit_margin: Set(10.4),\n            ..Default::default()\n        }\n        .save(&cot)\n        .await\n        .unwrap();\n\n        let bakeries = Bakery::find().all(&cot).await.unwrap();\n        assert_eq!(bakeries.len(), 1);\n\n        // Transaction dropped without commit - should rollback\n    }\n\n    let bakeries = Bakery::find().all(&ctx.db).await.unwrap();\n    assert_eq!(bakeries.len(), 0);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn into_database_executor_trait() {\n    let ctx = TestContext::new(\"into_database_executor_trait\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    async fn save_bakery<'c, C>(db: C, name: &str) -> Result<(), DbErr>\n    where\n        C: IntoDatabaseExecutor<'c>,\n    {\n        let db = db.into_database_executor();\n        bakery::ActiveModel {\n            name: Set(name.to_owned()),\n            profit_margin: Set(10.0),\n            ..Default::default()\n        }\n        .save(&db)\n        .await?;\n        Ok(())\n    }\n\n    // Test with connection\n    save_bakery(&ctx.db, \"Bakery 1\").await.unwrap();\n\n    // Test with transaction\n    let txn = ctx.db.begin().await.unwrap();\n    save_bakery(&txn, \"Bakery 2\").await.unwrap();\n    txn.commit().await.unwrap();\n\n    let bakeries = Bakery::find().all(&ctx.db).await.unwrap();\n    assert_eq!(bakeries.len(), 2);\n\n    ctx.delete().await;\n}\n"
  },
  {
    "path": "tests/delete_by_id_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\npub use common::{TestContext, features::*, setup::*};\nuse sea_orm::{DatabaseConnection, IntoActiveModel, entity::prelude::*};\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"delete_by_id_tests\").await;\n    create_log_table(&ctx.db).await?;\n    create_and_delete_applog(&ctx.db).await?;\n\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn create_and_delete_applog(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let log1 = applog::Model {\n        id: 1,\n        action: \"Testing\".to_owned(),\n        json: Json::String(\"HI\".to_owned()),\n        created_at: \"2021-09-17T17:50:20+08:00\".parse().unwrap(),\n    };\n\n    Applog::insert(log1.clone().into_active_model())\n        .exec(db)\n        .await?;\n\n    let log2 = applog::Model {\n        id: 2,\n        action: \"Tests\".to_owned(),\n        json: Json::String(\"HELLO\".to_owned()),\n        created_at: \"2022-09-17T17:50:20+08:00\".parse().unwrap(),\n    };\n\n    Applog::insert(log2.clone().into_active_model())\n        .exec(db)\n        .await?;\n\n    let delete_res = Applog::delete_by_id(2).exec(db).await?;\n    assert_eq!(delete_res.rows_affected, 1);\n\n    let find_res = Applog::find_by_id(1).all(db).await?;\n    assert_eq!(find_res, [log1]);\n\n    let find_res = Applog::find_by_id(2).all(db).await?;\n    assert_eq!(find_res, []);\n\n    let delete_res = Applog::delete_by_id(3).exec(db).await?;\n    assert_eq!(delete_res.rows_affected, 0);\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/derive_iden_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\npub use common::{TestContext, features::*, setup::*};\nuse sea_orm::entity::prelude::*;\n\n#[derive(DeriveIden)]\npub enum ClassName {\n    Table,\n    Id,\n    Title,\n    Text,\n}\n\n#[derive(DeriveIden)]\npub enum Book {\n    #[sea_orm(iden = \"book_table\")]\n    Table,\n    Id,\n    #[sea_orm(iden = \"turtle\")]\n    Title,\n    #[sea_orm(iden = \"TeXt\")]\n    Text,\n    #[sea_orm(iden = \"ty_pe\")]\n    Type,\n}\n\n#[derive(DeriveIden)]\nstruct GlyphToken;\n\n#[derive(DeriveIden)]\n#[sea_orm(iden = \"weRd\")]\nstruct Word;\n\n#[test]\nfn main() -> Result<(), DbErr> {\n    assert_eq!(ClassName::Table.to_string(), \"class_name\");\n    assert_eq!(ClassName::Id.to_string(), \"id\");\n    assert_eq!(ClassName::Title.to_string(), \"title\");\n    assert_eq!(ClassName::Text.to_string(), \"text\");\n\n    assert_eq!(Book::Id.to_string(), \"id\");\n    assert_eq!(Book::Table.to_string(), \"book_table\");\n    assert_eq!(Book::Title.to_string(), \"turtle\");\n    assert_eq!(Book::Text.to_string(), \"TeXt\");\n    assert_eq!(Book::Type.to_string(), \"ty_pe\");\n\n    assert_eq!(GlyphToken.to_string(), \"glyph_token\");\n\n    assert_eq!(Word.to_string(), \"weRd\");\n    Ok(())\n}\n"
  },
  {
    "path": "tests/derive_model_tests.rs",
    "content": "use sea_orm::prelude::{HasMany, HasOne};\n\nmod cake {\n    use sea_orm::prelude::*;\n    use serde::Serialize;\n\n    #[sea_orm::model]\n    #[derive(DeriveEntityModel, Debug, Clone, Serialize)]\n    #[sea_orm(table_name = \"cake\")]\n    #[sea_orm(model_attrs(serde(rename_all = \"UPPERCASE\")))]\n    #[sea_orm(model_ex_attrs(serde(rename_all = \"PascalCase\")))]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(has_many)]\n        pub fruits: HasMany<super::fruit::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod fruit {\n    use sea_orm::prelude::*;\n    use serde::Serialize;\n\n    #[sea_orm::model]\n    #[derive(DeriveEntityModel, Debug, Clone)]\n    #[sea_orm(\n        table_name = \"fruit\",\n        model_attrs(derive(Serialize), serde(rename_all = \"UPPERCASE\")),\n        model_ex_attrs(derive(Serialize), serde(rename_all = \"PascalCase\"))\n    )]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub cake_id: Option<i32>,\n        #[sea_orm(belongs_to, from = \"cake_id\", to = \"id\")]\n        pub cake: HasOne<super::cake::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[test]\nfn main() -> Result<(), serde_json::Error> {\n    use sea_orm::EntityName;\n    assert_eq!(cake::Entity.table_name(), \"cake\");\n    assert_eq!(fruit::Entity.table_name(), \"fruit\");\n\n    assert_eq!(serde_json::to_string(&cake::Model { id: 1 })?, \"{\\\"ID\\\":1}\");\n    assert_eq!(\n        serde_json::to_string(&cake::ModelEx {\n            id: 1,\n            fruits: HasMany::Loaded(Vec::new()),\n        })?,\n        \"{\\\"Id\\\":1,\\\"Fruits\\\":[]}\"\n    );\n\n    assert_eq!(\n        serde_json::to_string(&fruit::Model {\n            id: 2,\n            cake_id: Some(1)\n        })?,\n        \"{\\\"ID\\\":2,\\\"CAKE_ID\\\":1}\"\n    );\n    assert_eq!(\n        serde_json::to_string(&fruit::ModelEx {\n            id: 2,\n            cake_id: Some(1),\n            cake: HasOne::Unloaded,\n        })?,\n        \"{\\\"Id\\\":2,\\\"CakeId\\\":1,\\\"Cake\\\":null}\"\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/derive_tests.rs",
    "content": "use sea_orm::{FromQueryResult, TryGetable};\n\n#[derive(FromQueryResult)]\nstruct SimpleTest {\n    _foo: i32,\n    _bar: String,\n}\n\n#[derive(FromQueryResult)]\nstruct GenericTest<T: TryGetable> {\n    _foo: i32,\n    _bar: T,\n}\n\n#[derive(FromQueryResult)]\nstruct DoubleGenericTest<T: TryGetable, F: TryGetable> {\n    _foo: T,\n    _bar: F,\n}\n\n#[derive(FromQueryResult)]\nstruct BoundsGenericTest<T: TryGetable + Copy + Clone + 'static> {\n    _foo: T,\n}\n\n#[derive(FromQueryResult)]\nstruct WhereGenericTest<T>\nwhere\n    T: TryGetable + Copy + Clone + 'static,\n{\n    _foo: T,\n}\n\n#[derive(FromQueryResult)]\nstruct AlreadySpecifiedBoundsGenericTest<T: TryGetable> {\n    _foo: T,\n}\n\n#[derive(FromQueryResult)]\nstruct MixedGenericTest<T: TryGetable + Clone, F>\nwhere\n    F: TryGetable + Copy + Clone + 'static,\n{\n    _foo: T,\n    _bar: F,\n}\n\ntrait MyTrait {\n    type Item: TryGetable;\n}\n\n#[derive(FromQueryResult)]\nstruct TraitAssociateTypeTest<T>\nwhere\n    T: MyTrait,\n{\n    _foo: T::Item,\n}\n\n#[derive(FromQueryResult)]\nstruct FromQueryAttributeTests {\n    #[sea_orm(skip)]\n    _foo: i32,\n    _bar: String,\n}\n\n#[derive(FromQueryResult)]\nstruct FromQueryResultNested {\n    #[sea_orm(nested)]\n    _test: SimpleTest,\n}\n"
  },
  {
    "path": "tests/dyn_table_name_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{\n    DatabaseConnection, Delete, IntoActiveModel, Iterable, QueryTrait, Set, Update,\n    entity::prelude::*,\n};\nuse sea_query::{Expr, ExprTrait, Query};\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"dyn_table_name_tests\").await;\n    create_dyn_table_name_lazy_static_table(&ctx.db).await?;\n    dyn_table_name(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn dyn_table_name(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use dyn_table_name::*;\n\n    for i in 1..=2 {\n        let entity = Entity {\n            table_name: i as u32,\n        };\n        let model = Model {\n            id: 1,\n            name: \"1st Row\".into(),\n        };\n        // Prepare insert statement\n        let mut insert = Entity::insert(model.clone().into_active_model());\n        // Reset the table name of insert statement\n        insert.query().into_table(entity.table_ref());\n        // Execute the insert statement\n        assert_eq!(insert.exec(db).await?.last_insert_id, 1);\n\n        // Prepare select statement\n        let mut select = Entity::find();\n        // Override the select statement\n        *QueryTrait::query(&mut select) = Query::select()\n            .exprs(Column::iter().map(|col| col.select_as(Expr::col(col))))\n            .from(entity.table_ref())\n            .to_owned();\n        // Execute the select statement\n        assert_eq!(select.clone().one(db).await?, Some(model.clone()));\n\n        // Prepare update statement\n        let update = Update::many(entity).set(ActiveModel {\n            name: Set(\"1st Row (edited)\".into()),\n            ..model.clone().into_active_model()\n        });\n        // Execute the update statement\n        assert_eq!(update.exec(db).await?.rows_affected, 1);\n\n        assert_eq!(\n            select.clone().one(db).await?,\n            Some(Model {\n                id: 1,\n                name: \"1st Row (edited)\".into(),\n            })\n        );\n\n        // Prepare delete statement\n        let delete = Delete::many(entity).filter(Expr::col(Column::Id).eq(1));\n        // Execute the delete statement\n        assert_eq!(delete.exec(db).await?.rows_affected, 1);\n        assert_eq!(select.one(db).await?, None);\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/embedding_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, DerivePartialModel, entity::prelude::*, entity::*};\nuse serde_json::json;\n\n#[cfg(feature = \"postgres-vector\")]\nmod test {\n\n    #[sea_orm_macros::test]\n    async fn main() -> Result<(), DbErr> {\n        let ctx = TestContext::new(\"embedding_tests\").await;\n        create_embedding_table(&ctx.db).await?;\n        insert_embedding(&ctx.db).await?;\n        update_embedding(&ctx.db).await?;\n        select_embedding(&ctx.db).await?;\n        ctx.delete().await;\n\n        Ok(())\n    }\n\n    pub async fn insert_embedding(db: &DatabaseConnection) -> Result<(), DbErr> {\n        use embedding::*;\n\n        assert_eq!(\n            Model {\n                id: 1,\n                embedding: PgVector::from(vec![1.]),\n            }\n            .into_active_model()\n            .insert(db)\n            .await?,\n            Model {\n                id: 1,\n                embedding: PgVector::from(vec![1.]),\n            }\n        );\n\n        assert_eq!(\n            Model {\n                id: 2,\n                embedding: PgVector::from(vec![1., 2.]),\n            }\n            .into_active_model()\n            .insert(db)\n            .await?,\n            Model {\n                id: 2,\n                embedding: PgVector::from(vec![1., 2.]),\n            }\n        );\n\n        assert_eq!(\n            Model {\n                id: 3,\n                embedding: PgVector::from(vec![1., 2., 3.]),\n            }\n            .into_active_model()\n            .insert(db)\n            .await?,\n            Model {\n                id: 3,\n                embedding: PgVector::from(vec![1., 2., 3.]),\n            }\n        );\n\n        assert_eq!(\n            Entity::find_by_id(3).into_json().one(db).await?,\n            Some(json!({\n                \"id\": 3,\n                \"embedding\": [1., 2., 3.],\n            }))\n        );\n\n        Ok(())\n    }\n\n    pub async fn update_embedding(db: &DatabaseConnection) -> Result<(), DbErr> {\n        use embedding::*;\n\n        let model = Entity::find_by_id(1).one(db).await?.unwrap();\n\n        ActiveModel {\n            embedding: Set(PgVector::from(vec![10.])),\n            ..model.into_active_model()\n        }\n        .update(db)\n        .await?;\n\n        ActiveModel {\n            id: Unchanged(3),\n            embedding: Set(PgVector::from(vec![10., 20., 30.])),\n        }\n        .update(db)\n        .await?;\n\n        Ok(())\n    }\n\n    pub async fn select_embedding(db: &DatabaseConnection) -> Result<(), DbErr> {\n        use embedding::*;\n\n        #[derive(DerivePartialModel, Debug, PartialEq)]\n        #[sea_orm(entity = \"Entity\")]\n        struct PartialSelectResult {\n            embedding: PgVector,\n        }\n\n        let result = Entity::find_by_id(1)\n            .into_partial_model::<PartialSelectResult>()\n            .one(db)\n            .await?;\n\n        assert_eq!(\n            result,\n            Some(PartialSelectResult {\n                embedding: PgVector::from(vec![10.]),\n            })\n        );\n\n        let result = Entity::find_by_id(2)\n            .into_partial_model::<PartialSelectResult>()\n            .one(db)\n            .await?;\n\n        assert_eq!(\n            result,\n            Some(PartialSelectResult {\n                embedding: PgVector::from(vec![1., 2.]),\n            })\n        );\n\n        let result = Entity::find_by_id(3)\n            .into_partial_model::<PartialSelectResult>()\n            .one(db)\n            .await?;\n\n        assert_eq!(\n            result,\n            Some(PartialSelectResult {\n                embedding: PgVector::from(vec![10., 20., 30.]),\n            })\n        );\n\n        Ok(())\n    }\n}\n"
  },
  {
    "path": "tests/empty_insert_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\nmod crud;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\npub use sea_orm::{\n    DatabaseConnection, DbBackend, EntityName, ExecResult, entity::*, error::DbErr, tests_cfg,\n};\n\npub use crud::*;\n// use common::bakery_chain::*;\nuse sea_orm::{DbConn, TryInsertResult};\n\n#[sea_orm_macros::test]\nasync fn main() {\n    let ctx = TestContext::new(\"bakery_chain_empty_insert_tests\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n    test(&ctx.db).await;\n    ctx.delete().await;\n}\n\npub async fn test(db: &DbConn) {\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n\n    let res = Bakery::insert(seaside_bakery).exec(db).await;\n\n    assert!(res.is_ok());\n\n    let double_seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        id: Set(1),\n        ..Default::default()\n    };\n\n    let conflict_insert = Bakery::insert_many([double_seaside_bakery])\n        .on_conflict_do_nothing()\n        .exec(db)\n        .await;\n\n    assert!(matches!(conflict_insert, Ok(TryInsertResult::Conflicted)));\n\n    let empty_insert = Bakery::insert_many(std::iter::empty::<bakery::ActiveModel>())\n        .exec(db)\n        .await\n        .unwrap();\n\n    assert!(empty_insert.last_insert_id.is_none());\n}\n"
  },
  {
    "path": "tests/entity_loader_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{\n    TestContext,\n    bakery_chain::{create_tables, seed_data},\n    bakery_dense::*,\n    setup::*,\n};\nuse sea_orm::{DbConn, DbErr, EntityLoaderTrait, RuntimeErr, Set, prelude::*, query::*};\n\n#[sea_orm_macros::test]\nasync fn cake_entity_loader() -> Result<(), DbErr> {\n    use common::bakery_dense::prelude::*;\n    use sea_orm::compound::EntityLoaderTrait;\n\n    let ctx = TestContext::new(\"test_cake_entity_loader\").await;\n    let db = &ctx.db;\n    create_tables(db).await?;\n\n    let bakery_1 = insert_bakery(db, \"SeaSide Bakery\").await?;\n    let bakery_2 = insert_bakery(db, \"LakeSide Bakery\").await?;\n\n    let baker_1 = insert_baker(db, \"Jane\", bakery_1.id).await?;\n    let baker_2 = insert_baker(db, \"Peter\", bakery_1.id).await?;\n    let baker_3 = insert_baker(db, \"Fred\", bakery_2.id).await?; // does not make cake\n\n    let cake_1 = insert_cake(db, \"Cheesecake\", Some(bakery_1.id)).await?;\n    let cake_2 = insert_cake(db, \"Coffee\", Some(bakery_1.id)).await?;\n    let cake_3 = insert_cake(db, \"Chiffon\", Some(bakery_2.id)).await?;\n    let cake_4 = insert_cake(db, \"Apple Pie\", None).await?; // no one makes apple pie\n\n    insert_cake_baker(db, baker_1.id, cake_1.id).await?;\n    insert_cake_baker(db, baker_1.id, cake_2.id).await?;\n    insert_cake_baker(db, baker_2.id, cake_2.id).await?;\n    insert_cake_baker(db, baker_2.id, cake_3.id).await?;\n\n    let cakes = Cake::load().all(db).await?;\n    assert_eq!(\n        cakes,\n        [\n            cake_1.clone(),\n            cake_2.clone(),\n            cake_3.clone(),\n            cake_4.clone(),\n        ]\n    );\n\n    let cakes = Cake::load()\n        .filter(Cake::COLUMN.name.like(\"Ch%\"))\n        .all(db)\n        .await?;\n    assert_eq!(cakes, [cake_1.clone(), cake_3.clone()]);\n    assert!(cakes[0].bakers.is_empty());\n    assert!(cakes[0].bakery.is_unloaded());\n\n    assert_eq!(\n        Cake::load()\n            .filter(Cake::COLUMN.name.like(\"Ch%\"))\n            .order_by_desc(Cake::COLUMN.name)\n            .one(db)\n            .await?\n            .unwrap(),\n        cake_3\n    );\n\n    let cakes = Cake::load().with(Bakery).all(db).await?;\n    assert_eq!(\n        cakes,\n        [\n            cake_1.clone(),\n            cake_2.clone(),\n            cake_3.clone(),\n            cake_4.clone(),\n        ]\n    );\n    assert_eq!(cakes[0].bakery.as_ref().unwrap(), &bakery_1);\n    assert_eq!(cakes[1].bakery.as_ref().unwrap(), &bakery_1);\n    assert_eq!(cakes[2].bakery.as_ref().unwrap(), &bakery_2);\n    assert_eq!(cakes[3].bakery, None);\n\n    // low-level API\n    assert_eq!(\n        cakes,\n        cake::EntityLoader::load(\n            Cake::load().all(db).await?,\n            &cake::EntityLoaderWith {\n                bakery: true,\n                lineitems: false,\n                bakers: false,\n            },\n            &Default::default(),\n            db\n        )\n        .await?\n    );\n\n    let cake_with_bakery = Cake::load()\n        .filter(Cake::COLUMN.name.eq(\"Cheesecake\"))\n        .with(Bakery)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(cake_with_bakery, cake_1);\n    assert_eq!(cake_with_bakery.bakery.unwrap(), bakery_1);\n    assert!(cake_with_bakery.bakers.is_empty());\n\n    assert_eq!(\n        Cake::load()\n            .filter_by_id(cake_2.id)\n            .with(Bakery)\n            .one(db)\n            .await?\n            .unwrap(),\n        {\n            let mut cake_2 = cake_2.clone().into_ex();\n            cake_2.bakery = HasOne::loaded(bakery_1.clone());\n            cake_2\n        }\n    );\n\n    let cakes = Cake::load().with(Bakery).with(Baker).all(db).await?;\n    assert_eq!(\n        cakes,\n        [\n            cake_1.clone(),\n            cake_2.clone(),\n            cake_3.clone(),\n            cake_4.clone()\n        ]\n    );\n    assert_eq!(cakes[0].bakery.as_ref().unwrap(), &bakery_1);\n    assert_eq!(cakes[1].bakery.as_ref().unwrap(), &bakery_1);\n    assert_eq!(cakes[2].bakery.as_ref().unwrap(), &bakery_2);\n    assert_eq!(cakes[3].bakery, None);\n    assert_eq!(cakes[0].bakers, [baker_1.clone()]);\n    assert_eq!(cakes[1].bakers, [baker_1.clone(), baker_2.clone()]);\n    assert_eq!(cakes[2].bakers, [baker_2.clone()]);\n    assert!(cakes[3].bakers.is_empty());\n\n    let cake_with_bakery_baker = Cake::load()\n        .filter(Cake::COLUMN.name.eq(\"Chiffon\"))\n        .with(Bakery)\n        .with(Baker)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(cake_with_bakery_baker, cake_3);\n    assert_eq!(cake_with_bakery_baker.bakery.unwrap(), bakery_2);\n    assert_eq!(cake_with_bakery_baker.bakers, [baker_2.clone()]);\n\n    // start again from baker\n\n    let bakers = baker::Entity::find().all(db).await?;\n    assert_eq!(bakers, [baker_1.clone(), baker_2.clone(), baker_3.clone()]);\n\n    let bakers = baker::Entity::load().with(cake::Entity).all(db).await?;\n    assert_eq!(bakers[0].id, baker_1.id);\n    assert_eq!(bakers[1].id, baker_2.id);\n    assert_eq!(bakers[2].id, baker_3.id);\n    assert_eq!(bakers[0].cakes, [cake_1.clone(), cake_2.clone()]);\n    assert_eq!(bakers[1].cakes, [cake_2.clone(), cake_3.clone()]);\n    assert!(bakers[2].cakes.is_empty());\n\n    // alternative API\n    assert_eq!(\n        bakers,\n        baker::EntityLoader::load(\n            baker::Entity::load().all(db).await?,\n            &baker::EntityLoaderWith {\n                cakes: true,\n                bakery: false,\n            },\n            &Default::default(),\n            db\n        )\n        .await?\n    );\n\n    // 2 many\n    // bakery -> baker\n    //        -> cake\n\n    let bakeries = bakery::Entity::load()\n        .with(Baker)\n        .with(cake::Entity)\n        .order_by_asc(bakery::Column::Id)\n        .all(db)\n        .await?;\n\n    assert_eq!(bakeries[0].bakers, [baker_1.clone(), baker_2.clone()]);\n    assert_eq!(bakeries[1].bakers, [baker_3.clone()]);\n    assert_eq!(bakeries[0].cakes, [cake_1.clone(), cake_2.clone()]);\n    assert_eq!(bakeries[1].cakes, [cake_3.clone()]);\n\n    // nested\n    // cake -> bakery -> baker\n\n    let cakes = Cake::load().with((Bakery, Baker)).all(db).await?;\n    assert_eq!(cakes[0].bakery.as_ref().unwrap().name, bakery_1.name);\n    assert_eq!(cakes[1].bakery.as_ref().unwrap().name, bakery_1.name);\n    assert_eq!(cakes[2].bakery.as_ref().unwrap().name, bakery_2.name);\n    assert_eq!(cakes[3].bakery, None);\n    assert_eq!(\n        cakes[0].bakery.as_ref().unwrap().bakers,\n        [baker_1.clone(), baker_2.clone()]\n    );\n    assert_eq!(\n        cakes[1].bakery.as_ref().unwrap().bakers,\n        [baker_1.clone(), baker_2.clone()]\n    );\n    assert_eq!(cakes[2].bakery.as_ref().unwrap().bakers, [baker_3.clone()]);\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn entity_loader_join_three() {\n    let ctx = TestContext::new(\"entity_loader_join_three\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    let db = &ctx.db;\n\n    // verify basics\n    let cake_13 = cake::Entity::find_by_id(13).one(db).await.unwrap().unwrap();\n    let cake_15 = cake::Entity::find_by_id(15).one(db).await.unwrap().unwrap();\n\n    // new find by key feature\n    #[rustfmt::skip]\n    assert_eq!(cake::Entity::find_by_name(\"Cheesecake\").one(db).await.unwrap().unwrap().id, 13);\n    #[rustfmt::skip]\n    assert_eq!(cake::Entity::find_by_name(\"Chocolate\").one(db).await.unwrap().unwrap().id, 15);\n\n    // new load by key feature\n    #[rustfmt::skip]\n    assert_eq!(cake::Entity::load().filter_by_name(\"Cheesecake\").one(db).await.unwrap().unwrap().id, 13);\n    #[rustfmt::skip]\n    assert_eq!(cake::Entity::load().filter_by_name(\"Chocolate\").one(db).await.unwrap().unwrap().id, 15);\n\n    let lineitems = lineitem::Entity::load().all(db).await.unwrap();\n    assert_eq!(lineitems[0].cake_id, 13);\n    assert_eq!(lineitems[1].cake_id, 15);\n    assert_eq!(lineitems[0].order_id, 101);\n    assert_eq!(lineitems[1].order_id, 101);\n\n    // lineitem join order\n    let lineitems = lineitem::Entity::load()\n        .with(order::Entity)\n        .all(db)\n        .await\n        .unwrap();\n    assert_eq!(lineitems[0].order.as_ref().unwrap().id, 101);\n    assert_eq!(lineitems[0].order.as_ref().unwrap().total, 10.into());\n    assert_eq!(lineitems[1].order.as_ref().unwrap().id, 101);\n    assert_eq!(lineitems[1].order.as_ref().unwrap().total, 10.into());\n\n    // lineitem join cake\n    let lineitems = lineitem::Entity::load()\n        .with(cake::Entity)\n        .all(db)\n        .await\n        .unwrap();\n    assert_eq!(lineitems[0].cake.as_ref().unwrap().id, 13);\n    assert_eq!(lineitems[0].cake.as_ref().unwrap().name, \"Cheesecake\");\n    assert_eq!(lineitems[1].cake.as_ref().unwrap().id, 15);\n    assert_eq!(lineitems[1].cake.as_ref().unwrap().name, \"Chocolate\");\n\n    // lineitem join order + cake\n    let lineitems = lineitem::Entity::load()\n        .with(order::Entity)\n        .with(cake::Entity)\n        .all(db)\n        .await\n        .unwrap();\n    assert_eq!(lineitems[0].order.as_ref().unwrap().id, 101);\n    assert_eq!(lineitems[0].order.as_ref().unwrap().total, 10.into());\n    assert_eq!(lineitems[1].order.as_ref().unwrap().id, 101);\n    assert_eq!(lineitems[1].order.as_ref().unwrap().total, 10.into());\n    assert_eq!(lineitems[0].cake.as_ref().unwrap().id, 13);\n    assert_eq!(lineitems[0].cake.as_ref().unwrap().name, \"Cheesecake\");\n    assert_eq!(lineitems[1].cake.as_ref().unwrap().id, 15);\n    assert_eq!(lineitems[1].cake.as_ref().unwrap().name, \"Chocolate\");\n\n    // 1 layer select\n    let order = order::Entity::load()\n        .with(customer::Entity)\n        .order_by_asc(order::Column::Id)\n        .one(db)\n        .await\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(\n        order,\n        order::ModelEx {\n            id: 101,\n            total: 10.into(),\n            bakery_id: 42,\n            customer_id: 11,\n            placed_at: \"2020-01-01 00:00:00Z\".parse().unwrap(),\n            bakery: HasOne::Unloaded,\n            customer: HasOne::loaded(customer::Model {\n                id: 11,\n                name: \"Bob\".to_owned(),\n                notes: Some(\"Sweet tooth\".into()),\n            }),\n            lineitems: HasMany::Unloaded,\n        }\n    );\n\n    // 1 layer select\n    let order = order::Entity::load()\n        .with(bakery::Entity)\n        .with(customer::Entity)\n        .order_by_asc(order::Column::Id)\n        .one(db)\n        .await\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(\n        order,\n        order::ModelEx {\n            id: 101,\n            total: 10.into(),\n            bakery_id: 42,\n            customer_id: 11,\n            placed_at: \"2020-01-01 00:00:00Z\".parse().unwrap(),\n            bakery: HasOne::loaded(bakery::Model {\n                id: 42,\n                name: \"cool little bakery\".into(),\n                profit_margin: 4.1,\n            }),\n            customer: HasOne::loaded(customer::ModelEx {\n                id: 11,\n                name: \"Bob\".to_owned(),\n                notes: Some(\"Sweet tooth\".into()),\n                orders: HasMany::Unloaded,\n            }),\n            lineitems: HasMany::Unloaded,\n        }\n    );\n\n    // 1 layer select\n    let order = order::Entity::load()\n        .with(customer::Entity)\n        .with(lineitem::Entity)\n        .order_by_asc(order::Column::Id)\n        .one(db)\n        .await\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(\n        order,\n        order::ModelEx {\n            id: 101,\n            total: 10.into(),\n            bakery_id: 42,\n            customer_id: 11,\n            placed_at: \"2020-01-01 00:00:00Z\".parse().unwrap(),\n            bakery: HasOne::Unloaded,\n            customer: HasOne::loaded(customer::ModelEx {\n                id: 11,\n                name: \"Bob\".to_owned(),\n                notes: Some(\"Sweet tooth\".into()),\n                orders: HasMany::Unloaded,\n            }),\n            lineitems: HasMany::Loaded(vec![\n                lineitem::ModelEx {\n                    id: 1,\n                    price: 2.into(),\n                    quantity: 2,\n                    order_id: 101,\n                    cake_id: 13,\n                    order: HasOne::Unloaded,\n                    cake: HasOne::Unloaded,\n                },\n                lineitem::ModelEx {\n                    id: 2,\n                    price: 3.into(),\n                    quantity: 2,\n                    order_id: 101,\n                    cake_id: 15,\n                    order: HasOne::Unloaded,\n                    cake: HasOne::Unloaded,\n                }\n            ]),\n        }\n    );\n\n    // 2 layers\n    let order = order::Entity::load()\n        .with(customer::Entity)\n        .with((lineitem::Entity, cake::Entity))\n        .order_by_asc(order::Column::Id)\n        .one(db)\n        .await\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(\n        order,\n        order::ModelEx {\n            id: 101,\n            total: 10.into(),\n            bakery_id: 42,\n            customer_id: 11,\n            placed_at: \"2020-01-01 00:00:00Z\".parse().unwrap(),\n            bakery: HasOne::Unloaded,\n            customer: HasOne::loaded(customer::Model {\n                id: 11,\n                name: \"Bob\".to_owned(),\n                notes: Some(\"Sweet tooth\".into()),\n            }),\n            lineitems: HasMany::Loaded(vec![\n                lineitem::ModelEx {\n                    id: 1,\n                    price: 2.into(),\n                    quantity: 2,\n                    order_id: 101,\n                    cake_id: 13,\n                    order: HasOne::Unloaded,\n                    cake: HasOne::loaded(cake_13),\n                },\n                lineitem::ModelEx {\n                    id: 2,\n                    price: 3.into(),\n                    quantity: 2,\n                    order_id: 101,\n                    cake_id: 15,\n                    order: HasOne::Unloaded,\n                    cake: HasOne::loaded(cake_15),\n                }\n            ]),\n        }\n    );\n}\n\n#[sea_orm_macros::test]\nasync fn entity_loader_self_join() -> Result<(), DbErr> {\n    use common::film_store::{staff, staff_compact, staff_mono};\n\n    let ctx = TestContext::new(\"entity_loader_self_join\").await;\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(staff::Entity)\n        .apply(db)\n        .await?;\n\n    let alan = staff::ActiveModel {\n        name: Set(\"Alan\".into()),\n        reports_to_id: Set(None),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    staff::ActiveModel {\n        name: Set(\"Ben\".into()),\n        reports_to_id: Set(Some(alan.id)),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    staff::ActiveModel {\n        name: Set(\"Alice\".into()),\n        reports_to_id: Set(Some(alan.id)),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    staff::ActiveModel {\n        name: Set(\"Elle\".into()),\n        reports_to_id: Set(None),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    // load belongs_to\n\n    let staff = staff::Entity::load()\n        .with(staff::Relation::ReportsTo)\n        .all(db)\n        .await?;\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(staff[0].reports_to, None);\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(staff[2].reports_to.as_ref().unwrap().name, \"Alan\");\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(staff[3].reports_to, None);\n\n    // load belongs_to reverse\n\n    let staff = staff::Entity::load()\n        .with(staff::Relation::Manages)\n        .all(db)\n        .await?;\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(staff[0].manages[0].name, \"Ben\");\n    assert_eq!(staff[0].manages[1].name, \"Alice\");\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert!(staff[1].manages.is_empty());\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert!(staff[2].manages.is_empty());\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert!(staff[3].manages.is_empty());\n\n    // load both sides\n\n    let staff = staff::Entity::load()\n        .with(staff::Relation::ReportsTo)\n        .with(staff::Relation::Manages)\n        .all(db)\n        .await?;\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(staff[0].reports_to, None);\n    assert_eq!(staff[0].manages[0].name, \"Ben\");\n    assert_eq!(staff[0].manages[1].name, \"Alice\");\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n    assert!(staff[1].manages.is_empty());\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(staff[2].reports_to.as_ref().unwrap().name, \"Alan\");\n    assert!(staff[2].manages.is_empty());\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(staff[3].reports_to, None);\n    assert!(staff[3].manages.is_empty());\n\n    // test self_ref on model without reverse relation (not dual)\n\n    let staff = staff_mono::Entity::load()\n        .filter_by_id(2)\n        .with(staff_mono::Relation::ReportsTo)\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(staff.name, \"Ben\");\n    assert_eq!(\n        staff.reports_to.unwrap(),\n        staff_mono::Entity::find_by_id(alan.id)\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    // test self_ref on compact_model\n\n    let staff = staff_compact::Entity::load()\n        .with(staff_compact::Relation::ReportsTo)\n        .with(staff_compact::Relation::Manages)\n        .all(db)\n        .await?;\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(staff[0].reports_to, None);\n    assert_eq!(staff[0].manages[0].name, \"Ben\");\n    assert_eq!(staff[0].manages[1].name, \"Alice\");\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n    assert!(staff[1].manages.is_empty());\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(staff[2].reports_to.as_ref().unwrap().name, \"Alan\");\n    assert!(staff[2].manages.is_empty());\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(staff[3].reports_to, None);\n    assert!(staff[3].manages.is_empty());\n\n    // test pagination on loader\n\n    let mut pager = staff::Entity::load()\n        .with(staff::Relation::ReportsTo)\n        .order_by_asc(staff::COLUMN.id)\n        .paginate(db, 2);\n\n    let staff = pager.fetch_and_next().await?.unwrap();\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(staff[0].reports_to, None);\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(staff[1].reports_to.as_ref().unwrap().name, \"Alan\");\n\n    let staff = pager.fetch_and_next().await?.unwrap();\n\n    assert_eq!(staff[0].name, \"Alice\");\n    assert_eq!(staff[0].reports_to.as_ref().unwrap().name, \"Alan\");\n\n    assert_eq!(staff[1].name, \"Elle\");\n    assert_eq!(staff[1].reports_to, None);\n\n    assert!(pager.fetch_and_next().await?.is_none());\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn entity_loader_self_join_via() -> Result<(), DbErr> {\n    use common::blogger::{profile, user, user_follower, user_mono};\n\n    let ctx = TestContext::new(\"test_entity_loader_self_join_via\").await;\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(profile::Entity)\n        .register(user::Entity)\n        .register(user_follower::Entity)\n        .apply(db)\n        .await?;\n\n    let alice = user::ActiveModel::builder()\n        .set_name(\"Alice\")\n        .set_email(\"@1\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Alice.jpg\"))\n        .insert(db)\n        .await?;\n\n    let bob = user::ActiveModel::builder()\n        .set_name(\"Bob\")\n        .set_email(\"@2\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Bob.jpg\"))\n        .insert(db)\n        .await?;\n\n    let sam = user::ActiveModel::builder()\n        .set_name(\"Sam\")\n        .set_email(\"@3\")\n        .set_profile(profile::ActiveModel::builder().set_picture(\"Sam.jpg\"))\n        .insert(db)\n        .await?;\n\n    user_follower::ActiveModel {\n        user_id: Set(alice.id),\n        follower_id: Set(bob.id),\n    }\n    .insert(db)\n    .await?;\n\n    user_follower::ActiveModel {\n        user_id: Set(alice.id),\n        follower_id: Set(sam.id),\n    }\n    .insert(db)\n    .await?;\n\n    user_follower::ActiveModel {\n        user_id: Set(bob.id),\n        follower_id: Set(sam.id),\n    }\n    .insert(db)\n    .await?;\n\n    // test user + follower\n\n    let users = user::Entity::load()\n        .with(user_follower::Entity)\n        .all(db)\n        .await?;\n\n    assert_eq!(users[0].name, alice.name);\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0].name, bob.name);\n    assert_eq!(users[0].followers[1].name, sam.name);\n\n    assert_eq!(users[1].name, bob.name);\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0].name, sam.name);\n\n    assert_eq!(users[2].name, sam.name);\n    assert!(users[2].followers.is_empty());\n\n    // test user + follower, but on an Entity without reverse relation (following)\n\n    let users = user_mono::Entity::load()\n        .with(user_follower::Entity)\n        .all(db)\n        .await?;\n\n    assert_eq!(users[0].name, alice.name);\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0].name, bob.name);\n    assert_eq!(users[0].followers[1].name, sam.name);\n\n    assert_eq!(users[1].name, bob.name);\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0].name, sam.name);\n\n    assert_eq!(users[2].name, sam.name);\n    assert!(users[2].followers.is_empty());\n\n    // test user + follower + following (both sides)\n\n    let users = user::Entity::load()\n        .with(user::Follower)\n        .with(user::Following)\n        .all(db)\n        .await?;\n\n    assert_eq!(users[0].name, alice.name);\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0].name, bob.name);\n    assert_eq!(users[0].followers[1].name, sam.name);\n    assert!(users[0].following.is_empty());\n\n    assert_eq!(users[1].name, bob.name);\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0].name, sam.name);\n    assert_eq!(users[1].following.len(), 1);\n    assert_eq!(users[1].following[0].name, alice.name);\n\n    assert_eq!(users[2].name, sam.name);\n    assert!(users[2].followers.is_empty());\n    assert_eq!(users[2].following.len(), 2);\n    assert_eq!(users[2].following[0].name, alice.name);\n    assert_eq!(users[2].following[1].name, bob.name);\n\n    // test user + profile\n\n    let users = user::Entity::load()\n        .with(profile::Entity)\n        .with(user_follower::Entity)\n        .all(db)\n        .await?;\n\n    assert_eq!(users[0].profile, alice.profile);\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0].name, bob.name);\n    assert_eq!(users[0].followers[1].name, sam.name);\n\n    assert_eq!(users[1].profile, bob.profile);\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0].name, sam.name);\n\n    assert_eq!(users[2].profile, sam.profile);\n    assert!(users[2].followers.is_empty());\n\n    // test user + profile with nested user + profile\n\n    let users = user::Entity::load()\n        .with(profile::Entity)\n        .with((user::Follower, profile::Entity))\n        .all(db)\n        .await?;\n\n    assert_eq!(users[0].profile, alice.profile);\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0], bob);\n    assert_eq!(users[0].followers[1], sam);\n\n    assert_eq!(users[1].profile, bob.profile);\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0], sam);\n\n    assert_eq!(users[2].profile, sam.profile);\n    assert!(users[2].followers.is_empty());\n\n    // test all: user profile + follower profile + following profile\n\n    let users = user::Entity::load()\n        .with(profile::Entity)\n        .with((user::Follower, profile::Entity))\n        .with((user::Following, profile::Entity))\n        .all(db)\n        .await?;\n\n    assert_eq!(users[0].profile, alice.profile);\n    assert_eq!(users[0].followers.len(), 2);\n    assert_eq!(users[0].followers[0], bob);\n    assert_eq!(users[0].followers[1], sam);\n    assert!(users[0].following.is_empty());\n\n    assert_eq!(users[1].profile, bob.profile);\n    assert_eq!(users[1].followers.len(), 1);\n    assert_eq!(users[1].followers[0], sam);\n    assert_eq!(users[1].following.len(), 1);\n    assert_eq!(users[1].following[0], alice);\n\n    assert_eq!(users[2].profile, sam.profile);\n    assert!(users[2].followers.is_empty());\n    assert_eq!(users[2].following.len(), 2);\n    assert_eq!(users[2].following[0], alice);\n    assert_eq!(users[2].following[1], bob);\n\n    // test nested loading, but left right swapped\n\n    let alice_profile = profile::Entity::load()\n        .filter_by_id(alice.profile.as_ref().unwrap().id)\n        .with(sea_orm::compound::EntityLoaderWithSelf(\n            user::Entity,\n            user::Follower,\n        ))\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(\n        alice_profile.picture,\n        alice.profile.as_ref().unwrap().picture\n    );\n    assert_eq!(alice_profile.user.as_ref().unwrap().followers.len(), 2);\n    assert_eq!(\n        alice_profile.user.as_ref().unwrap().followers[0].name,\n        bob.name\n    );\n    assert_eq!(\n        alice_profile.user.as_ref().unwrap().followers[1].name,\n        sam.name\n    );\n\n    let sam_profile = profile::Entity::load()\n        .filter_by_id(sam.profile.as_ref().unwrap().id)\n        .with(sea_orm::compound::EntityLoaderWithSelfRev(\n            user::Entity,\n            user::Following,\n        ))\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(sam_profile.picture, sam.profile.as_ref().unwrap().picture);\n    assert_eq!(sam_profile.user.as_ref().unwrap().following.len(), 2);\n    assert_eq!(\n        sam_profile.user.as_ref().unwrap().following[0].name,\n        alice.name\n    );\n    assert_eq!(\n        sam_profile.user.as_ref().unwrap().following[1].name,\n        bob.name\n    );\n\n    Ok(())\n}\n\npub async fn insert_bakery(db: &DbConn, name: &str) -> Result<bakery::Model, DbErr> {\n    bakery::ActiveModel {\n        name: Set(name.to_owned()),\n        profit_margin: Set(1.0),\n        ..Default::default()\n    }\n    .insert(db)\n    .await\n}\n\npub async fn insert_baker(db: &DbConn, name: &str, bakery_id: i32) -> Result<baker::Model, DbErr> {\n    baker::ActiveModel {\n        name: Set(name.to_owned()),\n        contact_details: Set(serde_json::json!({})),\n        bakery_id: Set(Some(bakery_id)),\n        ..Default::default()\n    }\n    .insert(db)\n    .await\n}\n\npub async fn insert_cake(\n    db: &DbConn,\n    name: &str,\n    bakery_id: Option<i32>,\n) -> Result<cake::Model, DbErr> {\n    cake::ActiveModel {\n        name: Set(name.to_owned()),\n        price: Set(rust_decimal::Decimal::ONE),\n        gluten_free: Set(false),\n        bakery_id: Set(bakery_id),\n        ..Default::default()\n    }\n    .insert(db)\n    .await\n}\n\npub async fn insert_cake_baker(\n    db: &DbConn,\n    baker_id: i32,\n    cake_id: i32,\n) -> Result<cakes_bakers::Model, DbErr> {\n    cakes_bakers::ActiveModel {\n        cake_id: Set(cake_id),\n        baker_id: Set(baker_id),\n    }\n    .insert(db)\n    .await\n}\n"
  },
  {
    "path": "tests/enum_primary_key_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{\n    ActiveEnum as ActiveEnumTrait, DatabaseConnection,\n    entity::prelude::*,\n    entity::*,\n    sea_query::{BinOper, Expr},\n};\nuse sea_query::ExprTrait;\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"enum_primary_key_tests\").await;\n    create_tea_enum(&ctx.db).await?;\n    create_teas_table(&ctx.db).await?;\n    insert_teas(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn insert_teas(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use teas::*;\n\n    let model = Model {\n        id: Tea::EverydayTea,\n        category: None,\n        color: None,\n    };\n\n    assert_eq!(\n        model,\n        ActiveModel {\n            id: Set(Tea::EverydayTea),\n            category: Set(None),\n            color: Set(None),\n        }\n        .insert(db)\n        .await?\n    );\n    assert_eq!(model, Entity::find().one(db).await?.unwrap());\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.is_not_null())\n            .filter(Column::Category.is_null())\n            .filter(Column::Color.is_null())\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    // UNIQUE constraint failed\n    assert!(\n        ActiveModel {\n            id: Set(Tea::EverydayTea),\n            category: Set(Some(Category::Big)),\n            color: Set(Some(Color::Black)),\n        }\n        .insert(db)\n        .await\n        .is_err()\n    );\n\n    // UNIQUE constraint failed\n    assert!(\n        Entity::insert(ActiveModel {\n            id: Set(Tea::EverydayTea),\n            category: Set(Some(Category::Big)),\n            color: Set(Some(Color::Black)),\n        })\n        .exec(db)\n        .await\n        .is_err()\n    );\n\n    let _ = ActiveModel {\n        category: Set(Some(Category::Big)),\n        color: Set(Some(Color::Black)),\n        ..model.into_active_model()\n    }\n    .save(db)\n    .await?;\n\n    let model = Entity::find().one(db).await?.unwrap();\n    assert_eq!(\n        model,\n        Model {\n            id: Tea::EverydayTea,\n            category: Some(Category::Big),\n            color: Some(Color::Black),\n        }\n    );\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.eq(Tea::EverydayTea))\n            .filter(Column::Category.eq(Category::Big))\n            .filter(Column::Color.eq(Color::Black))\n            .one(db)\n            .await?\n            .unwrap()\n    );\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Expr::col(Column::Id).binary(\n                BinOper::In,\n                Expr::tuple([ActiveEnumTrait::as_enum(&Tea::EverydayTea)])\n            ))\n            .one(db)\n            .await?\n            .unwrap()\n    );\n    // Equivalent to the above.\n    assert_eq!(\n        model,\n        Entity::find()\n            .filter(Column::Id.is_in([Tea::EverydayTea]))\n            .one(db)\n            .await?\n            .unwrap()\n    );\n\n    let res = model.delete(db).await?;\n\n    assert_eq!(res.rows_affected, 1);\n    assert_eq!(Entity::find().one(db).await?, None);\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/event_trigger_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{\n    TestContext,\n    features::{\n        event_trigger::{Event, Events},\n        *,\n    },\n    setup::*,\n};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\n\n#[sea_orm_macros::test]\n#[cfg(all(feature = \"sqlx-postgres\", feature = \"postgres-array\"))]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"event_trigger_tests\").await;\n    create_event_trigger_table(&ctx.db).await?;\n    insert_event_trigger(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn insert_event_trigger(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let event_trigger = event_trigger::Model {\n        id: 1,\n        events: Events(\n            [\"A\", \"B\", \"C\"]\n                .into_iter()\n                .map(|s| Event(s.to_owned()))\n                .collect(),\n        ),\n    };\n\n    let result = event_trigger.clone().into_active_model().insert(db).await?;\n\n    assert_eq!(result, event_trigger);\n\n    let model = event_trigger::Entity::find()\n        .filter(event_trigger::Column::Id.eq(event_trigger.id))\n        .one(db)\n        .await?;\n\n    assert_eq!(model, Some(event_trigger));\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/execute_unprepared_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{ConnectionTrait, DatabaseConnection, entity::prelude::*};\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"execute_unprepared_tests\").await;\n    create_insert_default_table(&ctx.db).await?;\n    execute_unprepared(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn execute_unprepared(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    db.execute_unprepared(\n        [\n            \"INSERT INTO insert_default (id) VALUES (1), (2), (3), (4), (5)\",\n            \"DELETE FROM insert_default WHERE id % 2 = 0\",\n        ]\n        .join(\";\")\n        .as_str(),\n    )\n    .await?;\n\n    assert_eq!(\n        Entity::find().all(db).await?,\n        [Model { id: 1 }, Model { id: 3 }, Model { id: 5 }]\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/exists_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\npub use sea_orm::entity::*;\npub use sea_orm::{ConnectionTrait, QueryFilter, QueryOrder, QuerySelect, SelectExt};\n\n#[sea_orm_macros::test]\npub async fn exists_with_no_result() {\n    let ctx = TestContext::new(\"exists_with_no_result\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let exists = Bakery::find().exists(&ctx.db).await.unwrap();\n    assert_eq!(exists, false);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn exists_with_result() {\n    let ctx = TestContext::new(\"exists_with_result\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let _bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let exists = Bakery::find().exists(&ctx.db).await.unwrap();\n    assert_eq!(exists, true);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn exists_with_filter_no_result() {\n    let ctx = TestContext::new(\"exists_with_filter_no_result\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let _bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let exists = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Nonexistent\"))\n        .exists(&ctx.db)\n        .await\n        .unwrap();\n    assert_eq!(exists, false);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn exists_with_filter_has_result() {\n    let ctx = TestContext::new(\"exists_with_filter_has_result\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let _bakery1 = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let _bakery2 = bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let exists = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"SeaSide\"))\n        .exists(&ctx.db)\n        .await\n        .unwrap();\n    assert_eq!(exists, true);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn exists_with_complex_query() {\n    let ctx = TestContext::new(\"exists_with_complex_query\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let _bakery1 = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let _bakery2 = bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let _bakery3 = bakery::ActiveModel {\n        name: Set(\"Low Profit Bakery\".to_owned()),\n        profit_margin: Set(5.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    // Test with complex filter - exists bakery with profit margin > 12\n    let exists = Bakery::find()\n        .filter(bakery::Column::ProfitMargin.gt(12.0))\n        .exists(&ctx.db)\n        .await\n        .unwrap();\n    assert_eq!(exists, true);\n\n    // Test with complex filter - exists bakery with profit margin > 20\n    let exists = Bakery::find()\n        .filter(bakery::Column::ProfitMargin.gt(20.0))\n        .exists(&ctx.db)\n        .await\n        .unwrap();\n    assert_eq!(exists, false);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn exists_with_joins() {\n    let ctx = TestContext::new(\"exists_with_joins\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n    create_cake_table(&ctx.db).await.unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let _cake = cake::ActiveModel {\n        name: Set(\"Chocolate Cake\".to_owned()),\n        price: Set(rust_dec(12.50)), // 12.50\n        bakery_id: Set(Some(bakery.id.unwrap())),\n        gluten_free: Set(false),\n        serial: Set(uuid::Uuid::new_v4()),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert cake\");\n\n    // Test exists with join - exists cake from a specific bakery\n    let exists = Cake::find()\n        .inner_join(Bakery)\n        .filter(bakery::Column::Name.eq(\"SeaSide Bakery\"))\n        .exists(&ctx.db)\n        .await\n        .unwrap();\n    assert_eq!(exists, true);\n\n    // Test exists with join - no cake from non-existent bakery\n    let exists = Cake::find()\n        .inner_join(Bakery)\n        .filter(bakery::Column::Name.eq(\"Non-existent Bakery\"))\n        .exists(&ctx.db)\n        .await\n        .unwrap();\n    assert_eq!(exists, false);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn exists_with_ordering() {\n    let ctx = TestContext::new(\"exists_with_ordering\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let _bakery1 = bakery::ActiveModel {\n        name: Set(\"A Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let _bakery2 = bakery::ActiveModel {\n        name: Set(\"Z Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    // Test exists with order by - should still work and return true\n    let exists = Bakery::find()\n        .order_by_asc(bakery::Column::Name)\n        .exists(&ctx.db)\n        .await\n        .unwrap();\n    assert_eq!(exists, true);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn exists_with_limit_offset() {\n    let ctx = TestContext::new(\"exists_with_limit_offset\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    // Insert multiple bakeries\n    for i in 1..=5 {\n        let _bakery = bakery::ActiveModel {\n            name: Set(format!(\"Bakery {}\", i)),\n            profit_margin: Set(10.0 + (i as f64)),\n            ..Default::default()\n        }\n        .save(&ctx.db)\n        .await\n        .expect(\"could not insert bakery\");\n    }\n\n    // Test exists with limit - should still find records\n    let exists = Bakery::find().limit(2).exists(&ctx.db).await.unwrap();\n    assert_eq!(exists, true);\n\n    // Test exists with offset - should still find records\n    let exists = Bakery::find().offset(3).exists(&ctx.db).await.unwrap();\n    assert_eq!(exists, true);\n\n    // Test exists with limit and offset - exists() checks for existence regardless of offset\n    // This is the expected behavior since exists() is optimized to check if ANY record exists\n    let exists = Bakery::find()\n        .offset(10) // Beyond all records\n        .limit(1)\n        .exists(&ctx.db)\n        .await\n        .unwrap();\n    assert_eq!(exists, true); // exists() ignores offset for performance optimization\n\n    ctx.delete().await;\n}\n"
  },
  {
    "path": "tests/from_query_result_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\nuse sea_orm::{\n    FromQueryResult, JoinType, Set,\n    prelude::*,\n    query::{QueryOrder, QuerySelect},\n};\n\nuse crate::common::TestContext;\nuse common::bakery_chain::*;\nuse serde_json::json;\n\nmod common;\n\n#[derive(FromQueryResult)]\nstruct Cake {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<CakeBakery>,\n}\n\n#[derive(FromQueryResult)]\nstruct CakeBakery {\n    #[sea_orm(alias = \"bakery_id\")]\n    id: i32,\n    #[sea_orm(alias = \"bakery_name\")]\n    title: String,\n}\n\n#[derive(FromQueryResult)]\nstruct BakeryDetails {\n    #[sea_orm(nested)]\n    basics: Bakery,\n    profit: f64,\n}\n\n#[derive(FromQueryResult)]\nstruct Bakery {\n    id: i32,\n    title: String,\n}\n\n#[derive(FromQueryResult)]\nstruct BakeryFlat {\n    id: i32,\n    name: String,\n    #[sea_orm(from_alias = \"profit_margin\")]\n    profit: f64,\n}\n\n#[derive(FromQueryResult)]\nstruct CakeWithOptionalBakeryModel {\n    #[sea_orm(alias = \"cake_id\")]\n    id: i32,\n    #[sea_orm(alias = \"cake_name\")]\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<bakery::Model>,\n}\n\n#[sea_orm_macros::test]\nasync fn from_query_result_left_join_does_not_exist() {\n    let ctx = TestContext::new(\"from_query_result_left_join_does_not_exist\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, false).await;\n\n    let cake: Cake = cake::Entity::find()\n        .select_only()\n        .column(cake::Column::Id)\n        .column(cake::Column::Name)\n        .column_as(bakery::Column::Id, \"bakery_id\")\n        .column_as(bakery::Column::Name, \"bakery_name\")\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert!(cake.bakery.is_none());\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn from_query_result_left_join_with_optional_model_does_not_exist() {\n    let ctx =\n        TestContext::new(\"from_query_result_left_join_with_optional_model_does_not_exist\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, false).await;\n\n    let cake: CakeWithOptionalBakeryModel = cake::Entity::find()\n        .select_only()\n        .column_as(cake::Column::Id, \"cake_id\")\n        .column_as(cake::Column::Name, \"cake_name\")\n        .column(bakery::Column::Id)\n        .column(bakery::Column::Name)\n        .column(bakery::Column::ProfitMargin)\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert!(cake.bakery.is_none());\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn from_query_result_left_join_exists() {\n    let ctx = TestContext::new(\"from_query_result_left_join_exists\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    let cake: Cake = cake::Entity::find()\n        .select_only()\n        .column(cake::Column::Id)\n        .column(cake::Column::Name)\n        .column_as(bakery::Column::Id, \"bakery_id\")\n        .column_as(bakery::Column::Name, \"bakery_name\")\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    let bakery = cake.bakery.unwrap();\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.title, \"cool little bakery\");\n\n    let cake: CakeWithOptionalBakeryModel = cake::Entity::find()\n        .select_only()\n        .column_as(cake::Column::Id, \"cake_id\")\n        .column_as(cake::Column::Name, \"cake_name\")\n        .column(bakery::Column::Id)\n        .column(bakery::Column::Name)\n        .column(bakery::Column::ProfitMargin)\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    let bakery = cake.bakery.unwrap();\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.name, \"cool little bakery\");\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn from_query_result_flat() {\n    let ctx = TestContext::new(\"from_query_result_flat\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    let bakery: BakeryFlat = bakery::Entity::find()\n        .into_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.name, \"cool little bakery\");\n    assert_eq!(bakery.profit, 4.1);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn from_query_result_nested() {\n    let ctx = TestContext::new(\"from_query_result_nested\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    let bakery: BakeryDetails = bakery::Entity::find()\n        .select_only()\n        .column(bakery::Column::Id)\n        .column_as(bakery::Column::Name, \"title\")\n        .column_as(bakery::Column::ProfitMargin, \"profit\")\n        .into_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.basics.id, 42);\n    assert_eq!(bakery.basics.title, \"cool little bakery\");\n    assert_eq!(bakery.profit, 4.1);\n\n    ctx.delete().await;\n}\n\n#[derive(FromQueryResult)]\nstruct CakePlain {\n    id: i32,\n    name: String,\n    price: Decimal,\n    #[sea_orm(nested)]\n    baker: Option<cakes_bakers::Model>,\n    #[sea_orm(skip)]\n    hidden: i32,\n}\n\n#[sea_orm_macros::test]\nasync fn from_query_result_plain_model() {\n    let ctx = TestContext::new(\"from_query_result_plain_model\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    let cake: CakePlain = cake::Entity::find()\n        .column(cakes_bakers::Column::CakeId)\n        .column(cakes_bakers::Column::BakerId)\n        .join(JoinType::LeftJoin, cakes_bakers::Relation::Cake.def().rev())\n        .order_by_asc(cake::Column::Id)\n        .into_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert_eq!(cake.price, Decimal::from(2));\n    let baker = cake.baker.unwrap();\n    assert_eq!(baker.cake_id, 13);\n    assert_eq!(baker.baker_id, 22);\n\n    ctx.delete().await;\n}\n\n#[derive(Debug, FromQueryResult)]\nstruct WrongBakery {\n    id: String,\n    title: String,\n}\n\n#[derive(Debug, FromQueryResult)]\nstruct WrongCake {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<WrongBakery>,\n}\n\n#[sea_orm_macros::test]\nasync fn from_query_result_optional_field_but_type_error() {\n    let ctx = TestContext::new(\"from_query_result_nested_error\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, false).await;\n\n    let _: DbErr = cake::Entity::find()\n        .select_only()\n        .column(cake::Column::Id)\n        .left_join(bakery::Entity)\n        .into_model::<WrongCake>()\n        .one(&ctx.db)\n        .await\n        .expect_err(\"should error instead of returning an empty Option\");\n\n    ctx.delete().await;\n}\n"
  },
  {
    "path": "tests/host_network_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n#![cfg(feature = \"with-ipnetwork\")]\n\npub mod common;\n\nuse common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\nuse std::net::{Ipv4Addr, Ipv6Addr};\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-postgres\")]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"host_network_tests\").await;\n    create_host_network_table(&ctx.db).await?;\n    create_and_update_host_network(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\nasync fn create_and_update_host_network(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let addr = IpNetwork::new(Ipv4Addr::new(192, 168, 0, 20).into(), 24).unwrap();\n    let net = IpNetwork::new(addr.network(), addr.prefix()).unwrap();\n\n    let host = host_network::Model {\n        id: 1,\n        hostname: \"example.com\".to_owned(),\n        ipaddress: addr,\n        network: net,\n    };\n    let res = host.clone().into_active_model().insert(db).await?;\n\n    let model = host_network::Entity::find().one(db).await?.unwrap();\n    assert_eq!(model, res);\n    assert_eq!(model, host.clone());\n\n    let addrv6 = IpNetwork::new(\n        Ipv6Addr::new(0xfd89, 0x1926, 0x4cae, 0x8abd, 0, 0, 0, 0x6f52).into(),\n        64,\n    )\n    .unwrap();\n    let netv6 = IpNetwork::new(addr.network(), addr.prefix()).unwrap();\n\n    let res = host_network::ActiveModel {\n        id: Set(1),\n        ipaddress: Set(addrv6),\n        network: Set(netv6),\n        ..Default::default()\n    }\n    .update(db)\n    .await?;\n\n    assert_eq!(\n        res,\n        host_network::Model {\n            id: 1,\n            hostname: \"example.com\".to_owned(),\n            ipaddress: addrv6,\n            network: netv6,\n        }\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/impl_from_for_active_model.rs",
    "content": "use sea_orm::{Set, tests_cfg::cake};\n\nstruct Cake {\n    id: i32,\n    name: String,\n}\n\nimpl From<Cake> for cake::ActiveModel {\n    fn from(value: Cake) -> Self {\n        Self {\n            id: Set(value.id),\n            name: Set(value.name),\n        }\n    }\n}\n"
  },
  {
    "path": "tests/insert_default_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::entity::prelude::*;\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"insert_default_tests\").await;\n    create_insert_default_table(&ctx.db).await?;\n    create_insert_default(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    let active_model = ActiveModel {\n        ..Default::default()\n    };\n\n    active_model.clone().insert(db).await?;\n    active_model.clone().insert(db).await?;\n    active_model.insert(db).await?;\n\n    assert_eq!(\n        Entity::find().all(db).await?,\n        [Model { id: 1 }, Model { id: 2 }, Model { id: 3 }]\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/json_struct_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, DbBackend, ExprTrait, entity::prelude::*, entity::*};\nuse serde_json::json;\n\nmod json_compact {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::compact_model]\n    #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"json_compact\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(column_type = \"JsonBinary\")]\n        pub json: Json,\n        #[sea_orm(column_type = \"JsonBinary\", nullable)]\n        pub json_opt: Option<Json>,\n    }\n\n    #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[sea_orm_macros::test]\nasync fn json_struct_tests() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"json_struct_tests\").await;\n    create_json_struct_table(&ctx.db).await?;\n    insert_json_struct_1(&ctx.db).await?;\n    insert_json_struct_2(&ctx.db).await?;\n    insert_json_struct_3(&ctx.db).await?;\n\n    ctx.delete().await;\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\n#[should_panic(\n    expected = \"Failed to serialize 'NonSerializableStruct': Error(\\\"intentionally failing serialization\\\", line: 0, column: 0)\"\n)]\nasync fn panic_on_non_serializable_insert() {\n    use json_struct::*;\n\n    let ctx = TestContext::new(\"json_struct_non_serializable_test\").await;\n\n    let model = Model {\n        id: 1,\n        json: json!({\n            \"id\": 1,\n            \"name\": \"apple\",\n            \"price\": 12.01,\n            \"notes\": \"hand picked, organic\",\n        }),\n        json_value: KeyValue {\n            id: 1,\n            name: \"apple\".into(),\n            price: 12.01,\n            notes: Some(\"hand picked, organic\".into()),\n        },\n        json_value_opt: Some(KeyValue {\n            id: 1,\n            name: \"apple\".into(),\n            price: 12.01,\n            notes: Some(\"hand picked, organic\".into()),\n        }),\n        json_non_serializable: Some(NonSerializableStruct),\n    };\n\n    let _ = model.into_active_model().insert(&ctx.db).await;\n}\n\npub async fn insert_json_struct_1(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use json_struct::*;\n\n    let model = Model {\n        id: 1,\n        json: json!({\n            \"id\": 1,\n            \"name\": \"apple\",\n            \"price\": 12.01,\n            \"notes\": \"hand picked, organic\",\n        }),\n        json_value: KeyValue {\n            id: 1,\n            name: \"apple\".into(),\n            price: 12.01,\n            notes: Some(\"hand picked, organic\".into()),\n        },\n        json_value_opt: Some(KeyValue {\n            id: 1,\n            name: \"apple\".into(),\n            price: 12.01,\n            notes: Some(\"hand picked, organic\".into()),\n        }),\n        json_non_serializable: None,\n    };\n\n    let result = model.clone().into_active_model().insert(db).await?;\n\n    assert_eq!(result, model);\n\n    assert_eq!(\n        Entity::find()\n            .filter(Column::Id.eq(model.id))\n            .one(db)\n            .await?,\n        Some(model)\n    );\n\n    Ok(())\n}\n\npub async fn insert_json_struct_2(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use json_struct::*;\n\n    let model = Model {\n        id: 2,\n        json: json!({\n            \"id\": 2,\n            \"name\": \"orange\",\n            \"price\": 10.93,\n            \"notes\": \"sweet & juicy\",\n        }),\n        json_value: KeyValue {\n            id: 1,\n            name: \"orange\".into(),\n            price: 10.93,\n            notes: None,\n        },\n        json_value_opt: None,\n        json_non_serializable: None,\n    };\n\n    let result = model.clone().into_active_model().insert(db).await?;\n\n    assert_eq!(result, model);\n\n    assert_eq!(\n        Entity::find()\n            .filter(Column::Id.eq(model.id))\n            .one(db)\n            .await?,\n        Some(model)\n    );\n\n    Ok(())\n}\n\npub async fn insert_json_struct_3(db: &DatabaseConnection) -> Result<(), DbErr> {\n    db.get_schema_builder()\n        .register(json_compact::Entity)\n        .apply(db)\n        .await?;\n\n    use json_compact::*;\n\n    let model = Model {\n        id: 3,\n        json: json!({ \"id\": 22 }),\n        json_opt: None,\n    };\n\n    let model_2 = model.into_active_model().insert(db).await?;\n\n    if db.get_database_backend() == DbBackend::MySql {\n        // FIXME how can we abstract this?\n        // MariaDb doesn't require CAST AS json\n        if false {\n            assert_eq!(\n                Entity::find()\n                    .filter(\n                        Expr::col(COLUMN.json).eq(Expr::val(json!({ \"id\": 22 })).cast_as(\"json\"))\n                    )\n                    .one(db)\n                    .await?\n                    .unwrap(),\n                model_2\n            );\n        }\n    } else {\n        assert_eq!(\n            Entity::find()\n                .filter(COLUMN.json.eq(json!({ \"id\": 22 })))\n                .one(db)\n                .await?\n                .unwrap(),\n            model_2\n        );\n    }\n\n    let model = Model {\n        id: 4,\n        json: json!({ \"id\": 11 }),\n        json_opt: Some(json!({ \"id\": 33 })),\n    };\n\n    let model_4 = model.into_active_model().insert(db).await?;\n\n    if db.get_database_backend() == DbBackend::MySql {\n        // FIXME how can we abstract this?\n        // MariaDb doesn't require CAST AS json\n        if false {\n            assert_eq!(\n                Entity::find()\n                    .filter(\n                        Expr::col(COLUMN.json_opt)\n                            .eq(Expr::val(json!({ \"id\": 33 })).cast_as(\"json\"))\n                    )\n                    .one(db)\n                    .await?\n                    .unwrap(),\n                model_4\n            );\n        }\n    } else {\n        assert_eq!(\n            Entity::find()\n                .filter(COLUMN.json_opt.eq(json!({ \"id\": 33 })))\n                .one(db)\n                .await?\n                .unwrap(),\n            model_4\n        );\n    }\n\n    assert_eq!(\n        Entity::find()\n            .filter(COLUMN.json_opt.eq(Option::<Json>::None))\n            .one(db)\n            .await?\n            .unwrap(),\n        model_2\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/json_vec_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"json_vec_tests\").await;\n    create_json_vec_table(&ctx.db).await?;\n    create_json_string_vec_table(&ctx.db).await?;\n    create_json_struct_vec_table(&ctx.db).await?;\n    insert_json_vec(&ctx.db).await?;\n    insert_json_string_vec_derive(&ctx.db).await?;\n    insert_json_struct_vec_derive(&ctx.db).await?;\n\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn insert_json_vec(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let json_vec = json_vec::Model {\n        id: 1,\n        str_vec: Some(json_vec::StringVec(vec![\n            \"1\".to_string(),\n            \"2\".to_string(),\n            \"3\".to_string(),\n        ])),\n    };\n\n    let result = json_vec.clone().into_active_model().insert(db).await?;\n\n    assert_eq!(result, json_vec);\n\n    let model = json_vec::Entity::find()\n        .filter(json_vec::Column::Id.eq(json_vec.id))\n        .one(db)\n        .await?;\n\n    assert_eq!(model, Some(json_vec));\n\n    Ok(())\n}\n\npub async fn insert_json_string_vec_derive(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let json_vec = json_vec_derive::json_string_vec::Model {\n        id: 1,\n        str_vec: Some(json_vec_derive::json_string_vec::StringVec(vec![\n            \"4\".to_string(),\n            \"5\".to_string(),\n            \"6\".to_string(),\n        ])),\n    };\n\n    let result = json_vec_derive::json_string_vec::ActiveModel {\n        id: NotSet,\n        ..json_vec.clone().into_active_model()\n    }\n    .insert(db)\n    .await?;\n\n    assert_eq!(result, json_vec);\n\n    let model = json_vec_derive::json_string_vec::Entity::find()\n        .filter(json_vec_derive::json_string_vec::Column::Id.eq(json_vec.id))\n        .one(db)\n        .await?;\n\n    assert_eq!(model, Some(json_vec));\n\n    let result = json_vec_derive::json_string_vec::ActiveModel {\n        id: NotSet,\n        str_vec: Set(None),\n    }\n    .insert(db)\n    .await?;\n\n    assert_eq!(result.str_vec, None);\n\n    Ok(())\n}\n\npub async fn insert_json_struct_vec_derive(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let json_vec = json_vec_derive::json_struct_vec::Model {\n        id: 2,\n        struct_vec: vec![\n            json_vec_derive::json_struct_vec::JsonColumn {\n                value: \"4\".to_string(),\n            },\n            json_vec_derive::json_struct_vec::JsonColumn {\n                value: \"5\".to_string(),\n            },\n            json_vec_derive::json_struct_vec::JsonColumn {\n                value: \"6\".to_string(),\n            },\n        ],\n    };\n\n    let _result = json_vec.clone().into_active_model().insert(db).await?;\n\n    let model = json_vec_derive::json_struct_vec::Entity::find()\n        .filter(json_vec_derive::json_struct_vec::Column::Id.eq(json_vec.id))\n        .one(db)\n        .await?;\n\n    assert_eq!(model, Some(json_vec));\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/loader_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\nuse sea_orm::{DbConn, DbErr, LoaderTraitEx, RuntimeErr, entity::*, query::*};\n\nmod enum_pk_models {\n    use crate::common::features::Tea;\n    use sea_orm::entity::prelude::*;\n\n    pub mod tea_inventory {\n        use super::tea_order;\n        use super::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"tea_inventory\")]\n        pub struct Model {\n            #[sea_orm(primary_key, auto_increment = false)]\n            pub tea: Tea,\n            pub stock: i32,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {\n            #[sea_orm(has_many = \"super::tea_order::Entity\")]\n            TeaOrder,\n        }\n\n        impl Related<tea_order::Entity> for Entity {\n            fn to() -> RelationDef {\n                Relation::TeaOrder.def()\n            }\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n\n    pub mod tea_order {\n        use super::tea_inventory;\n        use super::*;\n\n        #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n        #[sea_orm(table_name = \"tea_orders\")]\n        pub struct Model {\n            #[sea_orm(primary_key, auto_increment = false)]\n            pub order_id: i32,\n            #[sea_orm(primary_key, auto_increment = false)]\n            pub tea: Tea,\n            pub quantity: i32,\n        }\n\n        #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]\n        pub enum Relation {\n            #[sea_orm(\n                belongs_to = \"super::tea_inventory::Entity\",\n                from = \"Column::Tea\",\n                to = \"super::tea_inventory::Column::Tea\"\n            )]\n            TeaInventory,\n        }\n\n        impl Related<tea_inventory::Entity> for Entity {\n            fn to() -> RelationDef {\n                Relation::TeaInventory.def()\n            }\n        }\n\n        impl ActiveModelBehavior for ActiveModel {}\n    }\n}\n\nuse enum_pk_models::{tea_inventory, tea_order};\n\n#[sea_orm_macros::test]\nasync fn loader_load_one() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"loader_test_load_one\").await;\n    create_tables(&ctx.db).await?;\n\n    let bakery_0 = insert_bakery(&ctx.db, \"SeaSide Bakery\").await?;\n\n    let baker_1 = insert_baker(&ctx.db, \"Baker 1\", bakery_0.id).await?;\n    let baker_2 = insert_baker(&ctx.db, \"Baker 2\", bakery_0.id).await?;\n    let baker_3 = baker::ActiveModel {\n        name: Set(\"Baker 3\".to_owned()),\n        contact_details: Set(serde_json::json!({})),\n        bakery_id: Set(None),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await?;\n\n    let bakers = baker::Entity::find().all(&ctx.db).await?;\n    let bakeries = bakers.load_one(bakery::Entity, &ctx.db).await?;\n\n    assert_eq!(bakers, [baker_1.clone(), baker_2.clone(), baker_3.clone()]);\n    assert_eq!(\n        bakeries,\n        [Some(bakery_0.clone()), Some(bakery_0.clone()), None]\n    );\n\n    let bakers = vec![\n        Some(baker_1.clone().into_ex()),\n        None,\n        Some(baker_2.clone().into_ex()),\n        Some(baker_3.clone().into_ex()),\n        None,\n    ];\n    let bakeries = bakers\n        .as_slice()\n        .load_one_ex(bakery::Entity, &ctx.db)\n        .await?;\n    assert_eq!(\n        bakeries,\n        [\n            Some(bakery_0.clone()),\n            None,\n            Some(bakery_0.clone()),\n            None,\n            None\n        ]\n    );\n\n    // has many find, should use load_many instead\n    let bakeries = bakery::Entity::find().all(&ctx.db).await?;\n    let bakers = bakeries.load_one(baker::Entity, &ctx.db).await;\n\n    assert_eq!(\n        bakers,\n        Err(DbErr::Query(RuntimeErr::Internal(\n            \"Relation is HasMany instead of HasOne\".to_string()\n        )))\n    );\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn loader_load_many() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"loader_test_load_many\").await;\n    create_tables(&ctx.db).await?;\n\n    let bakery_1 = insert_bakery(&ctx.db, \"SeaSide Bakery\").await?;\n    let bakery_2 = insert_bakery(&ctx.db, \"Offshore Bakery\").await?;\n    let bakery_3 = insert_bakery(&ctx.db, \"Rocky Bakery\").await?;\n\n    let baker_1 = insert_baker(&ctx.db, \"Baker 1\", bakery_1.id).await?;\n    let baker_2 = insert_baker(&ctx.db, \"Baker 2\", bakery_1.id).await?;\n\n    let baker_3 = insert_baker(&ctx.db, \"John\", bakery_2.id).await?;\n    let baker_4 = insert_baker(&ctx.db, \"Baker 4\", bakery_2.id).await?;\n\n    let bakeries = bakery::Entity::find().all(&ctx.db).await?;\n    let bakers = bakeries.load_many(baker::Entity, &ctx.db).await?;\n\n    assert_eq!(\n        bakeries,\n        [bakery_1.clone(), bakery_2.clone(), bakery_3.clone()]\n    );\n    assert_eq!(\n        bakers,\n        [\n            vec![baker_1.clone(), baker_2.clone()],\n            vec![baker_3.clone(), baker_4.clone()],\n            vec![]\n        ]\n    );\n\n    // test interlaced loader\n    let bakeries_sparse = vec![\n        Some(bakery_1.clone().into_ex()),\n        None,\n        Some(bakery_2.clone().into_ex()),\n        None,\n    ];\n    let bakers = bakeries_sparse\n        .as_slice()\n        .load_many_ex(baker::Entity, &ctx.db)\n        .await?;\n    assert_eq!(\n        bakers,\n        [\n            vec![baker_1.clone(), baker_2.clone()],\n            vec![],\n            vec![baker_3.clone(), baker_4.clone()],\n            vec![],\n        ]\n    );\n\n    // load bakers again but with additional condition\n\n    let bakers = bakeries\n        .load_many(\n            baker::Entity::find().filter(baker::Column::Name.like(\"Baker%\")),\n            &ctx.db,\n        )\n        .await?;\n\n    assert_eq!(\n        bakers,\n        [\n            vec![baker_1.clone(), baker_2.clone()],\n            vec![baker_4.clone()],\n            vec![]\n        ]\n    );\n\n    // now, start from baker\n\n    let bakers = baker::Entity::find().all(&ctx.db).await?;\n    let bakeries = bakers.load_one(bakery::Entity::find(), &ctx.db).await?;\n\n    // note that two bakers share the same bakery\n    assert_eq!(bakers, [baker_1, baker_2, baker_3, baker_4]);\n    assert_eq!(\n        bakeries,\n        [\n            Some(bakery_1.clone()),\n            Some(bakery_1.clone()),\n            Some(bakery_2.clone()),\n            Some(bakery_2.clone())\n        ]\n    );\n\n    // following should be equivalent\n    let bakeries = bakers.load_many(bakery::Entity::find(), &ctx.db).await?;\n\n    assert_eq!(\n        bakeries,\n        [\n            vec![bakery_1.clone()],\n            vec![bakery_1.clone()],\n            vec![bakery_2.clone()],\n            vec![bakery_2.clone()],\n        ]\n    );\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn loader_load_many_multi() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"loader_test_load_many_multi\").await;\n    create_tables(&ctx.db).await?;\n\n    let bakery_1 = insert_bakery(&ctx.db, \"SeaSide Bakery\").await?;\n    let bakery_2 = insert_bakery(&ctx.db, \"Offshore Bakery\").await?;\n\n    let baker_1 = insert_baker(&ctx.db, \"John\", bakery_1.id).await?;\n    let baker_2 = insert_baker(&ctx.db, \"Jane\", bakery_1.id).await?;\n    let baker_3 = insert_baker(&ctx.db, \"Peter\", bakery_2.id).await?;\n\n    let cake_1 = insert_cake(&ctx.db, \"Cheesecake\", Some(bakery_1.id)).await?;\n    let cake_2 = insert_cake(&ctx.db, \"Chocolate\", Some(bakery_2.id)).await?;\n    let cake_3 = insert_cake(&ctx.db, \"Chiffon\", Some(bakery_2.id)).await?;\n    let _cake_4 = insert_cake(&ctx.db, \"Apple Pie\", None).await?; // no one makes apple pie\n\n    let bakeries = bakery::Entity::find().all(&ctx.db).await?;\n    let bakers = bakeries.load_many(baker::Entity, &ctx.db).await?;\n    let cakes = bakeries.load_many(cake::Entity, &ctx.db).await?;\n\n    assert_eq!(bakeries, [bakery_1, bakery_2]);\n    assert_eq!(bakers, [vec![baker_1, baker_2], vec![baker_3]]);\n    assert_eq!(cakes, [vec![cake_1], vec![cake_2, cake_3]]);\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn loader_load_many_enum_pk_postgres() -> Result<(), DbErr> {\n    use crate::common::features::Tea;\n    use sea_orm::{ActiveValue::Set, ConnectionTrait, DbBackend, Schema};\n    use sea_query::{Alias, extension::postgres::Type};\n    use tea_inventory::{\n        ActiveModel as TeaInventoryActiveModel, Column as TeaInventoryColumn,\n        Entity as TeaInventoryEntity, Model as TeaInventoryModel,\n    };\n    use tea_order::{\n        ActiveModel as TeaOrderActiveModel, Column as TeaOrderColumn, Entity as TeaOrderEntity,\n        Model as TeaOrderModel,\n    };\n\n    let ctx = TestContext::new(\"loader_enum_pk_postgres\").await;\n    let db = &ctx.db;\n\n    if db.get_database_backend() != DbBackend::Postgres {\n        return Ok(());\n    }\n\n    let mut drop_type = Type::drop();\n    drop_type.if_exists().name(\"tea\").cascade();\n    db.execute(&drop_type).await?;\n\n    db.get_schema_builder()\n        .register(TeaInventoryEntity)\n        .register(TeaOrderEntity)\n        .apply(db)\n        .await?;\n\n    TeaInventoryActiveModel {\n        tea: Set(Tea::EverydayTea),\n        stock: Set(10),\n    }\n    .insert(db)\n    .await?;\n    TeaInventoryActiveModel {\n        tea: Set(Tea::BreakfastTea),\n        stock: Set(4),\n    }\n    .insert(db)\n    .await?;\n\n    TeaOrderActiveModel {\n        order_id: Set(1),\n        tea: Set(Tea::EverydayTea),\n        quantity: Set(2),\n    }\n    .insert(db)\n    .await?;\n    TeaOrderActiveModel {\n        order_id: Set(2),\n        tea: Set(Tea::EverydayTea),\n        quantity: Set(5),\n    }\n    .insert(db)\n    .await?;\n    TeaOrderActiveModel {\n        order_id: Set(1),\n        tea: Set(Tea::BreakfastTea),\n        quantity: Set(1),\n    }\n    .insert(db)\n    .await?;\n\n    let teas = TeaInventoryEntity::find()\n        .order_by_asc(TeaInventoryColumn::Tea)\n        .all(db)\n        .await?;\n    let loaded_orders = teas\n        .load_many(\n            TeaOrderEntity::find().order_by_asc(TeaOrderColumn::OrderId),\n            db,\n        )\n        .await?;\n\n    assert_eq!(teas.len(), 2);\n    assert_eq!(loaded_orders.len(), 2);\n\n    for (inventory, orders) in teas.iter().zip(&loaded_orders) {\n        match inventory.tea {\n            Tea::EverydayTea => {\n                assert_eq!(\n                    orders,\n                    &vec![\n                        TeaOrderModel {\n                            order_id: 1,\n                            tea: Tea::EverydayTea,\n                            quantity: 2,\n                        },\n                        TeaOrderModel {\n                            order_id: 2,\n                            tea: Tea::EverydayTea,\n                            quantity: 5,\n                        }\n                    ]\n                );\n            }\n            Tea::BreakfastTea => {\n                assert_eq!(\n                    orders,\n                    &vec![TeaOrderModel {\n                        order_id: 1,\n                        tea: Tea::BreakfastTea,\n                        quantity: 1,\n                    }]\n                );\n            }\n            Tea::AfternoonTea => {}\n        }\n    }\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn loader_load_many_to_many() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"loader_test_load_many_to_many\").await;\n    create_tables(&ctx.db).await?;\n\n    let bakery_1 = insert_bakery(&ctx.db, \"SeaSide Bakery\").await?;\n\n    let baker_1 = insert_baker(&ctx.db, \"Jane\", bakery_1.id).await?;\n    let baker_2 = insert_baker(&ctx.db, \"Peter\", bakery_1.id).await?;\n    let baker_3 = insert_baker(&ctx.db, \"Fred\", bakery_1.id).await?; // does not make cake\n\n    let cake_1 = insert_cake(&ctx.db, \"Cheesecake\", None).await?;\n    let cake_2 = insert_cake(&ctx.db, \"Coffee\", None).await?;\n    let cake_3 = insert_cake(&ctx.db, \"Chiffon\", None).await?;\n    let cake_4 = insert_cake(&ctx.db, \"Apple Pie\", None).await?; // no one makes apple pie\n\n    insert_cake_baker(&ctx.db, baker_1.id, cake_1.id).await?;\n    insert_cake_baker(&ctx.db, baker_1.id, cake_2.id).await?;\n    insert_cake_baker(&ctx.db, baker_2.id, cake_2.id).await?;\n    insert_cake_baker(&ctx.db, baker_2.id, cake_3.id).await?;\n\n    let bakers = baker::Entity::find().all(&ctx.db).await?;\n    let cakes = bakers\n        .load_many_to_many(cake::Entity, cakes_bakers::Entity, &ctx.db)\n        .await?;\n\n    assert_eq!(bakers, [baker_1.clone(), baker_2.clone(), baker_3.clone()]);\n    assert_eq!(\n        cakes,\n        [\n            vec![cake_1.clone(), cake_2.clone()],\n            vec![cake_2.clone(), cake_3.clone()],\n            vec![]\n        ]\n    );\n\n    // same, but apply restrictions on cakes\n\n    let cakes = bakers\n        .load_many_to_many(\n            cake::Entity::find().filter(cake::Column::Name.like(\"Ch%\")),\n            cakes_bakers::Entity,\n            &ctx.db,\n        )\n        .await?;\n    assert_eq!(cakes, [vec![cake_1.clone()], vec![cake_3.clone()], vec![]]);\n\n    // now, start again from cakes\n\n    let cakes = cake::Entity::find().all(&ctx.db).await?;\n    let bakers = cakes\n        .load_many_to_many(baker::Entity, cakes_bakers::Entity, &ctx.db)\n        .await?;\n\n    assert_eq!(cakes, [cake_1, cake_2, cake_3, cake_4]);\n    assert_eq!(\n        bakers,\n        [\n            vec![baker_1.clone()],\n            vec![baker_1.clone(), baker_2.clone()],\n            vec![baker_2.clone()],\n            vec![]\n        ]\n    );\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn loader_load_many_to_many_dyn() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"loader_test_load_many_to_many_dyn\").await;\n    create_tables(&ctx.db).await?;\n\n    let bakery_1 = insert_bakery(&ctx.db, \"SeaSide Bakery\").await?;\n\n    let baker_1 = insert_baker(&ctx.db, \"Jane\", bakery_1.id).await?;\n    let baker_2 = insert_baker(&ctx.db, \"Peter\", bakery_1.id).await?;\n    let baker_3 = insert_baker(&ctx.db, \"Fred\", bakery_1.id).await?; // does not make cake\n\n    let cake_1 = insert_cake(&ctx.db, \"Cheesecake\", None).await?;\n    let cake_2 = insert_cake(&ctx.db, \"Coffee\", None).await?;\n    let cake_3 = insert_cake(&ctx.db, \"Chiffon\", None).await?;\n    let cake_4 = insert_cake(&ctx.db, \"Apple Pie\", None).await?; // no one makes apple pie\n\n    insert_cake_baker(&ctx.db, baker_1.id, cake_1.id).await?;\n    insert_cake_baker(&ctx.db, baker_1.id, cake_2.id).await?;\n    insert_cake_baker(&ctx.db, baker_2.id, cake_2.id).await?;\n    insert_cake_baker(&ctx.db, baker_2.id, cake_3.id).await?;\n\n    let bakers = baker::Entity::find().all(&ctx.db).await?;\n    let cakes = bakers.load_many(cake::Entity, &ctx.db).await?;\n\n    assert_eq!(bakers, [baker_1.clone(), baker_2.clone(), baker_3.clone()]);\n    assert_eq!(\n        cakes,\n        [\n            vec![cake_1.clone(), cake_2.clone()],\n            vec![cake_2.clone(), cake_3.clone()],\n            vec![]\n        ]\n    );\n\n    // same, but apply restrictions on cakes\n\n    let cakes = bakers\n        .load_many_to_many(\n            cake::Entity::find().filter(cake::Column::Name.like(\"Ch%\")),\n            cakes_bakers::Entity,\n            &ctx.db,\n        )\n        .await?;\n    assert_eq!(cakes, [vec![cake_1.clone()], vec![cake_3.clone()], vec![]]);\n\n    // now, start again from cakes\n\n    let cakes = cake::Entity::find().all(&ctx.db).await?;\n    let bakers = cakes.load_many(baker::Entity, &ctx.db).await?;\n\n    assert_eq!(cakes, [cake_1, cake_2, cake_3, cake_4]);\n    assert_eq!(\n        bakers,\n        [\n            vec![baker_1.clone()],\n            vec![baker_1.clone(), baker_2.clone()],\n            vec![baker_2.clone()],\n            vec![]\n        ]\n    );\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn loader_self_join() -> Result<(), DbErr> {\n    use common::blogger::{user, user_follower};\n    use common::film_store::{staff, staff_compact};\n\n    let ctx = TestContext::new(\"test_loader_self_join\").await;\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(staff::Entity)\n        .register(user::Entity)\n        .register(user_follower::Entity)\n        .apply(db)\n        .await?;\n\n    let alan = staff::ActiveModel {\n        name: Set(\"Alan\".into()),\n        reports_to_id: Set(None),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    staff::ActiveModel {\n        name: Set(\"Ben\".into()),\n        reports_to_id: Set(Some(alan.id)),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    staff::ActiveModel {\n        name: Set(\"Alice\".into()),\n        reports_to_id: Set(Some(alan.id)),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    staff::ActiveModel {\n        name: Set(\"Elle\".into()),\n        reports_to_id: Set(None),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    let staff = staff::Entity::find()\n        .order_by_asc(staff::Column::Id)\n        .all(db)\n        .await?;\n\n    let reports_to = staff\n        .load_self(staff::Entity, staff::Relation::ReportsTo, db)\n        .await?;\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(reports_to[0], None);\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(reports_to[1].as_ref().unwrap().name, \"Alan\");\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(reports_to[2].as_ref().unwrap().name, \"Alan\");\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(reports_to[3], None);\n\n    let manages = staff\n        .load_self_many(\n            staff::Entity::find().order_by_asc(staff::COLUMN.id),\n            staff::Relation::ReportsTo,\n            db,\n        )\n        .await?;\n\n    assert_eq!(\n        manages,\n        staff\n            .load_self_many(\n                staff::Entity::find().order_by_asc(staff::COLUMN.id),\n                staff::Relation::Manages,\n                db,\n            )\n            .await?\n    );\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(manages[0].len(), 2);\n    assert_eq!(manages[0][0].name, \"Ben\");\n    assert_eq!(manages[0][1].name, \"Alice\");\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(manages[1].len(), 0);\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(manages[2].len(), 0);\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(manages[3].len(), 0);\n\n    // test self_ref on compact_model\n\n    let staff = staff_compact::Entity::find()\n        .order_by_asc(staff_compact::COLUMN.id)\n        .all(db)\n        .await?;\n\n    let reports_to = staff\n        .load_self(\n            staff_compact::Entity,\n            staff_compact::Relation::ReportsTo,\n            db,\n        )\n        .await?;\n\n    let manages = staff\n        .load_self_many(\n            staff_compact::Entity::find().order_by_asc(staff_compact::COLUMN.id),\n            staff_compact::Relation::ReportsTo,\n            db,\n        )\n        .await?;\n\n    assert_eq!(\n        manages,\n        staff\n            .load_self_many(\n                staff_compact::Entity::find().order_by_asc(staff_compact::COLUMN.id),\n                staff_compact::Relation::Manages,\n                db,\n            )\n            .await?\n    );\n\n    assert_eq!(staff[0].name, \"Alan\");\n    assert_eq!(reports_to[0], None);\n    assert_eq!(manages[0].len(), 2);\n    assert_eq!(manages[0][0].name, \"Ben\");\n    assert_eq!(manages[0][1].name, \"Alice\");\n\n    assert_eq!(staff[1].name, \"Ben\");\n    assert_eq!(reports_to.get(1).unwrap().as_ref().unwrap().name, \"Alan\");\n    assert_eq!(manages[1].len(), 0);\n\n    assert_eq!(staff[2].name, \"Alice\");\n    assert_eq!(reports_to.get(2).unwrap().as_ref().unwrap().name, \"Alan\");\n    assert_eq!(manages[2].len(), 0);\n\n    assert_eq!(staff[3].name, \"Elle\");\n    assert_eq!(reports_to[3], None);\n    assert_eq!(manages[3].len(), 0);\n\n    // self_ref + via\n\n    let alice = user::ActiveModel {\n        name: Set(\"Alice\".into()),\n        email: Set(\"@1\".into()),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    let bob = user::ActiveModel {\n        name: Set(\"Bob\".into()),\n        email: Set(\"@2\".into()),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    let sam = user::ActiveModel {\n        name: Set(\"Sam\".into()),\n        email: Set(\"@3\".into()),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    user_follower::ActiveModel {\n        user_id: Set(alice.id),\n        follower_id: Set(bob.id),\n    }\n    .insert(db)\n    .await?;\n\n    user_follower::ActiveModel {\n        user_id: Set(alice.id),\n        follower_id: Set(sam.id),\n    }\n    .insert(db)\n    .await?;\n\n    user_follower::ActiveModel {\n        user_id: Set(bob.id),\n        follower_id: Set(sam.id),\n    }\n    .insert(db)\n    .await?;\n\n    let users = user::Entity::find().all(db).await?;\n    let followers = users.load_self_via(user_follower::Entity, db).await?;\n    let following = users.load_self_via_rev(user_follower::Entity, db).await?;\n\n    assert_eq!(users[0], alice);\n    assert_eq!(followers[0], [bob.clone(), sam.clone()]);\n    assert!(following[0].is_empty());\n\n    assert_eq!(users[1], bob);\n    assert_eq!(followers[1], [sam.clone()]);\n    assert_eq!(following[1], [alice.clone()]);\n\n    assert_eq!(users[2], sam);\n    assert!(followers[2].is_empty());\n    assert_eq!(following[2], [alice, bob]);\n\n    Ok(())\n}\n\npub async fn insert_bakery(db: &DbConn, name: &str) -> Result<bakery::Model, DbErr> {\n    bakery::ActiveModel {\n        name: Set(name.to_owned()),\n        profit_margin: Set(1.0),\n        ..Default::default()\n    }\n    .insert(db)\n    .await\n}\n\npub async fn insert_baker(db: &DbConn, name: &str, bakery_id: i32) -> Result<baker::Model, DbErr> {\n    baker::ActiveModel {\n        name: Set(name.to_owned()),\n        contact_details: Set(serde_json::json!({})),\n        bakery_id: Set(Some(bakery_id)),\n        ..Default::default()\n    }\n    .insert(db)\n    .await\n}\n\npub async fn insert_cake(\n    db: &DbConn,\n    name: &str,\n    bakery_id: Option<i32>,\n) -> Result<cake::Model, DbErr> {\n    cake::ActiveModel {\n        name: Set(name.to_owned()),\n        price: Set(rust_decimal::Decimal::ONE),\n        gluten_free: Set(false),\n        bakery_id: Set(bakery_id),\n        ..Default::default()\n    }\n    .insert(db)\n    .await\n}\n\npub async fn insert_cake_baker(\n    db: &DbConn,\n    baker_id: i32,\n    cake_id: i32,\n) -> Result<cakes_bakers::Model, DbErr> {\n    cakes_bakers::ActiveModel {\n        cake_id: Set(cake_id),\n        baker_id: Set(baker_id),\n    }\n    .insert(db)\n    .await\n}\n"
  },
  {
    "path": "tests/multi_select_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\nmod common;\n\nuse crate::common::TestContext;\nuse sea_orm::{\n    Database, DbConn, DbErr,\n    entity::*,\n    query::*,\n    sea_query::{Expr, Query},\n};\n\nmod one {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"one\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(has_one)]\n        pub two: Option<super::two::Entity>,\n        #[sea_orm(has_one)]\n        pub six: Option<super::six::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod two {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"two\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub one_id: i32,\n        pub three_id: i32,\n        #[sea_orm(belongs_to, from = \"one_id\", to = \"id\")]\n        pub one: Option<super::one::Entity>,\n        #[sea_orm(belongs_to, from = \"three_id\", to = \"id\")]\n        pub three: Option<super::three::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod three {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"three\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(has_one)]\n        pub four: Option<super::four::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod four {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"four\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub three_id: Option<i32>,\n        #[sea_orm(belongs_to, from = \"three_id\", to = \"id\")]\n        pub three: Option<super::three::Entity>,\n        #[sea_orm(has_one)]\n        pub five: Option<super::five::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod five {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"five\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub four_id: i32,\n        #[sea_orm(belongs_to, from = \"four_id\", to = \"id\")]\n        pub four: Option<super::four::Entity>,\n        #[sea_orm(has_one)]\n        pub six: Option<super::six::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod six {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"six\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub one_id: i32,\n        pub five_id: i32,\n        #[sea_orm(belongs_to, from = \"one_id\", to = \"id\")]\n        pub one: Option<super::one::Entity>,\n        #[sea_orm(belongs_to, from = \"five_id\", to = \"id\")]\n        pub five: Option<super::five::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod composite_a {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"composite_a\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique_key = \"pair\")]\n        pub left_id: i32,\n        #[sea_orm(unique_key = \"pair\")]\n        pub right_id: i32,\n        #[sea_orm(has_one)]\n        pub b: Option<super::composite_b::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod composite_b {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"composite_b\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub left_id: i32,\n        pub right_id: i32,\n        #[sea_orm(belongs_to, from = \"(left_id, right_id)\", to = \"(left_id, right_id)\")]\n        pub a: Option<super::composite_a::Entity>,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod composite_b_without_index {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"composite_b\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub left_id: i32,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\nmod composite_c {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"composite_c\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique_key = \"season_episode\")]\n        pub season_number: i32,\n        #[sea_orm(unique_key = \"season_episode\")]\n        pub episode_number: i32,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[sea_orm_macros::test]\nasync fn test_select_six() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"test_select_six\").await;\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(one::Entity)\n        .register(two::Entity)\n        .register(three::Entity) // topologically three ranks higher than two\n        .register(four::Entity)\n        .register(five::Entity)\n        .register(six::Entity)\n        .apply(db)\n        .await?;\n\n    one::ActiveModel { id: Set(1) }.insert(db).await?;\n    one::ActiveModel { id: Set(11) }.insert(db).await?;\n\n    three::ActiveModel { id: Set(3) }.insert(db).await?;\n    three::ActiveModel { id: Set(33) }.insert(db).await?;\n\n    two::ActiveModel {\n        id: Set(2),\n        one_id: Set(1),\n        three_id: Set(3),\n    }\n    .insert(db)\n    .await?;\n\n    four::ActiveModel {\n        id: Set(4),\n        three_id: Set(Some(3)),\n    }\n    .insert(db)\n    .await?;\n\n    four::ActiveModel {\n        id: Set(44),\n        three_id: Set(None),\n    }\n    .insert(db)\n    .await?;\n\n    five::ActiveModel {\n        id: Set(5),\n        four_id: Set(4),\n    }\n    .insert(db)\n    .await?;\n\n    five::ActiveModel {\n        id: Set(55),\n        four_id: Set(44),\n    }\n    .insert(db)\n    .await?;\n\n    six::ActiveModel {\n        id: Set(6),\n        one_id: Set(1),\n        five_id: Set(55),\n    }\n    .insert(db)\n    .await?;\n\n    let one = one::Entity::find()\n        .order_by_id_asc()\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(one.id, 1);\n\n    let two = two::Entity::find()\n        .order_by_id_asc()\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(two.id, 2);\n\n    let three = three::Entity::find()\n        .order_by_id_asc()\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(three.id, 3);\n\n    let four = four::Entity::find()\n        .order_by_id_asc()\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(four.id, 4);\n\n    let five = five::Entity::find()\n        .order_by_id_asc()\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(five.id, 5);\n\n    let six = six::Entity::find()\n        .order_by_id_asc()\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(six.id, 6);\n\n    let (one, two) = one::Entity::find()\n        .find_also(one::Entity, two::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(one.id, 1);\n    assert_eq!(two.unwrap().id, 2);\n\n    let (one, two, three) = one::Entity::find()\n        .find_also(one::Entity, two::Entity)\n        .find_also(two::Entity, three::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(one.id, 1);\n    assert_eq!(two.unwrap().id, 2);\n    assert_eq!(three.unwrap().id, 3);\n\n    let (two, one, three) = two::Entity::find()\n        .find_also_related(one::Entity)\n        .find_also_related(three::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(one.unwrap().id, 1);\n    assert_eq!(two.id, 2);\n    assert_eq!(three.unwrap().id, 3);\n\n    let (one, two, three, four) = one::Entity::find()\n        .find_also(one::Entity, two::Entity)\n        .find_also(two::Entity, three::Entity)\n        .find_also(three::Entity, four::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(one.id, 1);\n    assert_eq!(two.unwrap().id, 2);\n    assert_eq!(three.unwrap().id, 3);\n    assert_eq!(four.unwrap().id, 4);\n\n    let (one, two, three, six) = one::Entity::find()\n        .find_also(one::Entity, two::Entity)\n        .find_also(two::Entity, three::Entity)\n        .find_also(one::Entity, six::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(one.id, 1);\n    assert_eq!(two.unwrap().id, 2);\n    assert_eq!(three.unwrap().id, 3);\n    assert_eq!(six.unwrap().id, 6);\n\n    let (one, two, three, four, five) = one::Entity::find()\n        .find_also(one::Entity, two::Entity)\n        .find_also(two::Entity, three::Entity)\n        .find_also(three::Entity, four::Entity)\n        .find_also(four::Entity, five::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(one.id, 1);\n    assert_eq!(two.unwrap().id, 2);\n    assert_eq!(three.unwrap().id, 3);\n    assert_eq!(four.unwrap().id, 4);\n    assert_eq!(five.unwrap().id, 5);\n\n    let (one, two, three, four, five, six) = one::Entity::find()\n        .find_also(one::Entity, two::Entity)\n        .find_also(two::Entity, three::Entity)\n        .find_also(three::Entity, four::Entity)\n        .find_also(four::Entity, five::Entity)\n        .find_also(one::Entity, six::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(one.id, 1);\n    assert_eq!(two.unwrap().id, 2);\n    assert_eq!(three.unwrap().id, 3);\n    assert_eq!(four.unwrap().id, 4);\n    assert_eq!(five.unwrap().id, 5);\n    assert_eq!(six.unwrap().id, 6);\n\n    let (six, five, four) = six::Entity::find_by_id(6)\n        .find_also_related(five::Entity)\n        .and_also_related(four::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(four.unwrap().id, 44);\n    assert_eq!(five.unwrap().id, 55);\n    assert_eq!(six.id, 6);\n\n    let (four, five, six) = four::Entity::find_by_id(44)\n        .find_also_related(five::Entity)\n        .and_also_related(six::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(four.id, 44);\n    assert_eq!(five.unwrap().id, 55);\n    assert_eq!(six.unwrap().id, 6);\n\n    // below is EntityLoader\n\n    let one_ex = one::Entity::load().one(db).await?.unwrap();\n    assert_eq!(one_ex.id, 1);\n\n    let one_ex = one::Entity::load()\n        .with(two::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(one_ex.id, 1);\n    assert_eq!(one_ex.two.unwrap().id, 2);\n\n    let one_ex = one::Entity::load()\n        .with((two::Entity, three::Entity))\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(one_ex.id, 1);\n    let two = one_ex.two.unwrap();\n    assert_eq!(two.id, 2);\n    assert_eq!(two.three.unwrap().id, 3);\n\n    let one_ex = one::Entity::load()\n        .with(six::Entity)\n        .with((two::Entity, three::Entity))\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(one_ex.id, 1);\n    let two = one_ex.two.unwrap();\n    assert_eq!(two.id, 2);\n    assert_eq!(two.three.unwrap().id, 3);\n    let six = one_ex.six.unwrap();\n    assert_eq!(six.id, 6);\n\n    let one_ex = one::Entity::load()\n        .with((six::Entity, five::Entity))\n        .with((two::Entity, three::Entity))\n        .one(db)\n        .await?\n        .unwrap();\n    assert_eq!(one_ex.id, 1);\n    let two = one_ex.two.unwrap();\n    assert_eq!(two.id, 2);\n    assert_eq!(two.three.unwrap().id, 3);\n    let six = one_ex.six.unwrap();\n    assert_eq!(six.id, 6);\n    assert_eq!(six.five.unwrap().id, 55);\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn test_composite_foreign_key() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"test_composite_foreign_key\").await;\n    let db = &ctx.db;\n\n    #[cfg(not(feature = \"schema-sync\"))]\n    {\n        db.get_schema_builder()\n            .register(composite_b::Entity)\n            .register(composite_a::Entity) // should create a first\n            .apply(db)\n            .await?;\n    }\n\n    #[cfg(feature = \"schema-sync\")]\n    {\n        // create 1 table only\n        db.get_schema_builder()\n            .register(composite_a::Entity)\n            .apply(db)\n            .await?;\n\n        // this incrementally creates the 2nd table without index\n        if db.get_database_backend() != sea_orm::DbBackend::Sqlite {\n            db.get_schema_builder()\n                .register(composite_a::Entity)\n                .register(composite_b_without_index::Entity)\n                .sync(db)\n                .await?;\n        }\n\n        // this creates the full 2nd table\n        db.get_schema_builder()\n            .register(composite_a::Entity)\n            .register(composite_b::Entity)\n            .register(composite_c::Entity)\n            .sync(db)\n            .await?;\n\n        // sync again just to be sure\n        db.get_schema_builder()\n            .register(composite_a::Entity)\n            .register(composite_b::Entity)\n            .register(composite_c::Entity)\n            .sync(db)\n            .await?;\n\n        #[cfg(feature = \"sqlx-postgres\")]\n        {\n            let has_index: bool = db\n                .query_one(\n                    Query::select()\n                        .expr(Expr::cust(\"COUNT(*) > 0\"))\n                        .from(\"pg_indexes\")\n                        .cond_where(\n                            Condition::all()\n                                .add(Expr::cust(\"schemaname = CURRENT_SCHEMA()\"))\n                                .add(Expr::col(\"tablename\").eq(\"composite_c\"))\n                                .add(Expr::col(\"indexname\").eq(\"idx-composite_c-season_episode\")),\n                        ),\n                )\n                .await?\n                .unwrap()\n                .try_get_by_index(0)\n                .unwrap();\n\n            assert!(has_index, \"Should have index on `composite_c`\");\n        }\n    }\n\n    composite_a::ActiveModel {\n        id: Set(100),\n        left_id: Set(1),\n        right_id: Set(2),\n    }\n    .insert(db)\n    .await?;\n    composite_a::ActiveModel {\n        id: Set(101),\n        left_id: Set(1),\n        right_id: Set(3),\n    }\n    .insert(db)\n    .await?;\n    composite_a::ActiveModel {\n        id: Set(102),\n        left_id: Set(2),\n        right_id: Set(3),\n    }\n    .insert(db)\n    .await?;\n    composite_b::ActiveModel {\n        id: Set(200),\n        left_id: Set(1),\n        right_id: Set(2),\n    }\n    .insert(db)\n    .await?;\n    composite_b::ActiveModel {\n        id: Set(202),\n        left_id: Set(2),\n        right_id: Set(3),\n    }\n    .insert(db)\n    .await?;\n\n    let a = composite_a::Entity::find_by_id(100).one(db).await?.unwrap();\n    assert_eq!(a.left_id, 1);\n    assert_eq!(a.right_id, 2);\n    #[rustfmt::skip]\n    assert_eq!(composite_a::Entity::find_by_pair((1, 3)).one(db).await?.unwrap().id, 101);\n    #[rustfmt::skip]\n    assert_eq!(composite_a::Entity::load().filter_by_pair((1, 3)).one(db).await?.unwrap().id, 101);\n\n    let Some((a, Some(b))) = composite_a::Entity::find_by_id(100)\n        .find_also_related(composite_b::Entity)\n        .one(db)\n        .await?\n    else {\n        panic!(\"query error\")\n    };\n    assert_eq!(a.left_id, 1);\n    assert_eq!(a.right_id, 2);\n    assert_eq!(b.id, 200);\n    assert_eq!(b.left_id, 1);\n    assert_eq!(b.right_id, 2);\n\n    let a = composite_a::Entity::load()\n        .filter_by_id(101)\n        .with(composite_b::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(a.id, 101);\n    assert!(a.b.is_not_found());\n\n    let a = composite_a::Entity::load()\n        .filter_by_id(102)\n        .with(composite_b::Entity)\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(a.id, 102);\n    assert_eq!(a.left_id, 2);\n    assert_eq!(a.right_id, 3);\n    assert_eq!(a.b.unwrap().id, 202);\n\n    assert_eq!(\n        composite_b::Entity::delete_by_id(202)\n            .exec(db)\n            .await?\n            .rows_affected,\n        1\n    );\n\n    assert_eq!(\n        composite_a::Entity::delete_by_pair((2, 3))\n            .exec(db)\n            .await?\n            .rows_affected,\n        1\n    );\n\n    assert!(\n        composite_a::Entity::find_by_id(102)\n            .one(db)\n            .await?\n            .is_none()\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/paginator_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{PaginatorTrait, QueryOrder, Set, entity::prelude::*};\n\n#[sea_orm_macros::test]\nasync fn paginator_tests() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"paginator_tests\").await;\n    create_insert_default_table(&ctx.db).await?;\n    create_insert_default(&ctx.db).await?;\n    paginator_num_items(&ctx.db).await?;\n    paginator_num_pages(&ctx.db).await?;\n    paginator_num_items_and_pages(&ctx.db).await?;\n    paginator_fetch_page(&ctx.db).await?;\n    paginator_count(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    for _ in 0..10 {\n        ActiveModel {\n            ..Default::default()\n        }\n        .insert(db)\n        .await?;\n    }\n\n    assert_eq!(\n        Entity::find().all(db).await?,\n        [\n            Model { id: 1 },\n            Model { id: 2 },\n            Model { id: 3 },\n            Model { id: 4 },\n            Model { id: 5 },\n            Model { id: 6 },\n            Model { id: 7 },\n            Model { id: 8 },\n            Model { id: 9 },\n            Model { id: 10 },\n        ]\n    );\n\n    Ok(())\n}\n\npub async fn paginator_num_items(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 3);\n    assert_eq!(paginator.num_items().await?, 10);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 5);\n    assert_eq!(paginator.num_items().await?, 10);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 10);\n    assert_eq!(paginator.num_items().await?, 10);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 100);\n    assert_eq!(paginator.num_items().await?, 10);\n\n    Ok(())\n}\n\npub async fn paginator_num_pages(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 3);\n    assert_eq!(paginator.num_pages().await?, 4);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 5);\n    assert_eq!(paginator.num_pages().await?, 2);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 10);\n    assert_eq!(paginator.num_pages().await?, 1);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 7);\n    assert_eq!(paginator.num_pages().await?, 2);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 100);\n    assert_eq!(paginator.num_pages().await?, 1);\n\n    Ok(())\n}\n\npub async fn paginator_num_items_and_pages(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 3);\n\n    let result = paginator.num_items_and_pages().await?;\n    assert_eq!(result.number_of_items, 10);\n    assert_eq!(result.number_of_pages, 4);\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 5);\n\n    let result = paginator.num_items_and_pages().await?;\n    assert_eq!(result.number_of_items, 10);\n    assert_eq!(result.number_of_pages, 2);\n\n    Ok(())\n}\n\npub async fn paginator_fetch_page(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    let paginator = Entity::find().order_by_asc(Column::Id).paginate(db, 3);\n\n    assert_eq!(\n        paginator.fetch_page(0).await?,\n        vec![Model { id: 1 }, Model { id: 2 }, Model { id: 3 }]\n    );\n\n    assert_eq!(\n        paginator.fetch_page(1).await?,\n        vec![Model { id: 4 }, Model { id: 5 }, Model { id: 6 }]\n    );\n\n    assert_eq!(\n        paginator.fetch_page(2).await?,\n        vec![Model { id: 7 }, Model { id: 8 }, Model { id: 9 }]\n    );\n\n    assert_eq!(paginator.fetch_page(3).await?, vec![Model { id: 10 }]);\n\n    assert!(paginator.fetch_page(4).await?.is_empty());\n\n    Ok(())\n}\n\npub async fn paginator_count(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    assert_eq!(Entity::find().count(db).await?, 10);\n\n    assert_eq!(Entity::find().filter(Column::Id.gt(5)).count(db).await?, 5);\n\n    assert_eq!(Entity::find().filter(Column::Id.lte(3)).count(db).await?, 3);\n\n    assert_eq!(\n        Entity::find().filter(Column::Id.gt(100)).count(db).await?,\n        0\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/parallel_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, IntoActiveModel, Set, entity::prelude::*};\n\n#[sea_orm_macros::test]\n#[cfg(not(feature = \"sync\"))]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"features_parallel_tests\").await;\n    create_metadata_table(&ctx.db).await?;\n    crud_in_parallel(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\n#[cfg(not(feature = \"sync\"))]\npub async fn crud_in_parallel(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let metadata = [\n        metadata::Model {\n            uuid: Uuid::new_v4(),\n            ty: \"Type\".to_owned(),\n            key: \"markup\".to_owned(),\n            value: \"1.18\".to_owned(),\n            bytes: vec![1, 2, 3],\n            date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()),\n            time: Some(Time::from_hms_opt(11, 32, 55).unwrap()),\n        },\n        metadata::Model {\n            uuid: Uuid::new_v4(),\n            ty: \"Type\".to_owned(),\n            key: \"exchange_rate\".to_owned(),\n            value: \"0.78\".to_owned(),\n            bytes: vec![1, 2, 3],\n            date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()),\n            time: Some(Time::from_hms_opt(11, 32, 55).unwrap()),\n        },\n        metadata::Model {\n            uuid: Uuid::new_v4(),\n            ty: \"Type\".to_owned(),\n            key: \"service_charge\".to_owned(),\n            value: \"1.1\".to_owned(),\n            bytes: vec![1, 2, 3],\n            date: None,\n            time: None,\n        },\n    ];\n\n    let _insert_res = futures_util::future::try_join_all([\n        metadata[0].clone().into_active_model().insert(db),\n        metadata[1].clone().into_active_model().insert(db),\n        metadata[2].clone().into_active_model().insert(db),\n    ])\n    .await?;\n\n    let find_res = futures_util::future::try_join_all([\n        Metadata::find_by_id(metadata[0].uuid).one(db),\n        Metadata::find_by_id(metadata[1].uuid).one(db),\n        Metadata::find_by_id(metadata[2].uuid).one(db),\n    ])\n    .await?;\n\n    assert_eq!(\n        metadata,\n        [\n            find_res[0].clone().unwrap(),\n            find_res[1].clone().unwrap(),\n            find_res[2].clone().unwrap(),\n        ]\n    );\n\n    let mut active_models = (\n        find_res[0].clone().unwrap().into_active_model(),\n        find_res[1].clone().unwrap().into_active_model(),\n        find_res[2].clone().unwrap().into_active_model(),\n    );\n\n    active_models.0.bytes = Set(vec![0]);\n    active_models.1.bytes = Set(vec![1]);\n    active_models.2.bytes = Set(vec![2]);\n\n    let _update_res = futures_util::future::try_join_all([\n        active_models.0.clone().update(db),\n        active_models.1.clone().update(db),\n        active_models.2.clone().update(db),\n    ])\n    .await?;\n\n    let find_res = futures_util::future::try_join_all([\n        Metadata::find_by_id(metadata[0].uuid).one(db),\n        Metadata::find_by_id(metadata[1].uuid).one(db),\n        Metadata::find_by_id(metadata[2].uuid).one(db),\n    ])\n    .await?;\n\n    assert_eq!(\n        [\n            active_models.0.bytes.clone().unwrap(),\n            active_models.1.bytes.clone().unwrap(),\n            active_models.2.bytes.clone().unwrap(),\n        ],\n        [\n            find_res[0].clone().unwrap().bytes,\n            find_res[1].clone().unwrap().bytes,\n            find_res[2].clone().unwrap().bytes,\n        ]\n    );\n\n    let _delete_res = futures_util::future::try_join_all([\n        active_models.0.delete(db),\n        active_models.1.delete(db),\n        active_models.2.delete(db),\n    ])\n    .await?;\n\n    assert_eq!(Metadata::find().all(db).await?, []);\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/partial_model_nested/local/mod.rs",
    "content": "mod model;\n\npub use model::*;\n\npub use model::schema::create_tables;\n"
  },
  {
    "path": "tests/partial_model_nested/local/model/bakery.rs",
    "content": "use sea_orm::entity::prelude::*;\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]\n#[sea_orm(table_name = \"bakery\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    pub profit_margin: f64,\n    pub manager_id: i32,\n    pub cashier_id: i32,\n    #[sea_orm(belongs_to, relation_enum = \"Manager\", from = \"manager_id\", to = \"id\")]\n    pub manager: HasOne<super::worker::Entity>,\n    #[sea_orm(belongs_to, relation_enum = \"Cashier\", from = \"cashier_id\", to = \"id\")]\n    pub cashier: HasOne<super::worker::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/partial_model_nested/local/model/mod.rs",
    "content": "pub mod bakery;\npub mod schema;\npub mod worker;\n"
  },
  {
    "path": "tests/partial_model_nested/local/model/schema.rs",
    "content": "use crate::common::setup::create_table;\nuse crate::local::{bakery, worker};\nuse sea_orm::{DatabaseConnection, DbConn, ExecResult, error::*, sea_query};\nuse sea_query::{ColumnDef, ForeignKey, ForeignKeyAction, Index, Table};\n\npub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> {\n    create_worker_table(db).await?;\n    create_bakery_table(db).await?;\n    Ok(())\n}\n\npub async fn create_bakery_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(bakery::Entity)\n        .col(\n            ColumnDef::new(bakery::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(bakery::Column::Name).string().not_null())\n        .col(\n            ColumnDef::new(bakery::Column::ProfitMargin)\n                .double()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(bakery::Column::ManagerId)\n                .integer()\n                .not_null(),\n        )\n        .col(\n            ColumnDef::new(bakery::Column::CashierId)\n                .integer()\n                .not_null(),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-bakery-manager_id\")\n                .from(bakery::Entity, bakery::Column::ManagerId)\n                .to(worker::Entity, worker::Column::Id),\n        )\n        .foreign_key(\n            ForeignKey::create()\n                .name(\"fk-bakery-cashier_id\")\n                .from(bakery::Entity, bakery::Column::CashierId)\n                .to(worker::Entity, worker::Column::Id),\n        )\n        .to_owned();\n\n    create_table(db, &stmt, bakery::Entity).await\n}\n\npub async fn create_worker_table(db: &DbConn) -> Result<ExecResult, DbErr> {\n    let stmt = Table::create()\n        .table(worker::Entity)\n        .col(\n            ColumnDef::new(worker::Column::Id)\n                .integer()\n                .not_null()\n                .auto_increment()\n                .primary_key(),\n        )\n        .col(ColumnDef::new(worker::Column::Name).string().not_null())\n        .to_owned();\n\n    create_table(db, &stmt, worker::Entity).await\n}\n"
  },
  {
    "path": "tests/partial_model_nested/local/model/worker.rs",
    "content": "use sea_orm::{ActiveValue, entity::prelude::*};\n\n#[sea_orm::model]\n#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n#[sea_orm(table_name = \"worker\")]\npub struct Model {\n    #[sea_orm(primary_key)]\n    pub id: i32,\n    pub name: String,\n    #[sea_orm(has_many, relation_enum = \"BakeryManager\", via_rel = \"Manager\")]\n    pub manager_of: HasMany<super::bakery::Entity>,\n    #[sea_orm(has_many, relation_enum = \"BakeryCashier\", via_rel = \"Cashier\")]\n    pub cashier_of: HasMany<super::bakery::Entity>,\n}\n\nimpl ActiveModelBehavior for ActiveModel {}\n"
  },
  {
    "path": "tests/partial_model_nested/main.rs",
    "content": "mod local;\nmod nested_alias;\n\n#[path = \"../common/mod.rs\"]\n#[allow(unused)]\nmod common;\n"
  },
  {
    "path": "tests/partial_model_nested/nested_alias.rs",
    "content": "use crate::common::TestContext;\nuse crate::local::{bakery, create_tables, worker};\nuse sea_orm::{\n    DbBackend, DerivePartialModel, IntoActiveModel, JoinType, NotSet, QueryOrder, QuerySelect,\n    QueryTrait, Set, prelude::*, sea_query::Alias,\n};\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"worker::Entity\")]\nstruct Worker {\n    id: i32,\n    name: String,\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"bakery::Entity\")]\nstruct BakeryWorker {\n    id: i32,\n    name: String,\n    profit_margin: f64,\n    #[sea_orm(nested, alias = \"manager\")]\n    manager: Worker,\n    #[sea_orm(nested, alias = \"cashier\")]\n    cashier: worker::Model,\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"worker::Entity\")]\nstruct ManagerOfBakery {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: bakery::Model,\n}\n\n#[sea_orm_macros::test]\nasync fn partial_model_nested_alias() {\n    let ctx = TestContext::new(\"partial_model_nested\").await;\n    create_tables(&ctx.db)\n        .await\n        .expect(\"unable to create tables\");\n\n    // TODO: init utils\n\n    worker::Entity::insert(worker::ActiveModel {\n        id: Set(1),\n        name: Set(\"Tom\".to_owned()),\n        ..Default::default()\n    })\n    .exec(&ctx.db)\n    .await\n    .expect(\"insert succeeds\");\n\n    worker::Entity::insert(worker::ActiveModel {\n        id: Set(2),\n        name: Set(\"Jerry\".to_owned()),\n        ..Default::default()\n    })\n    .exec(&ctx.db)\n    .await\n    .expect(\"insert succeeds\");\n\n    bakery::Entity::insert(bakery::ActiveModel {\n        id: Set(42),\n        name: Set(\"Master Bakery\".to_string()),\n        profit_margin: Set(4.1),\n        manager_id: Set(1),\n        cashier_id: Set(2),\n    })\n    .exec(&ctx.db)\n    .await\n    .expect(\"insert succeeds\");\n\n    let selector = bakery::Entity::find()\n        .join_as(\n            sea_orm::JoinType::LeftJoin,\n            bakery::Relation::Manager.def(),\n            \"manager\",\n        )\n        .join_as(\n            sea_orm::JoinType::LeftJoin,\n            bakery::Relation::Cashier.def(),\n            \"cashier\",\n        );\n\n    assert_eq!(\n        selector.build(DbBackend::MySql).to_string(),\n        \"SELECT `bakery`.`id`, `bakery`.`name`, `bakery`.`profit_margin`, `bakery`.`manager_id`, `bakery`.`cashier_id` FROM `bakery` LEFT JOIN `worker` AS `manager` ON `bakery`.`manager_id` = `manager`.`id` LEFT JOIN `worker` AS `cashier` ON `bakery`.`cashier_id` = `cashier`.`id`\"\n    );\n\n    let bakery: BakeryWorker = selector\n        .into_partial_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.manager.name, \"Tom\");\n    assert_eq!(bakery.cashier.name, \"Jerry\");\n\n    let selector = worker::Entity::find().join(\n        sea_orm::JoinType::LeftJoin,\n        worker::Relation::BakeryManager.def(),\n    );\n\n    assert_eq!(\n        selector.build(DbBackend::MySql).to_string(),\n        \"SELECT `worker`.`id`, `worker`.`name` FROM `worker` LEFT JOIN `bakery` ON `worker`.`id` = `bakery`.`manager_id`\"\n    );\n\n    let manager: ManagerOfBakery = selector\n        .into_partial_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(manager.name, \"Tom\");\n    assert_eq!(manager.bakery.name, \"Master Bakery\");\n\n    ctx.delete().await;\n}\n"
  },
  {
    "path": "tests/partial_model_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\nuse entity::{Column, Entity};\nuse sea_orm::{\n    DerivePartialModel, IntoActiveModel, JoinType, NotSet, QueryOrder, QuerySelect, Set,\n    prelude::*, sea_query::Alias,\n};\nuse sea_query::ExprTrait;\n\nuse crate::common::TestContext;\nuse common::bakery_chain::*;\n\nmod common;\n\nmod entity {\n    use sea_orm::prelude::*;\n\n    #[derive(Debug, Clone, DeriveEntityModel)]\n    #[sea_orm(table_name = \"foo_table\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        id: i32,\n        foo: i32,\n        bar: String,\n        foo2: bool,\n        bar2: f64,\n    }\n\n    #[derive(Debug, DeriveRelation, EnumIter)]\n    pub enum Relation {}\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"Entity\")]\nstruct SimpleTest {\n    foo: i32,\n    bar: String,\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"<entity::Model as ModelTrait>::Entity\")]\nstruct EntityNameNotAIdent {\n    #[sea_orm(from_col = \"foo2\")]\n    foo: i32,\n    #[sea_orm(from_col = \"bar2\")]\n    bar: String,\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"Entity\")]\nstruct FieldFromDiffNameColumnTest {\n    #[sea_orm(from_col = \"foo2\")]\n    foo: i32,\n    #[sea_orm(from_col = \"bar2\")]\n    bar: String,\n}\n\n#[derive(DerivePartialModel)]\nstruct FieldFromExpr {\n    #[sea_orm(from_expr = \"Column::Bar2.sum()\")]\n    foo: f64,\n    #[sea_orm(from_expr = \"Expr::col(Column::Id).equals(Column::Foo)\")]\n    bar: bool,\n}\n\n#[derive(DerivePartialModel)]\nstruct Nest {\n    #[sea_orm(nested)]\n    foo: SimpleTest,\n}\n\n#[derive(DerivePartialModel)]\nstruct NestOption {\n    #[sea_orm(nested)]\n    foo: Option<SimpleTest>,\n}\n\n#[derive(Debug, DerivePartialModel)]\n#[sea_orm(entity = \"bakery::Entity\")]\nstruct Bakery {\n    id: i32,\n    #[sea_orm(from_col = \"Name\")]\n    title: String,\n}\n\n#[derive(Debug, DerivePartialModel)]\n#[sea_orm(entity = \"cake::Entity\", into_active_model)]\nstruct Cake {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<Bakery>,\n    #[sea_orm(skip)]\n    ignore: Ignore,\n}\n\n#[derive(DerivePartialModel)]\n#[sea_orm(entity = \"bakery::Entity\")]\nstruct BakeryDetails {\n    #[sea_orm(nested)]\n    basics: Bakery,\n    #[sea_orm(from_expr = \"bakery::Column::ProfitMargin\")]\n    profit: f64,\n}\n\n#[derive(Debug, Default, PartialEq, Eq)]\nstruct Ignore {}\n\n#[sea_orm_macros::test]\nasync fn partial_model_left_join_does_not_exist() {\n    let ctx = TestContext::new(\"partial_model_left_join_does_not_exist\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, false).await;\n\n    let cake: Cake = cake::Entity::find()\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert!(cake.bakery.is_none());\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn partial_model_left_join_exists() {\n    let ctx = TestContext::new(\"partial_model_left_join_exists\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    let cake: Cake = cake::Entity::find()\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert!(matches!(cake.bakery, Some(Bakery { id: 42, .. })));\n    assert_eq!(cake.bakery.as_ref().unwrap().title, \"cool little bakery\");\n\n    #[derive(Debug, DerivePartialModel)]\n    #[sea_orm(entity = \"cake::Entity\", into_active_model)]\n    struct Cake2 {\n        id: i32,\n        name: String,\n        #[sea_orm(nested, alias = \"r0\")]\n        bakery: Option<Bakery>,\n        #[sea_orm(skip)]\n        ignore: Ignore,\n    }\n\n    let cake2: Cake2 = cake::Entity::find()\n        .left_join_linked(cake::ToBakery)\n        .order_by_asc(cake::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(\n        format!(\"{cake:?}\").trim_start_matches(\"Cake \"),\n        format!(\"{cake2:?}\").trim_start_matches(\"Cake2 \")\n    );\n\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"cake::Entity\")]\n    struct Cake3 {\n        id: i32,\n        name: String,\n        #[sea_orm(nested)]\n        bakery: Option<bakery::Model>,\n    }\n\n    let cake: Cake3 = cake::Entity::find()\n        .left_join(bakery::Entity)\n        .order_by_asc(cake::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert_eq!(\n        cake.bakery.unwrap(),\n        bakery::Model {\n            id: 42,\n            name: \"cool little bakery\".to_string(),\n            profit_margin: 4.1,\n        }\n    );\n\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"cake::Entity\")]\n    struct Cake4 {\n        id: i32,\n        price: Decimal,\n        #[sea_orm(from_expr = \"cake::COLUMN.price.add(\\\"0.2\\\".parse::<Decimal>().unwrap())\")]\n        price_vat: Decimal,\n    }\n\n    let cake: Cake4 = cake::Entity::find()\n        .order_by_asc(cake::COLUMN.id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.price, \"2\".parse().unwrap());\n    assert_eq!(cake.price_vat, \"2.2\".parse().unwrap());\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn model_as_partial_model() {\n    let ctx = TestContext::new(\"model_as_partial_model\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, false).await;\n\n    let bakery: bakery::Model = bakery::Entity::find()\n        .order_by_asc(bakery::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(\n        bakery,\n        bakery::Model {\n            id: 42,\n            name: \"cool little bakery\".to_string(),\n            profit_margin: 4.1,\n        }\n    );\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn partial_model_left_join_alias() {\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"bakery::Entity\")]\n    struct Factory {\n        id: i32,\n        #[sea_orm(from_col = \"name\")]\n        plant: String,\n    }\n\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"cake::Entity\")]\n    struct CakeFactory {\n        id: i32,\n        name: String,\n        #[sea_orm(nested, alias = \"factory\")]\n        bakery: Option<Factory>,\n    }\n\n    // SELECT \"cake\".\"id\" AS \"id\", \"cake\".\"name\" AS \"name\", \"factory\".\"id\" AS \"bakery_id\", \"factory\".\"name\" AS \"bakery_plant\" FROM \"cake\" LEFT JOIN \"bakery\" AS \"factory\" ON \"cake\".\"bakery_id\" = \"factory\".\"id\" LIMIT 1\n    let ctx = TestContext::new(\"partial_model_left_join_alias\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    let cake: CakeFactory = cake::Entity::find()\n        .join_as(JoinType::LeftJoin, cake::Relation::Bakery.def(), \"factory\")\n        .order_by_asc(cake::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert!(matches!(cake.bakery, Some(Factory { id: 42, .. })));\n    assert_eq!(cake.bakery.unwrap().plant, \"cool little bakery\");\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn partial_model_left_join_alias_old() {\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"bakery::Entity\", alias = \"factory\")]\n    struct Factory {\n        id: i32,\n        #[sea_orm(from_col = \"name\")]\n        plant: String,\n    }\n\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"cake::Entity\")]\n    struct CakeFactory {\n        id: i32,\n        name: String,\n        #[sea_orm(nested)]\n        bakery: Option<Factory>,\n    }\n\n    let ctx = TestContext::new(\"partial_model_left_join_alias_old\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    let cake: CakeFactory = cake::Entity::find()\n        .join_as(JoinType::LeftJoin, cake::Relation::Bakery.def(), \"factory\")\n        .order_by_asc(cake::Column::Id)\n        .into_partial_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(cake.id, 13);\n    assert_eq!(cake.name, \"Cheesecake\");\n    assert!(matches!(cake.bakery, Some(Factory { id: 42, .. })));\n    assert_eq!(cake.bakery.unwrap().plant, \"cool little bakery\");\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn partial_model_flat() {\n    let ctx = TestContext::new(\"partial_model_flat\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    let bakery: Bakery = bakery::Entity::find()\n        .into_partial_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.title, \"cool little bakery\");\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn partial_model_nested() {\n    // SELECT \"bakery\".\"id\" AS \"basics_id\", \"bakery\".\"name\" AS \"basics_title\", \"bakery\".\"profit_margin\" AS \"profit\" FROM \"bakery\" LIMIT 1\n    let ctx = TestContext::new(\"partial_model_nested\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    let bakery: BakeryDetails = bakery::Entity::find()\n        .into_partial_model()\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.basics.id, 42);\n    assert_eq!(bakery.basics.title, \"cool little bakery\");\n    assert_eq!(bakery.profit, 4.1);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn partial_model_join_three() {\n    let ctx = TestContext::new(\"partial_model_join_three\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"order::Entity\")]\n    struct OrderItem {\n        id: i32,\n        total: Decimal,\n        #[sea_orm(nested)]\n        customer: Customer,\n        #[sea_orm(nested)]\n        line: LineItem,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"customer::Entity\")]\n    struct Customer {\n        name: String,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"lineitem::Entity\")]\n    struct LineItem {\n        price: Decimal,\n        quantity: i32,\n        #[sea_orm(nested)]\n        cake: Cake,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"cake::Entity\")]\n    struct Cake {\n        name: String,\n    }\n\n    let items: Vec<OrderItem> = order::Entity::find()\n        .left_join(customer::Entity)\n        .left_join(lineitem::Entity)\n        .join(JoinType::LeftJoin, lineitem::Relation::Cake.def())\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .into_partial_model()\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(\n        items,\n        [\n            OrderItem {\n                id: 101,\n                total: Decimal::from(10),\n                customer: Customer {\n                    name: \"Bob\".to_owned()\n                },\n                line: LineItem {\n                    cake: Cake {\n                        name: \"Cheesecake\".to_owned()\n                    },\n                    price: Decimal::from(2),\n                    quantity: 2,\n                }\n            },\n            OrderItem {\n                id: 101,\n                total: Decimal::from(10),\n                customer: Customer {\n                    name: \"Bob\".to_owned()\n                },\n                line: LineItem {\n                    cake: Cake {\n                        name: \"Chocolate\".to_owned()\n                    },\n                    price: Decimal::from(3),\n                    quantity: 2,\n                }\n            }\n        ]\n    );\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn partial_model_join_three_flat() {\n    let ctx = TestContext::new(\"partial_model_join_three_flat\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"order::Entity\")]\n    struct OrderItem {\n        #[sea_orm(nested)]\n        order: Order,\n        #[sea_orm(nested)]\n        customer: Customer,\n        #[sea_orm(nested)]\n        line: LineItem,\n        #[sea_orm(nested)]\n        cake: Cake,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"order::Entity\")]\n    struct Order {\n        #[sea_orm(from_col = \"id\")]\n        order_id: i32,\n        total: Decimal,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"customer::Entity\")]\n    struct Customer {\n        name: String,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"lineitem::Entity\")]\n    struct LineItem {\n        price: Decimal,\n        quantity: i32,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"cake::Entity\")]\n    struct Cake {\n        name: String,\n    }\n\n    let items: Vec<OrderItem> = order::Entity::find()\n        .left_join(customer::Entity)\n        .left_join(lineitem::Entity)\n        .join(JoinType::LeftJoin, lineitem::Relation::Cake.def())\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .into_partial_model()\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(\n        items,\n        [\n            OrderItem {\n                order: Order {\n                    order_id: 101,\n                    total: Decimal::from(10),\n                },\n                customer: Customer {\n                    name: \"Bob\".to_owned()\n                },\n                line: LineItem {\n                    price: Decimal::from(2),\n                    quantity: 2,\n                },\n                cake: Cake {\n                    name: \"Cheesecake\".to_owned()\n                },\n            },\n            OrderItem {\n                order: Order {\n                    order_id: 101,\n                    total: Decimal::from(10),\n                },\n                customer: Customer {\n                    name: \"Bob\".to_owned()\n                },\n                line: LineItem {\n                    price: Decimal::from(3),\n                    quantity: 2,\n                },\n                cake: Cake {\n                    name: \"Chocolate\".to_owned()\n                },\n            }\n        ]\n    );\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn partial_model_join_two_linked() {\n    let ctx = TestContext::new(\"partial_model_join_two_linked\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"order::Entity\")]\n    struct OrderItem {\n        #[sea_orm(nested)]\n        order: Order,\n        #[sea_orm(nested, alias = \"r0\")]\n        customer: Customer,\n        #[sea_orm(nested, alias = \"r1\")]\n        line: LineItem,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"order::Entity\")]\n    struct Order {\n        #[sea_orm(from_col = \"id\")]\n        order_id: i32,\n        total: Decimal,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"customer::Entity\")]\n    struct Customer {\n        name: String,\n    }\n\n    #[derive(Debug, DerivePartialModel, PartialEq)]\n    #[sea_orm(entity = \"lineitem::Entity\")]\n    struct LineItem {\n        price: Decimal,\n        quantity: i32,\n    }\n\n    let items: Vec<OrderItem> = order::Entity::find()\n        .left_join_linked(order::ToCustomer)\n        .left_join_linked(order::ToLineitem)\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(Expr::col((\"r1\", lineitem::Column::Id)))\n        .into_partial_model()\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(\n        items,\n        [\n            OrderItem {\n                order: Order {\n                    order_id: 101,\n                    total: Decimal::from(10),\n                },\n                customer: Customer {\n                    name: \"Bob\".to_owned()\n                },\n                line: LineItem {\n                    price: Decimal::from(2),\n                    quantity: 2,\n                },\n            },\n            OrderItem {\n                order: Order {\n                    order_id: 101,\n                    total: Decimal::from(10),\n                },\n                customer: Customer {\n                    name: \"Bob\".to_owned()\n                },\n                line: LineItem {\n                    price: Decimal::from(3),\n                    quantity: 2,\n                },\n            }\n        ]\n    );\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\nasync fn partial_model_into_active_model() {\n    let mut cake = Cake {\n        id: 12,\n        name: \"Lemon Drizzle\".to_owned(),\n        bakery: None,\n        ignore: Ignore {},\n    }\n    .into_active_model();\n    cake.serial = NotSet;\n\n    assert_eq!(\n        cake,\n        cake::ActiveModel {\n            id: Set(12),\n            name: Set(\"Lemon Drizzle\".to_owned()),\n            serial: NotSet,\n            ..Default::default()\n        }\n    );\n\n    assert_eq!(\n        cake::ActiveModel {\n            ..cake.into_active_model()\n        },\n        cake::ActiveModel {\n            id: Set(12),\n            name: Set(\"Lemon Drizzle\".to_owned()),\n            serial: NotSet,\n            ..Default::default()\n        }\n    );\n}\n\n#[derive(Debug, DerivePartialModel)]\n#[sea_orm(entity = \"bakery::Entity\")]\nstruct WrongBakery {\n    id: String,\n    #[sea_orm(from_col = \"Name\")]\n    title: String,\n}\n\n#[derive(Debug, DerivePartialModel)]\n#[sea_orm(entity = \"cake::Entity\")]\nstruct WrongCake {\n    id: i32,\n    name: String,\n    #[sea_orm(nested)]\n    bakery: Option<WrongBakery>,\n}\n\n#[sea_orm_macros::test]\n#[ignore = \"This currently does not work, as sqlx does not perform type checking when a column is absent..\"]\nasync fn partial_model_optional_field_but_type_error() {\n    let ctx = TestContext::new(\"partial_model_nested\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, false).await;\n\n    let _: DbErr = cake::Entity::find()\n        .left_join(bakery::Entity)\n        .into_partial_model::<WrongCake>()\n        .one(&ctx.db)\n        .await\n        .expect_err(\"should error instead of returning an empty Option\");\n\n    ctx.delete().await;\n}\n"
  },
  {
    "path": "tests/pi_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\nuse std::str::FromStr;\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"with-bigdecimal\")]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"pi_tests\").await;\n    create_pi_table(&ctx.db).await?;\n    create_and_update_pi(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\n#[cfg(feature = \"with-bigdecimal\")]\npub async fn create_and_update_pi(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use pi::Entity as Pi;\n\n    fn trunc_dec_scale(mut model: pi::Model) -> pi::Model {\n        model.decimal = model.decimal.trunc_with_scale(3);\n        model.big_decimal = model.big_decimal.with_scale(3);\n        model.decimal_opt = model.decimal_opt.map(|decimal| decimal.trunc_with_scale(3));\n        model.big_decimal_opt = model\n            .big_decimal_opt\n            .map(|big_decimal| big_decimal.with_scale(3));\n        model\n    }\n\n    let pi = trunc_dec_scale(pi::Model {\n        id: 1,\n        decimal: rust_dec(3.1415926536),\n        big_decimal: BigDecimal::from_str(\"3.1415926536\").unwrap(),\n        decimal_opt: None,\n        big_decimal_opt: None,\n    });\n\n    let res = trunc_dec_scale(pi.clone().into_active_model().insert(db).await?);\n\n    let model = trunc_dec_scale(Pi::find().one(db).await?.unwrap());\n    assert_eq!(model, res);\n    assert_eq!(model, pi.clone());\n\n    let res = trunc_dec_scale(\n        pi::ActiveModel {\n            decimal_opt: Set(Some(rust_dec(3.1415926536))),\n            big_decimal_opt: Set(Some(BigDecimal::from_str(\"3.1415926536\").unwrap())),\n            ..pi.clone().into_active_model()\n        }\n        .update(db)\n        .await?,\n    );\n\n    let model = trunc_dec_scale(Pi::find().one(db).await?.unwrap());\n    assert_eq!(model, res);\n    assert_eq!(\n        model,\n        trunc_dec_scale(pi::Model {\n            id: 1,\n            decimal: rust_dec(3.1415926536),\n            big_decimal: BigDecimal::from_str(\"3.1415926536\").unwrap(),\n            decimal_opt: Some(rust_dec(3.1415926536)),\n            big_decimal_opt: Some(BigDecimal::from_str(\"3.1415926536\").unwrap()),\n        })\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/query_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, bakery_dense, setup::*};\npub use sea_orm::entity::*;\npub use sea_orm::{ConnectionTrait, QueryFilter, QuerySelect};\n\n// Run the test locally:\n// DATABASE_URL=\"mysql://root:@localhost\" cargo test --features sqlx-mysql,runtime-async-std --test query_tests\n#[sea_orm_macros::test]\npub async fn find_one_with_no_result() {\n    let ctx = TestContext::new(\"find_one_with_no_result\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let bakery = Bakery::find().one(&ctx.db).await.unwrap();\n    assert_eq!(bakery, None);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn find_one_with_result() {\n    let ctx = TestContext::new(\"find_one_with_result\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let result = Bakery::find().one(&ctx.db).await.unwrap().unwrap();\n\n    assert_eq!(result.id, bakery.id.unwrap());\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn find_by_id_with_no_result() {\n    let ctx = TestContext::new(\"find_by_id_with_no_result\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let bakery = Bakery::find_by_id(999).one(&ctx.db).await.unwrap();\n    assert_eq!(bakery, None);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn find_by_id_with_result() {\n    let ctx = TestContext::new(\"find_by_id_with_result\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let result = Bakery::find_by_id(bakery.id.clone().unwrap())\n        .one(&ctx.db)\n        .await\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(result.id, bakery.id.unwrap());\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn find_all_with_no_result() {\n    let ctx = TestContext::new(\"find_all_with_no_result\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let bakeries = Bakery::find().all(&ctx.db).await.unwrap();\n    assert_eq!(bakeries.len(), 0);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn find_all_with_result() {\n    let ctx = TestContext::new(\"find_all_with_result\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let _ = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let _ = bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let bakeries = Bakery::find().all(&ctx.db).await.unwrap();\n\n    assert_eq!(bakeries.len(), 2);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn find_all_filter_no_result() {\n    let ctx = TestContext::new(\"find_all_filter_no_result\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let _ = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let _ = bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let bakeries = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Good\"))\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(bakeries.len(), 0);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn find_all_filter_with_results() {\n    let ctx = TestContext::new(\"find_all_filter_with_results\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let _ = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let _ = bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let bakeries = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Bakery\"))\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(bakeries.len(), 2);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn select_only_exclude_option_fields() {\n    let ctx = TestContext::new(\"select_only_exclude_option_fields\").await;\n    create_customer_table(&ctx.db).await.unwrap();\n\n    let _ = customer::ActiveModel {\n        name: Set(\"Alice\".to_owned()),\n        notes: Set(Some(\"Want to communicate with Bob\".to_owned())),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let _ = customer::ActiveModel {\n        name: Set(\"Bob\".to_owned()),\n        notes: Set(Some(\"Just listening\".to_owned())),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let _ = customer::ActiveModel {\n        name: Set(\"Sam\".to_owned()),\n        notes: Set(None),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let customers = Customer::find()\n        .select_only()\n        .column(customer::Column::Id)\n        .column(customer::Column::Name)\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(customers.len(), 3);\n    assert_eq!(customers[0].notes, None);\n    assert_eq!(customers[1].notes, None);\n    assert_eq!(customers[2].notes, None);\n\n    let sam = bakery_dense::customer::Entity::find()\n        .filter(bakery_dense::customer::COLUMN.name.eq(\"Sam\"))\n        .one(&ctx.db)\n        .await\n        .unwrap()\n        .unwrap();\n\n    let _: sea_orm::StringColumnNullable<bakery_dense::customer::Entity> =\n        bakery_dense::customer::COLUMN.notes;\n\n    assert_eq!(\n        sam,\n        bakery_dense::customer::Entity::find()\n            .filter(\n                bakery_dense::customer::COLUMN\n                    .notes\n                    .eq(Option::<String>::None)\n            )\n            .one(&ctx.db)\n            .await\n            .unwrap()\n            .unwrap()\n    );\n\n    ctx.delete().await;\n}\n"
  },
  {
    "path": "tests/raw_sql_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\nuse sea_orm::{FromQueryResult, prelude::*, raw_sql};\n\nuse crate::common::TestContext;\nuse common::bakery_chain::*;\nuse serde_json::json;\n\nmod common;\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-sqlite\")]\nasync fn raw_sql_test_simple_select() {\n    #[derive(FromQueryResult)]\n    struct BakerySimple {\n        id: i32,\n        brand: String,\n    }\n\n    #[derive(FromQueryResult)]\n    struct BakeryFlat {\n        id: i32,\n        name: String,\n        #[sea_orm(alias = \"profit_margin\")]\n        profit: f64,\n    }\n\n    let ctx = TestContext::new(\"raw_sql_test_simple_select\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, false).await;\n\n    let id = 42;\n\n    let bakery: bakery::Model = bakery::Entity::find()\n        .from_raw_sql(raw_sql!(\n            Sqlite,\n            r#\"SELECT \"id\", \"name\", \"profit_margin\" FROM \"bakery\" WHERE id = {id}\"#\n        ))\n        .one(&ctx.db)\n        .await\n        .expect(\"succeeds to get the result\")\n        .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.name, \"cool little bakery\");\n    assert_eq!(bakery.profit_margin, 4.1);\n\n    let bakery = BakeryFlat::find_by_statement(raw_sql!(\n        Sqlite,\n        r#\"SELECT \"id\", \"name\", \"profit_margin\" FROM \"bakery\" WHERE id = {id}\"#\n    ))\n    .one(&ctx.db)\n    .await\n    .expect(\"succeeds to get the result\")\n    .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.name, \"cool little bakery\");\n    assert_eq!(bakery.profit, 4.1);\n\n    let bakery = BakerySimple::find_by_statement(raw_sql!(\n        Sqlite,\n        r#\"SELECT \"id\", \"name\" as \"brand\" FROM \"bakery\" WHERE id = {id}\"#\n    ))\n    .one(&ctx.db)\n    .await\n    .expect(\"succeeds to get the result\")\n    .expect(\"exactly one model in DB\");\n\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.brand, \"cool little bakery\");\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-sqlite\")]\nasync fn raw_sql_test_nested_select() {\n    #[derive(FromQueryResult)]\n    struct Cake {\n        id: i32,\n        name: String,\n        #[sea_orm(nested)]\n        bakery: Option<Bakery>,\n    }\n\n    #[derive(FromQueryResult)]\n    struct Bakery {\n        #[sea_orm(alias = \"bakery_id\")]\n        id: i32,\n        #[sea_orm(alias = \"bakery_name\")]\n        name: String,\n    }\n\n    let ctx = TestContext::new(\"raw_sql_test_nested_select\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    seed_data::init_1(&ctx, true).await;\n\n    let bakery_id = 42;\n    let cake_ids = [10, 12, 15];\n\n    let cake: Option<Cake> = Cake::find_by_statement(raw_sql!(\n        Sqlite,\n        r#\"SELECT\n                \"cake\".\"id\",\n                \"cake\".\"name\",\n                \"bakery\".\"id\" AS \"bakery_id\",\n                \"bakery\".\"name\" AS \"bakery_name\"\n            FROM \"cake\"\n            LEFT JOIN \"bakery\" ON \"cake\".\"bakery_id\" = \"bakery\".\"id\"\n            WHERE\n                \"bakery\".\"id\" = {bakery_id}\n                AND \"cake\".\"id\" IN ({..cake_ids})\n            ORDER BY \"cake\".\"id\" ASC LIMIT 1\"#\n    ))\n    .one(&ctx.db)\n    .await\n    .expect(\"succeeds to get the result\");\n\n    let cake = cake.unwrap();\n    assert_eq!(cake.id, 15);\n    assert_eq!(cake.name, \"Chocolate\");\n    let bakery = cake.bakery.unwrap();\n    assert_eq!(bakery.id, 42);\n    assert_eq!(bakery.name, \"cool little bakery\");\n\n    ctx.delete().await;\n}\n"
  },
  {
    "path": "tests/rbac_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\nuse sea_orm::{\n    ColumnTrait, ConnectionTrait, DbConn, DbErr, EntityName, EntityTrait, IntoActiveModel, NotSet,\n    QueryFilter, Set, TransactionTrait, entity::prelude::ChronoUtc,\n};\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"rbac\")]\nasync fn main() {\n    let ctx = TestContext::new(\"bakery_chain_rbac_tests\").await;\n    create_tables(&ctx.db).await.unwrap();\n    sea_orm::rbac::schema::create_tables(&ctx.db, Default::default())\n        .await\n        .unwrap();\n    rbac_setup(&ctx.db).await.unwrap();\n    crud_tests(&ctx.db).await.unwrap();\n    ctx.delete().await;\n}\n\n#[cfg(feature = \"rbac\")]\nasync fn rbac_setup(db: &DbConn) -> Result<(), DbErr> {\n    use sea_orm::rbac::{RbacAddRoleHierarchy, RbacContext};\n\n    let mut context = RbacContext::load(db).await?;\n\n    let tables = [\n        baker::Entity.table_name(),\n        bakery::Entity.table_name(),\n        cake::Entity.table_name(),\n        cakes_bakers::Entity.table_name(),\n        customer::Entity.table_name(),\n        lineitem::Entity.table_name(),\n        order::Entity.table_name(),\n        \"*\", // WILDCARD\n    ];\n\n    context.add_tables(db, &tables).await?;\n\n    context.add_crud_permissions(db).await?;\n\n    context\n        .add_roles(db, &[\"admin\", \"manager\", \"public\"])\n        .await?;\n\n    context\n        .assign_user_role(db, &[(1, \"admin\"), (2, \"manager\"), (3, \"public\")])\n        .await?;\n\n    // public can select everything\n    context\n        .add_role_permissions(db, \"public\", &[\"select\"], &[\"*\"])\n        .await?;\n\n    // manager can create / update everything except bakery\n    context\n        .add_role_permissions(\n            db,\n            \"manager\",\n            &[\"insert\", \"update\"],\n            &tables\n                .iter()\n                .cloned()\n                .filter(|t| !matches!(*t, \"bakery\" | \"*\"))\n                .collect::<Vec<_>>(),\n        )\n        .await?;\n\n    // manager can delete order\n    context\n        .add_role_permissions(db, \"manager\", &[\"delete\"], &[\"order\", \"lineitem\"])\n        .await?;\n\n    // admin can do anything, in addition to public / manager\n    context\n        .add_role_permissions(db, \"admin\", &[\"delete\"], &[\"*\"])\n        .await?;\n\n    // add permissions to bakery which manager doesn't have\n    context\n        .add_role_permissions(db, \"admin\", &[\"insert\", \"update\"], &[\"bakery\"])\n        .await?;\n\n    context\n        .add_role_hierarchy(\n            db,\n            &[\n                RbacAddRoleHierarchy {\n                    super_role: \"admin\",\n                    role: \"manager\",\n                },\n                RbacAddRoleHierarchy {\n                    super_role: \"manager\",\n                    role: \"public\",\n                },\n            ],\n        )\n        .await?;\n\n    Ok(())\n}\n\n#[cfg(feature = \"rbac\")]\nasync fn crud_tests(db: &DbConn) -> Result<(), DbErr> {\n    use sea_orm::{RestrictedConnection, RestrictedTransaction, rbac::RbacUserId};\n\n    db.load_rbac().await?;\n\n    let admin = RbacUserId(1);\n    let manager = RbacUserId(2);\n    let public = RbacUserId(3);\n\n    async fn admin_create_bakery(db: RestrictedConnection) -> Result<(), DbErr> {\n        // only admin can create bakery\n        let seaside_bakery = bakery::ActiveModel {\n            name: Set(\"SeaSide Bakery\".to_owned()),\n            profit_margin: Set(10.2),\n            ..Default::default()\n        };\n        let res = Bakery::insert(seaside_bakery).exec(&db).await?;\n        let bakery: Option<bakery::Model> = Bakery::find_by_id(res.last_insert_id).one(&db).await?;\n\n        assert_eq!(bakery.unwrap().name, \"SeaSide Bakery\");\n        Ok(())\n    }\n\n    admin_create_bakery(db.restricted_for(admin)?).await?;\n\n    // manager / public can't create bakery\n    for user in [manager, public] {\n        assert!(matches!(\n            Bakery::insert(bakery::ActiveModel::default())\n                .exec(&db.restricted_for(user)?)\n                .await,\n            Err(DbErr::AccessDenied { .. })\n        ));\n        let txn = db.restricted_for(user)?.begin().await?;\n        assert!(matches!(\n            Bakery::insert(bakery::ActiveModel::default())\n                .exec(&txn)\n                .await,\n            Err(DbErr::AccessDenied { .. })\n        ));\n    }\n\n    // anyone can read bakery\n    for user_id in [1, 2, 3] {\n        let db = db.restricted_for(RbacUserId(user_id))?;\n\n        let bakery = Bakery::find().one(&db).await?.unwrap();\n        assert_eq!(bakery.name, \"SeaSide Bakery\");\n    }\n\n    // manager can create cake / baker\n    {\n        let db = db.restricted_for(manager)?;\n\n        cake::Entity::insert(cake::ActiveModel {\n            name: Set(\"Cheesecake\".to_owned()),\n            price: Set(2.into()),\n            bakery_id: Set(Some(1)),\n            gluten_free: Set(false),\n            ..Default::default()\n        })\n        .exec(&db)\n        .await\n        .expect(\"insert succeeds\");\n\n        db.transaction::<_, _, DbErr>(|txn| {\n            Box::pin(async move {\n                cake::Entity::insert(cake::ActiveModel {\n                    name: Set(\"Chocolate\".to_owned()),\n                    price: Set(3.into()),\n                    bakery_id: Set(Some(1)),\n                    gluten_free: Set(true),\n                    ..Default::default()\n                })\n                .exec(txn)\n                .await?;\n\n                Ok(())\n            })\n        })\n        .await\n        .expect(\"insert succeeds\");\n\n        let txn: RestrictedTransaction = db.begin().await?;\n\n        baker::Entity::insert(baker::ActiveModel {\n            name: Set(\"Master Baker\".to_owned()),\n            contact_details: Set(Default::default()),\n            bakery_id: Set(Some(1)),\n            ..Default::default()\n        })\n        .exec(&txn)\n        .await\n        .expect(\"insert succeeds\");\n\n        txn.commit().await?;\n    }\n\n    assert_eq!(cake::Entity::find().all(db).await?.len(), 2);\n\n    // anyone can read cake\n    for user_id in [1, 2, 3] {\n        let db = db.restricted_for(RbacUserId(user_id))?;\n\n        let cake = cake::Entity::find().one(&db).await?.unwrap();\n        assert_eq!(cake.name, \"Cheesecake\");\n    }\n\n    // admin can create customer\n    {\n        let db = db.restricted_for(admin)?;\n\n        customer::Entity::insert(customer::ActiveModel {\n            id: Set(11),\n            name: Set(\"Alice\".to_owned()),\n            notes: Set(None),\n        })\n        .exec(&db)\n        .await?;\n\n        customer::Entity::insert(customer::ActiveModel {\n            id: Set(12),\n            name: Set(\"Bob\".to_owned()),\n            notes: Set(None),\n        })\n        .exec(&db)\n        .await?;\n    }\n\n    // manager can create / delete order\n    {\n        let public_db = db.restricted_for(public)?;\n        let db = db.restricted_for(manager)?;\n\n        order::Entity::insert(order::ActiveModel {\n            id: Set(101),\n            total: Set(10.into()),\n            bakery_id: Set(1),\n            customer_id: Set(11),\n            placed_at: Set(ChronoUtc::now()),\n        })\n        .exec(&db)\n        .await?;\n\n        lineitem::Entity::insert(lineitem::ActiveModel {\n            id: NotSet,\n            price: Set(2.into()),\n            quantity: Set(2),\n            order_id: Set(101),\n            cake_id: Set(1),\n        })\n        .exec(&db)\n        .await?;\n\n        let to_insert = lineitem::ActiveModel {\n            id: NotSet,\n            price: Set(3.into()),\n            quantity: Set(3),\n            order_id: Set(101),\n            cake_id: Set(2),\n        };\n        let lineitem_id = if db.support_returning() {\n            lineitem::Entity::insert(to_insert)\n                .exec_with_returning(&db)\n                .await?\n                .id\n        } else {\n            lineitem::Entity::insert(to_insert)\n                .exec(&db)\n                .await?\n                .last_insert_id\n        };\n\n        let order_with_items = order::Entity::find()\n            .find_with_related(lineitem::Entity)\n            .all(&public_db)\n            .await?;\n        assert_eq!(order_with_items[0].1.len(), 2);\n\n        lineitem::Entity::delete_many()\n            .filter(lineitem::Column::Id.eq(lineitem_id))\n            .exec(&db)\n            .await?;\n\n        // reject; of course\n        assert!(matches!(\n            lineitem::Entity::delete_many()\n                .filter(lineitem::Column::Id.eq(lineitem_id))\n                .exec(&public_db)\n                .await,\n            Err(DbErr::AccessDenied { .. })\n        ));\n\n        // only 1 line item left\n        let order_with_items = order::Entity::find()\n            .find_with_related(lineitem::Entity)\n            .all(&public_db)\n            .await?;\n        assert_eq!(order_with_items[0].1.len(), 1);\n    }\n\n    // manager can update order\n    {\n        use sea_orm::ActiveModelTrait;\n\n        let db = db.restricted_for(manager)?;\n\n        let lineitem = lineitem::Entity::find_by_id(1).one(&db).await?.unwrap();\n        assert_eq!(lineitem.quantity, 2);\n        let mut lineitem = lineitem.into_active_model();\n        lineitem.quantity = Set(3);\n        let lineitem = lineitem.save(&db).await?;\n        assert_eq!(lineitem.quantity.unwrap(), 3);\n    }\n\n    // only admin can delete customer\n    {\n        use sea_orm::ModelTrait;\n\n        let db = db.restricted_for(admin)?;\n\n        let bob = customer::Entity::find_by_id(12).one(&db).await?.unwrap();\n        assert_eq!(bob.name, \"Bob\");\n\n        bob.delete(&db).await?;\n        assert!(customer::Entity::find_by_id(12).one(&db).await?.is_none());\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/relational_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::sea_query::{Expr, Func, SimpleExpr};\nuse sea_orm::{\n    DbBackend, DbErr, DerivePartialModel, FromQueryResult,\n    entity::*,\n    prelude::{ChronoUtc, DateTimeUtc, Decimal, Uuid},\n    query::*,\n};\n\n// Run the test locally:\n// DATABASE_URL=\"mysql://root:@localhost\" cargo test --features sqlx-mysql,runtime-async-std-native-tls --test relational_tests\n#[sea_orm_macros::test]\npub async fn left_join() {\n    let ctx = TestContext::new(\"test_left_join\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let _baker_1 = baker::ActiveModel {\n        name: Set(\"Baker 1\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(bakery.id)),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert baker\");\n\n    let _baker_2 = baker::ActiveModel {\n        name: Set(\"Baker 2\".to_owned()),\n        contact_details: Set(serde_json::json!({})),\n        bakery_id: Set(None),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert baker\");\n\n    #[derive(Debug, FromQueryResult)]\n    struct SelectResult {\n        name: String,\n        bakery_name: Option<String>,\n    }\n\n    let select = baker::Entity::find()\n        .left_join(bakery::Entity)\n        .select_only()\n        .column(baker::Column::Name)\n        .column_as(bakery::Column::Name, \"bakery_name\")\n        .filter(baker::Column::Name.contains(\"Baker 1\"));\n\n    let result = select\n        .clone()\n        .into_model::<SelectResult>()\n        .one(&ctx.db)\n        .await\n        .unwrap()\n        .unwrap();\n    assert_eq!(result.name.as_str(), \"Baker 1\");\n    assert_eq!(result.bakery_name, Some(\"SeaSide Bakery\".to_string()));\n\n    #[derive(DerivePartialModel, Debug, PartialEq)]\n    #[sea_orm(entity = \"Baker\")]\n    struct PartialSelectResult {\n        name: String,\n        #[sea_orm(from_expr = \"Expr::col((bakery::Entity, bakery::Column::Name))\")]\n        bakery_name: Option<String>,\n        #[sea_orm(\n            from_expr = r#\"SimpleExpr::FunctionCall(Func::upper(Expr::col((bakery::Entity, bakery::Column::Name))))\"#\n        )]\n        bakery_name_upper: Option<String>,\n    }\n\n    let result = select\n        .into_partial_model::<PartialSelectResult>()\n        .one(&ctx.db)\n        .await\n        .unwrap()\n        .unwrap();\n    assert_eq!(result.name.as_str(), \"Baker 1\");\n    assert_eq!(result.bakery_name, Some(\"SeaSide Bakery\".to_string()));\n    assert_eq!(result.bakery_name_upper, Some(\"SEASIDE BAKERY\".to_string()));\n\n    let select = baker::Entity::find()\n        .left_join(bakery::Entity)\n        .select_only()\n        .column(baker::Column::Name)\n        .column_as(bakery::Column::Name, \"bakery_name\")\n        .filter(baker::Column::Name.contains(\"Baker 2\"));\n\n    let result = select\n        .into_model::<SelectResult>()\n        .one(&ctx.db)\n        .await\n        .unwrap()\n        .unwrap();\n    assert_eq!(result.bakery_name, None);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\n#[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-postgres\"))]\npub async fn right_join() {\n    let ctx = TestContext::new(\"test_right_join\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let _customer_jim = customer::ActiveModel {\n        name: Set(\"Jim\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let _order = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(15.10)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert order\");\n\n    #[derive(FromQueryResult)]\n    #[allow(dead_code)]\n    struct SelectResult {\n        name: String,\n        order_total: Option<Decimal>,\n    }\n\n    let select = order::Entity::find()\n        .right_join(customer::Entity)\n        .select_only()\n        .column(customer::Column::Name)\n        .column_as(order::Column::Total, \"order_total\")\n        .filter(customer::Column::Name.contains(\"Kate\"));\n\n    let result = select\n        .into_model::<SelectResult>()\n        .one(&ctx.db)\n        .await\n        .unwrap()\n        .unwrap();\n    assert_eq!(result.order_total, Some(rust_dec(15.10)));\n\n    let select = order::Entity::find()\n        .right_join(customer::Entity)\n        .select_only()\n        .column(customer::Column::Name)\n        .column_as(order::Column::Total, \"order_total\")\n        .filter(customer::Column::Name.contains(\"Jim\"));\n\n    let result = select\n        .into_model::<SelectResult>()\n        .one(&ctx.db)\n        .await\n        .unwrap()\n        .unwrap();\n    assert_eq!(result.order_total, None);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn inner_join() {\n    let ctx = TestContext::new(\"test_inner_join\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let _customer_jim = customer::ActiveModel {\n        name: Set(\"Jim\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let kate_order_1 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(15.10)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert order\");\n\n    let kate_order_2 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(100.00)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert order\");\n\n    #[derive(Debug, FromQueryResult)]\n    struct SelectResult {\n        name: String,\n        order_total: Option<Decimal>,\n    }\n\n    let select = order::Entity::find()\n        .inner_join(customer::Entity)\n        .select_only()\n        .column(customer::Column::Name)\n        .column_as(order::Column::Total, \"order_total\");\n\n    let results = select\n        .into_model::<SelectResult>()\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(results.len(), 2);\n    assert!(\n        results\n            .iter()\n            .any(|result| result.name == customer_kate.name.clone()\n                && result.order_total == Some(kate_order_1.total))\n    );\n    assert!(\n        results\n            .iter()\n            .any(|result| result.name == customer_kate.name.clone()\n                && result.order_total == Some(kate_order_2.total))\n    );\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\n#[cfg(any(\n    feature = \"sqlx-mysql\",\n    feature = \"sqlx-sqlite\",\n    feature = \"sqlx-postgres\"\n))]\npub async fn find_both_related() {\n    let ctx = TestContext::new(\"test_find_both_related\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let _customer_jim = customer::ActiveModel {\n        name: Set(\"Jim\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let kate_order_1 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(15.10)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert order\");\n\n    let kate_order_2 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(100.00)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert order\");\n\n    let results: Vec<(order::Model, customer::Model)> = order::Entity::find()\n        .find_both_related(customer::Entity)\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(results.len(), 2);\n    assert!(\n        results\n            .iter()\n            .any(|result| result.1.name == customer_kate.name.clone()\n                && result.0.total == kate_order_1.total)\n    );\n    assert!(\n        results\n            .iter()\n            .any(|result| result.1.name == customer_kate.name.clone()\n                && result.0.total == kate_order_2.total)\n    );\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\n#[cfg(any(\n    feature = \"sqlx-mysql\",\n    feature = \"sqlx-sqlite\",\n    feature = \"sqlx-postgres\"\n))]\npub async fn group_by() {\n    let ctx = TestContext::new(\"test_group_by\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let customer_sam = customer::ActiveModel {\n        name: Set(\"Sam\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let kate_order_1 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(99.95)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert order\");\n\n    let kate_order_2 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(200.00)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert order\");\n\n    let sam_order = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_sam.id),\n        total: Set(rust_dec(28.24)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert order\");\n\n    type Count = i64;\n\n    #[derive(Debug, FromQueryResult)]\n    struct SelectResult {\n        name: String,\n        number_orders: Count,\n        total_spent: Decimal,\n        min_spent: Decimal,\n        max_spent: Decimal,\n    }\n\n    let select = customer::Entity::find()\n        .left_join(order::Entity)\n        .select_only()\n        .column(customer::Column::Name)\n        .column_as(order::Column::Total.count(), \"number_orders\")\n        .column_as(order::Column::Total.sum(), \"total_spent\")\n        .column_as(order::Column::Total.min(), \"min_spent\")\n        .column_as(order::Column::Total.max(), \"max_spent\")\n        .order_by_asc(customer::Column::Name)\n        .group_by(customer::Column::Name);\n\n    let result = select\n        .into_model::<SelectResult>()\n        .one(&ctx.db)\n        .await\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(result.name, \"Kate\");\n    assert_eq!(result.number_orders, 2);\n    assert_eq!(result.total_spent, kate_order_1.total + kate_order_2.total);\n    assert_eq!(result.min_spent, kate_order_1.total.min(kate_order_2.total));\n    assert_eq!(result.max_spent, kate_order_1.total.max(kate_order_2.total));\n\n    let (customer, total_spent): (String, Decimal) = customer::Entity::find()\n        .left_join(order::Entity)\n        .select_only()\n        .column(customer::Column::Name)\n        .column_as(order::Column::Total.sum(), \"sum\")\n        .group_by(customer::Column::Name)\n        .into_tuple()\n        .one(&ctx.db)\n        .await\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(customer, \"Kate\");\n    assert_eq!(total_spent, result.total_spent);\n\n    let sum_order_value: Decimal = order::Entity::find()\n        .select_only()\n        .column_as(order::Column::Total.sum(), \"sum\")\n        .into_tuple()\n        .one(&ctx.db)\n        .await\n        .unwrap()\n        .unwrap();\n\n    assert_eq!(\n        sum_order_value,\n        kate_order_1.total + kate_order_2.total + sam_order.total\n    );\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn having() {\n    // customers with orders with total equal to $90\n    let ctx = TestContext::new(\"test_having\").await;\n    create_tables(&ctx.db).await.unwrap();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let kate_order_1 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(100.00)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert order\");\n\n    let _kate_order_2 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_kate.id),\n        total: Set(rust_dec(12.00)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert order\");\n\n    let customer_bob = customer::ActiveModel {\n        name: Set(\"Bob\".to_owned()),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let _bob_order_1 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_bob.id),\n        total: Set(rust_dec(50.0)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert order\");\n\n    let _bob_order_2 = order::ActiveModel {\n        bakery_id: Set(bakery.id),\n        customer_id: Set(customer_bob.id),\n        total: Set(rust_dec(50.0)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await\n    .expect(\"could not insert order\");\n\n    #[derive(Debug, FromQueryResult)]\n    struct SelectResult {\n        name: String,\n        order_total: Option<Decimal>,\n    }\n\n    let results = customer::Entity::find()\n        .inner_join(order::Entity)\n        .select_only()\n        .column(customer::Column::Name)\n        .column_as(order::Column::Total, \"order_total\")\n        .group_by(customer::Column::Name)\n        .group_by(order::Column::Total)\n        .having(order::Column::Total.gt(rust_dec(90.00)))\n        .into_model::<SelectResult>()\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(results.len(), 1);\n    assert_eq!(results[0].name, customer_kate.name.clone());\n    assert_eq!(results[0].order_total, Some(kate_order_1.total));\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn related() -> Result<(), DbErr> {\n    use sea_orm::{SelectA, SelectB};\n\n    let ctx = TestContext::new(\"test_related\").await;\n    create_tables(&ctx.db).await?;\n\n    // SeaSide Bakery\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let seaside_bakery_res = Bakery::insert(seaside_bakery).exec(&ctx.db).await?;\n\n    // Bob's Baker\n    let baker_bob = baker::ActiveModel {\n        name: Set(\"Baker Bob\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await?;\n\n    // Bobby's Baker\n    let baker_bobby = baker::ActiveModel {\n        name: Set(\"Baker Bobby\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+85212345678\",\n        })),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let _baker_bobby_res = Baker::insert(baker_bobby).exec(&ctx.db).await?;\n\n    // Terres Bakery\n    let terres_bakery = bakery::ActiveModel {\n        name: Set(\"Terres Bakery\".to_owned()),\n        profit_margin: Set(13.5),\n        ..Default::default()\n    };\n    let terres_bakery_res = Bakery::insert(terres_bakery).exec(&ctx.db).await?;\n\n    // Ada's Baker\n    let baker_ada = baker::ActiveModel {\n        name: Set(\"Baker Ada\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(terres_bakery_res.last_insert_id)),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await?;\n\n    // Stone Bakery, with no baker\n    let stone_bakery = bakery::ActiveModel {\n        name: Set(\"Stone Bakery\".to_owned()),\n        profit_margin: Set(13.5),\n        ..Default::default()\n    };\n    let _stone_bakery_res = Bakery::insert(stone_bakery).exec(&ctx.db).await?;\n\n    let cake = cake::ActiveModel {\n        name: Set(\"Chocolate\".to_owned()),\n        price: Set(\"1.2\".parse().unwrap()),\n        gluten_free: Set(false),\n        bakery_id: Set(None),\n        ..Default::default()\n    }\n    .insert(&ctx.db)\n    .await?;\n\n    cakes_bakers::ActiveModel {\n        cake_id: Set(cake.id),\n        baker_id: Set(baker_bob.id),\n    }\n    .insert(&ctx.db)\n    .await?;\n\n    cakes_bakers::ActiveModel {\n        cake_id: Set(cake.id),\n        baker_id: Set(baker_ada.id),\n    }\n    .insert(&ctx.db)\n    .await?;\n\n    #[derive(Debug, FromQueryResult, PartialEq)]\n    struct BakerLite {\n        name: String,\n    }\n\n    #[derive(Debug, FromQueryResult, PartialEq)]\n    struct BakeryLite {\n        name: String,\n    }\n\n    // get all bakery and baker's name and put them into tuples\n    let bakers_in_bakery: Vec<(BakeryLite, Option<BakerLite>)> = Bakery::find()\n        .find_also_related(Baker)\n        .select_only()\n        .column_as(bakery::Column::Name, (SelectA, bakery::Column::Name))\n        .column_as(baker::Column::Name, (SelectB, baker::Column::Name))\n        .order_by_asc(bakery::Column::Id)\n        .order_by_asc(baker::Column::Id)\n        .into_model()\n        .all(&ctx.db)\n        .await?;\n\n    assert_eq!(\n        bakers_in_bakery,\n        [\n            (\n                BakeryLite {\n                    name: \"SeaSide Bakery\".to_owned(),\n                },\n                Some(BakerLite {\n                    name: \"Baker Bob\".to_owned(),\n                })\n            ),\n            (\n                BakeryLite {\n                    name: \"SeaSide Bakery\".to_owned(),\n                },\n                Some(BakerLite {\n                    name: \"Baker Bobby\".to_owned(),\n                })\n            ),\n            (\n                BakeryLite {\n                    name: \"Terres Bakery\".to_owned(),\n                },\n                Some(BakerLite {\n                    name: \"Baker Ada\".to_owned(),\n                })\n            ),\n            (\n                BakeryLite {\n                    name: \"Stone Bakery\".to_owned(),\n                },\n                None,\n            ),\n        ]\n    );\n\n    let seaside_bakery = Bakery::find()\n        .filter(bakery::Column::Id.eq(1))\n        .one(&ctx.db)\n        .await?\n        .unwrap();\n\n    let bakers = seaside_bakery.find_related(Baker).all(&ctx.db).await?;\n\n    assert_eq!(\n        bakers,\n        [\n            baker::Model {\n                id: 1,\n                name: \"Baker Bob\".to_owned(),\n                contact_details: serde_json::json!({\n                    \"mobile\": \"+61424000000\",\n                    \"home\": \"0395555555\",\n                    \"address\": \"12 Test St, Testville, Vic, Australia\"\n                }),\n                bakery_id: Some(1),\n            },\n            baker::Model {\n                id: 2,\n                name: \"Baker Bobby\".to_owned(),\n                contact_details: serde_json::json!({\n                    \"mobile\": \"+85212345678\",\n                }),\n                bakery_id: Some(1),\n            }\n        ]\n    );\n\n    let select_bakery_with_baker = Bakery::find()\n        .find_with_related(Baker)\n        .order_by_asc(baker::Column::Id);\n\n    assert_eq!(\n        select_bakery_with_baker\n            .build(sea_orm::DatabaseBackend::MySql)\n            .to_string(),\n        [\n            \"SELECT `bakery`.`id` AS `A_id`,\",\n            \"`bakery`.`name` AS `A_name`,\",\n            \"`bakery`.`profit_margin` AS `A_profit_margin`,\",\n            \"`baker`.`id` AS `B_id`,\",\n            \"`baker`.`name` AS `B_name`,\",\n            \"`baker`.`contact_details` AS `B_contact_details`,\",\n            \"`baker`.`bakery_id` AS `B_bakery_id`\",\n            \"FROM `bakery`\",\n            \"LEFT JOIN `baker` ON `bakery`.`id` = `baker`.`bakery_id`\",\n            \"ORDER BY `bakery`.`id` ASC, `baker`.`id` ASC\"\n        ]\n        .join(\" \")\n    );\n\n    let select_bakery_with_baker_result = select_bakery_with_baker.all(&ctx.db).await?;\n\n    assert_eq!(\n        select_bakery_with_baker_result,\n        [\n            (\n                bakery::Model {\n                    id: 1,\n                    name: \"SeaSide Bakery\".to_owned(),\n                    profit_margin: 10.4,\n                },\n                vec![\n                    baker::Model {\n                        id: 1,\n                        name: \"Baker Bob\".to_owned(),\n                        contact_details: serde_json::json!({\n                            \"mobile\": \"+61424000000\",\n                            \"home\": \"0395555555\",\n                            \"address\": \"12 Test St, Testville, Vic, Australia\"\n                        }),\n                        bakery_id: Some(seaside_bakery_res.last_insert_id),\n                    },\n                    baker::Model {\n                        id: 2,\n                        name: \"Baker Bobby\".to_owned(),\n                        contact_details: serde_json::json!({\n                            \"mobile\": \"+85212345678\",\n                        }),\n                        bakery_id: Some(seaside_bakery_res.last_insert_id),\n                    }\n                ]\n            ),\n            (\n                bakery::Model {\n                    id: 2,\n                    name: \"Terres Bakery\".to_owned(),\n                    profit_margin: 13.5,\n                },\n                vec![baker::Model {\n                    id: 3,\n                    name: \"Baker Ada\".to_owned(),\n                    contact_details: serde_json::json!({\n                        \"mobile\": \"+61424000000\",\n                        \"home\": \"0395555555\",\n                        \"address\": \"12 Test St, Testville, Vic, Australia\"\n                    }),\n                    bakery_id: Some(terres_bakery_res.last_insert_id),\n                }]\n            ),\n            (\n                bakery::Model {\n                    id: 3,\n                    name: \"Stone Bakery\".to_owned(),\n                    profit_margin: 13.5,\n                },\n                vec![]\n            ),\n        ]\n    );\n\n    assert_eq!(\n        select_bakery_with_baker_result,\n        Bakery::find()\n            .find_with_linked(bakery::ToBaker)\n            .order_by_asc(bakery::Column::Id)\n            .order_by_asc(Expr::col((\"r0\", baker::Column::Id)))\n            .all(&ctx.db)\n            .await?\n    );\n\n    let select_cake_with_baker = Cake::find().find_with_related(Baker);\n\n    assert_eq!(\n        select_cake_with_baker\n            .build(sea_orm::DatabaseBackend::MySql)\n            .to_string(),\n        [\n            \"SELECT\",\n            \"`cake`.`id` AS `A_id`, `cake`.`name` AS `A_name`, `cake`.`price` AS `A_price`,\",\n            \"`cake`.`bakery_id` AS `A_bakery_id`, `cake`.`gluten_free` AS `A_gluten_free`,\",\n            \"`cake`.`serial` AS `A_serial`, `baker`.`id` AS `B_id`, `baker`.`name` AS `B_name`,\",\n            \"`baker`.`contact_details` AS `B_contact_details`, `baker`.`bakery_id` AS `B_bakery_id`\",\n            \"FROM `cake` LEFT JOIN `cakes_bakers` ON `cake`.`id` = `cakes_bakers`.`cake_id`\",\n            \"LEFT JOIN `baker` ON `cakes_bakers`.`baker_id` = `baker`.`id`\",\n            \"ORDER BY `cake`.`id` ASC\"\n        ].join(\" \")\n    );\n\n    assert_eq!(\n        select_cake_with_baker.all(&ctx.db).await?,\n        [(cake.try_into_model().unwrap(), vec![baker_bob, baker_ada])]\n    );\n\n    ctx.delete().await;\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub async fn linked() -> Result<(), DbErr> {\n    use common::bakery_chain::Order;\n    use sea_orm::{SelectA, SelectB};\n    use sea_query::{Alias, Expr};\n\n    let ctx = TestContext::new(\"test_linked\").await;\n    create_tables(&ctx.db).await?;\n\n    // SeaSide Bakery\n    let seaside_bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    };\n    let seaside_bakery_res = Bakery::insert(seaside_bakery).exec(&ctx.db).await?;\n\n    // Bob's Baker, Cake & Cake Baker\n    let baker_bob = baker::ActiveModel {\n        name: Set(\"Baker Bob\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+61424000000\",\n            \"home\": \"0395555555\",\n            \"address\": \"12 Test St, Testville, Vic, Australia\"\n        })),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let baker_bob_res = Baker::insert(baker_bob).exec(&ctx.db).await?;\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let mud_cake_res = Cake::insert(mud_cake).exec(&ctx.db).await?;\n    let bob_cakes_bakers = cakes_bakers::ActiveModel {\n        cake_id: Set(mud_cake_res.last_insert_id),\n        baker_id: Set(baker_bob_res.last_insert_id),\n    };\n    CakesBakers::insert(bob_cakes_bakers).exec(&ctx.db).await?;\n\n    // Bobby's Baker, Cake & Cake Baker\n    let baker_bobby = baker::ActiveModel {\n        name: Set(\"Baker Bobby\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+85212345678\",\n        })),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let baker_bobby_res = Baker::insert(baker_bobby).exec(&ctx.db).await?;\n    let cheese_cake = cake::ActiveModel {\n        name: Set(\"Cheese Cake\".to_owned()),\n        price: Set(rust_dec(20.5)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let cheese_cake_res = Cake::insert(cheese_cake).exec(&ctx.db).await?;\n    let bobby_cakes_bakers = cakes_bakers::ActiveModel {\n        cake_id: Set(cheese_cake_res.last_insert_id),\n        baker_id: Set(baker_bobby_res.last_insert_id),\n    };\n    CakesBakers::insert(bobby_cakes_bakers)\n        .exec(&ctx.db)\n        .await?;\n    let chocolate_cake = cake::ActiveModel {\n        name: Set(\"Chocolate Cake\".to_owned()),\n        price: Set(rust_dec(30.15)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let chocolate_cake_res = Cake::insert(chocolate_cake).exec(&ctx.db).await?;\n    let bobby_cakes_bakers = cakes_bakers::ActiveModel {\n        cake_id: Set(chocolate_cake_res.last_insert_id),\n        baker_id: Set(baker_bobby_res.last_insert_id),\n    };\n    CakesBakers::insert(bobby_cakes_bakers)\n        .exec(&ctx.db)\n        .await?;\n\n    // Freerider's Baker, no cake baked\n    let baker_freerider = baker::ActiveModel {\n        name: Set(\"Freerider\".to_owned()),\n        contact_details: Set(serde_json::json!({\n            \"mobile\": \"+85298765432\",\n        })),\n        bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),\n        ..Default::default()\n    };\n    let _baker_freerider_res = Baker::insert(baker_freerider).exec(&ctx.db).await?;\n\n    // Kate's Customer, Order & Line Item\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        notes: Set(Some(\"Loves cheese cake\".to_owned())),\n        ..Default::default()\n    };\n    let customer_kate_res = Customer::insert(customer_kate).exec(&ctx.db).await?;\n    let kate_order_1 = order::ActiveModel {\n        bakery_id: Set(seaside_bakery_res.last_insert_id),\n        customer_id: Set(customer_kate_res.last_insert_id),\n        total: Set(rust_dec(15.10)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    };\n    let kate_order_1_res = Order::insert(kate_order_1).exec(&ctx.db).await?;\n    lineitem::ActiveModel {\n        cake_id: Set(cheese_cake_res.last_insert_id),\n        order_id: Set(kate_order_1_res.last_insert_id),\n        price: Set(rust_dec(7.55)),\n        quantity: Set(2),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await?;\n    let kate_order_2 = order::ActiveModel {\n        bakery_id: Set(seaside_bakery_res.last_insert_id),\n        customer_id: Set(customer_kate_res.last_insert_id),\n        total: Set(rust_dec(29.7)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    };\n    let kate_order_2_res = Order::insert(kate_order_2).exec(&ctx.db).await?;\n    lineitem::ActiveModel {\n        cake_id: Set(chocolate_cake_res.last_insert_id),\n        order_id: Set(kate_order_2_res.last_insert_id),\n        price: Set(rust_dec(9.9)),\n        quantity: Set(3),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await?;\n\n    // Kara's Customer, Order & Line Item\n    let customer_kara = customer::ActiveModel {\n        name: Set(\"Kara\".to_owned()),\n        notes: Set(Some(\"Loves all cakes\".to_owned())),\n        ..Default::default()\n    };\n    let customer_kara_res = Customer::insert(customer_kara).exec(&ctx.db).await?;\n    let kara_order_1 = order::ActiveModel {\n        bakery_id: Set(seaside_bakery_res.last_insert_id),\n        customer_id: Set(customer_kara_res.last_insert_id),\n        total: Set(rust_dec(15.10)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    };\n    let kara_order_1_res = Order::insert(kara_order_1).exec(&ctx.db).await?;\n    lineitem::ActiveModel {\n        cake_id: Set(mud_cake_res.last_insert_id),\n        order_id: Set(kara_order_1_res.last_insert_id),\n        price: Set(rust_dec(7.55)),\n        quantity: Set(2),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await?;\n    let kara_order_2 = order::ActiveModel {\n        bakery_id: Set(seaside_bakery_res.last_insert_id),\n        customer_id: Set(customer_kara_res.last_insert_id),\n        total: Set(rust_dec(29.7)),\n        placed_at: Set(ChronoUtc::now()),\n        ..Default::default()\n    };\n    let kara_order_2_res = Order::insert(kara_order_2).exec(&ctx.db).await?;\n    lineitem::ActiveModel {\n        cake_id: Set(cheese_cake_res.last_insert_id),\n        order_id: Set(kara_order_2_res.last_insert_id),\n        price: Set(rust_dec(9.9)),\n        quantity: Set(3),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await?;\n\n    #[derive(Debug, FromQueryResult, PartialEq)]\n    struct BakerLite {\n        name: String,\n    }\n\n    #[derive(Debug, FromQueryResult, PartialEq)]\n    struct CustomerLite {\n        name: String,\n    }\n\n    // filtered find\n    let baked_for_customers: Vec<(BakerLite, Option<CustomerLite>)> = Baker::find()\n        .find_also_linked(baker::BakedForCustomer)\n        .select_only()\n        .column_as(baker::Column::Name, (SelectA, baker::Column::Name))\n        .column_as(\n            Expr::col((\"r4\", customer::Column::Name)),\n            (SelectB, customer::Column::Name),\n        )\n        .group_by(baker::Column::Id)\n        .group_by(Expr::col((\"r4\", customer::Column::Id)))\n        .group_by(baker::Column::Name)\n        .group_by(Expr::col((\"r4\", customer::Column::Name)))\n        .order_by_asc(baker::Column::Id)\n        .order_by_asc(Expr::col((\"r4\", customer::Column::Id)))\n        .into_model()\n        .all(&ctx.db)\n        .await?;\n\n    assert_eq!(\n        baked_for_customers,\n        [\n            (\n                BakerLite {\n                    name: \"Baker Bob\".to_owned(),\n                },\n                Some(CustomerLite {\n                    name: \"Kara\".to_owned(),\n                })\n            ),\n            (\n                BakerLite {\n                    name: \"Baker Bobby\".to_owned(),\n                },\n                Some(CustomerLite {\n                    name: \"Kate\".to_owned(),\n                })\n            ),\n            (\n                BakerLite {\n                    name: \"Baker Bobby\".to_owned(),\n                },\n                Some(CustomerLite {\n                    name: \"Kara\".to_owned(),\n                })\n            ),\n            (\n                BakerLite {\n                    name: \"Freerider\".to_owned(),\n                },\n                None,\n            ),\n        ]\n    );\n\n    // try to use find_linked instead\n    let baker_bob = Baker::find()\n        .filter(baker::Column::Id.eq(1))\n        .one(&ctx.db)\n        .await?\n        .unwrap();\n\n    let baker_bob_customers = baker_bob\n        .find_linked(baker::BakedForCustomer)\n        .all(&ctx.db)\n        .await?;\n\n    assert_eq!(\n        baker_bob_customers,\n        [customer::Model {\n            id: 2,\n            name: \"Kara\".to_owned(),\n            notes: Some(\"Loves all cakes\".to_owned()),\n        }]\n    );\n\n    // find full model using with_linked\n    let select_baker_with_customer = Baker::find()\n        .find_with_linked(baker::BakedForCustomer)\n        .order_by_asc(baker::Column::Id)\n        .order_by_asc(Expr::col((\"r4\", customer::Column::Id)));\n\n    assert_eq!(\n        select_baker_with_customer\n            .build(sea_orm::DatabaseBackend::MySql)\n            .to_string(),\n        [\n            \"SELECT `baker`.`id` AS `A_id`,\",\n            \"`baker`.`name` AS `A_name`,\",\n            \"`baker`.`contact_details` AS `A_contact_details`,\",\n            \"`baker`.`bakery_id` AS `A_bakery_id`,\",\n            \"`r4`.`id` AS `B_id`,\",\n            \"`r4`.`name` AS `B_name`,\",\n            \"`r4`.`notes` AS `B_notes`\",\n            \"FROM `baker`\",\n            \"LEFT JOIN `cakes_bakers` AS `r0` ON `baker`.`id` = `r0`.`baker_id`\",\n            \"LEFT JOIN `cake` AS `r1` ON `r0`.`cake_id` = `r1`.`id`\",\n            \"LEFT JOIN `lineitem` AS `r2` ON `r1`.`id` = `r2`.`cake_id`\",\n            \"LEFT JOIN `order` AS `r3` ON `r2`.`order_id` = `r3`.`id`\",\n            \"LEFT JOIN `customer` AS `r4` ON `r3`.`customer_id` = `r4`.`id`\",\n            \"ORDER BY `baker`.`id` ASC, `r4`.`id` ASC\"\n        ]\n        .join(\" \")\n    );\n\n    assert_eq!(\n        select_baker_with_customer.all(&ctx.db).await?,\n        [\n            (\n                baker::Model {\n                    id: 1,\n                    name: \"Baker Bob\".into(),\n                    contact_details: serde_json::json!({\n                        \"mobile\": \"+61424000000\",\n                        \"home\": \"0395555555\",\n                        \"address\": \"12 Test St, Testville, Vic, Australia\",\n                    }),\n                    bakery_id: Some(1),\n                },\n                vec![customer::Model {\n                    id: 2,\n                    name: \"Kara\".into(),\n                    notes: Some(\"Loves all cakes\".into()),\n                }]\n            ),\n            (\n                baker::Model {\n                    id: 2,\n                    name: \"Baker Bobby\".into(),\n                    contact_details: serde_json::json!({\n                        \"mobile\": \"+85212345678\",\n                    }),\n                    bakery_id: Some(1),\n                },\n                vec![\n                    customer::Model {\n                        id: 1,\n                        name: \"Kate\".into(),\n                        notes: Some(\"Loves cheese cake\".into()),\n                    },\n                    customer::Model {\n                        id: 1,\n                        name: \"Kate\".into(),\n                        notes: Some(\"Loves cheese cake\".into()),\n                    },\n                    customer::Model {\n                        id: 2,\n                        name: \"Kara\".into(),\n                        notes: Some(\"Loves all cakes\".into()),\n                    },\n                ]\n            ),\n            (\n                baker::Model {\n                    id: 3,\n                    name: \"Freerider\".into(),\n                    contact_details: serde_json::json!({\n                        \"mobile\": \"+85298765432\",\n                    }),\n                    bakery_id: Some(1),\n                },\n                vec![]\n            ),\n        ]\n    );\n\n    ctx.delete().await;\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub async fn select_three() -> Result<(), DbErr> {\n    use common::bakery_chain::*;\n\n    let ctx = TestContext::new(\"test_select_three\").await;\n    create_tables(&ctx.db).await?;\n\n    seed_data::init_1(&ctx, true).await;\n\n    let items: Vec<(order::Model, Option<customer::Model>)> = order::Entity::find()\n        .find_also_related(customer::Entity)\n        .order_by_asc(order::Column::Id)\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    let order = order::Model {\n        id: 101,\n        total: Decimal::from(10),\n        bakery_id: 42,\n        customer_id: 11,\n        placed_at: \"2020-01-01T00:00:00Z\".parse().unwrap(),\n    };\n\n    let customer = customer::Model {\n        id: 11,\n        name: \"Bob\".to_owned(),\n        notes: Some(\"Sweet tooth\".to_owned()),\n    };\n\n    assert_eq!(items.len(), 1);\n    assert_eq!(items[0].0, order);\n    assert_eq!(items[0].1.as_ref().unwrap(), &customer);\n\n    let line_1 = lineitem::Model {\n        id: 1,\n        price: 2.into(),\n        quantity: 2,\n        order_id: 101,\n        cake_id: 13,\n    };\n\n    let line_2 = lineitem::Model {\n        id: 2,\n        price: 3.into(),\n        quantity: 2,\n        order_id: 101,\n        cake_id: 15,\n    };\n\n    let cake_1 = cake::Entity::find_by_id(13)\n        .one(&ctx.db)\n        .await\n        .unwrap()\n        .unwrap();\n\n    let cake_2 = cake::Entity::find_by_id(15)\n        .one(&ctx.db)\n        .await\n        .unwrap()\n        .unwrap();\n\n    let items: Vec<(\n        order::Model,\n        Option<customer::Model>,\n        Option<lineitem::Model>,\n    )> = order::Entity::find()\n        .find_also_related(customer::Entity)\n        .find_also_related(lineitem::Entity)\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(\n        items,\n        vec![\n            (order.clone(), Some(customer.clone()), Some(line_1.clone())),\n            (order.clone(), Some(customer.clone()), Some(line_2.clone())),\n        ]\n    );\n\n    // same, just different API\n    let items: Vec<(\n        order::Model,\n        Option<customer::Model>,\n        Option<lineitem::Model>,\n    )> = order::Entity::find()\n        .find_also(order::Entity, customer::Entity)\n        .find_also(order::Entity, lineitem::Entity)\n        .order_by_asc(order::Column::Id)\n        .order_by_asc(lineitem::Column::Id)\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(\n        items,\n        vec![\n            (order.clone(), Some(customer.clone()), Some(line_1.clone())),\n            (order.clone(), Some(customer.clone()), Some(line_2.clone())),\n        ]\n    );\n\n    let items: Vec<(order::Model, Vec<customer::Model>, Vec<lineitem::Model>)> =\n        order::Entity::find()\n            .find_also_related(customer::Entity)\n            .find_also_related(lineitem::Entity)\n            .order_by_asc(order::Column::Id)\n            .order_by_asc(lineitem::Column::Id)\n            .consolidate()\n            .all(&ctx.db)\n            .await\n            .unwrap();\n\n    assert_eq!(\n        items,\n        vec![(\n            order.clone(),\n            vec![customer.clone()],\n            vec![line_1.clone(), line_2.clone()]\n        )]\n    );\n\n    let items: Vec<(order::Model, Option<lineitem::Model>, Option<cake::Model>)> =\n        order::Entity::find()\n            .find_also_related(lineitem::Entity)\n            .and_also_related(cake::Entity)\n            .order_by_asc(order::Column::Id)\n            .order_by_asc(lineitem::Column::Id)\n            .all(&ctx.db)\n            .await\n            .unwrap();\n\n    assert_eq!(\n        items,\n        vec![\n            (order.clone(), Some(line_1.clone()), Some(cake_1.clone())),\n            (order.clone(), Some(line_2.clone()), Some(cake_2.clone())),\n        ]\n    );\n\n    let items: Vec<(order::Model, Vec<(lineitem::Model, Vec<cake::Model>)>)> =\n        order::Entity::find()\n            .find_also_related(lineitem::Entity)\n            .and_also_related(cake::Entity)\n            .order_by_asc(order::Column::Id)\n            .order_by_asc(lineitem::Column::Id)\n            .consolidate()\n            .all(&ctx.db)\n            .await\n            .unwrap();\n\n    assert_eq!(\n        items,\n        vec![(\n            order.clone(),\n            vec![(line_1, vec![cake_1]), (line_2, vec![cake_2])]\n        )]\n    );\n\n    ctx.delete().await;\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub async fn select_has_related() -> Result<(), DbErr> {\n    use common::bakery_chain::*;\n\n    let ctx = TestContext::new(\"test_select_has_related\").await;\n    create_tables(&ctx.db).await?;\n    let db = &ctx.db;\n    seed_data::init_2(&ctx).await?;\n\n    let bakery: Vec<bakery::Model> = bakery::Entity::find()\n        .has_related(cake::Entity, cake::Column::Name.contains(\"Chocolate\"))\n        .all(db)\n        .await?;\n\n    assert_eq!(bakery.len(), 1);\n    assert_eq!(bakery[0].name, \"SeaSide Bakery\");\n\n    let bakery: Vec<bakery::Model> = bakery::Entity::find()\n        .has_related(cake::Entity, cake::Column::Name.contains(\"Lemon\"))\n        .order_by_asc(bakery::Column::Id)\n        .all(db)\n        .await?;\n\n    assert_eq!(bakery.len(), 2);\n    assert_eq!(bakery[0].name, \"SeaSide Bakery\");\n    assert_eq!(bakery[1].name, \"LakeSide Bakery\");\n\n    let cake: Option<cake::Model> = cake::Entity::find()\n        .has_related(bakery::Entity, bakery::Column::Name.eq(\"SeaSide Bakery\"))\n        .order_by_asc(cake::Column::Name)\n        .one(db)\n        .await?;\n\n    assert_eq!(\n        cake::Entity::find()\n            .has_related(bakery::Entity, bakery::Column::Name.eq(\"SeaSide Bakery\"))\n            .build(DbBackend::Sqlite)\n            .to_string(),\n        [\n            r#\"SELECT \"cake\".\"id\", \"cake\".\"name\", \"cake\".\"price\", \"cake\".\"bakery_id\", \"cake\".\"gluten_free\", \"cake\".\"serial\" FROM \"cake\"\"#,\n            r#\"WHERE EXISTS(SELECT 1 FROM \"bakery\"\"#,\n            r#\"WHERE \"bakery\".\"name\" = 'SeaSide Bakery'\"#,\n            r#\"AND \"cake\".\"bakery_id\" = \"bakery\".\"id\")\"#,\n        ]\n        .join(\" \")\n    );\n\n    assert_eq!(cake.unwrap().name, \"Chocolate Cake\");\n\n    let baker: Vec<baker::Model> = baker::Entity::find()\n        .has_related(cake::Entity, cake::Column::Name.contains(\"Chocolate\"))\n        .all(db)\n        .await?;\n\n    assert_eq!(baker.len(), 1);\n    assert_eq!(baker[0].name, \"Alice\");\n\n    let baker: Vec<baker::Model> = baker::Entity::find()\n        .has_related(cake::Entity, cake::Column::Name.contains(\"Strawberry\"))\n        .all(db)\n        .await?;\n\n    assert_eq!(baker.len(), 1);\n    assert_eq!(baker[0].name, \"Bob\");\n\n    let baker: Vec<baker::Model> = baker::Entity::find()\n        .has_related(cake::Entity, cake::Column::Name.contains(\"Lemon\"))\n        .order_by_asc(baker::Column::Id)\n        .all(db)\n        .await?;\n\n    assert_eq!(baker.len(), 2);\n    assert_eq!(baker[0].name, \"Alice\");\n    assert_eq!(baker[1].name, \"Bob\");\n\n    let cake: Option<cake::Model> = cake::Entity::find()\n        .has_related(baker::Entity, baker::Column::Name.eq(\"Alice\"))\n        .order_by_asc(cake::Column::Name)\n        .one(db)\n        .await?;\n\n    assert_eq!(cake.unwrap().name, \"Chocolate Cake\");\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/returning_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse common::{TestContext, bakery_chain, setup::*};\nuse sea_orm::{IntoActiveModel, NotSet, Set, entity::prelude::*};\nuse sea_query::{Expr, Query};\nuse serde_json::json;\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    use bakery_chain::bakery::*;\n\n    let ctx = TestContext::new(\"returning_tests\").await;\n    let db = &ctx.db;\n    let builder = db.get_database_backend();\n\n    let mut insert = Query::insert();\n    insert\n        .into_table(Entity)\n        .columns([Column::Name, Column::ProfitMargin])\n        .values_panic([\"Bakery Shop\".into(), 0.5.into()]);\n\n    let mut update = Query::update();\n    update\n        .table(Entity)\n        .values([\n            (Column::Name, \"Bakery 2\".into()),\n            (Column::ProfitMargin, 0.8.into()),\n        ])\n        .and_where(Column::Id.eq(1));\n\n    let columns = [Column::Id, Column::Name, Column::ProfitMargin];\n    let returning =\n        Query::returning().exprs(columns.into_iter().map(|c| c.into_returning_expr(builder)));\n\n    bakery_chain::create_bakery_table(db).await?;\n\n    if db.support_returning() {\n        insert.returning(returning.clone());\n        let insert_res = db\n            .query_one(&insert)\n            .await?\n            .expect(\"Insert failed with query_one\");\n        let id: i32 = insert_res.try_get(\"\", \"id\")?;\n        assert_eq!(id, 1);\n        let name: String = insert_res.try_get(\"\", \"name\")?;\n        assert_eq!(name, \"Bakery Shop\");\n        let profit_margin: f64 = insert_res.try_get(\"\", \"profit_margin\")?;\n        assert_eq!(profit_margin, 0.5);\n\n        update.returning(returning.clone());\n        let update_res = db\n            .query_one(&update)\n            .await?\n            .expect(\"Update filed with query_one\");\n        let id: i32 = update_res.try_get(\"\", \"id\")?;\n        assert_eq!(id, 1);\n        let name: String = update_res.try_get(\"\", \"name\")?;\n        assert_eq!(name, \"Bakery 2\");\n        let profit_margin: f64 = update_res.try_get(\"\", \"profit_margin\")?;\n        assert_eq!(profit_margin, 0.8);\n    } else {\n        let insert_res = db.execute(&insert).await?;\n        assert!(insert_res.rows_affected() > 0);\n\n        let update_res = db.execute(&update).await?;\n        assert!(update_res.rows_affected() > 0);\n    }\n\n    ctx.delete().await;\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn insert_many() {\n    pub use common::{TestContext, features::*};\n    use edit_log::*;\n\n    let ctx = TestContext::new(\"returning_tests_insert_many\").await;\n    let db = &ctx.db;\n\n    create_edit_log_table(db).await.unwrap();\n\n    Entity::insert(ActiveModel {\n        id: NotSet,\n        action: Set(\"one\".into()),\n        values: Set(json!({ \"id\": \"unique-id-001\" })),\n    })\n    .exec(db)\n    .await\n    .unwrap();\n\n    assert_eq!(\n        Entity::find().all(db).await.unwrap(),\n        [Model {\n            id: 1,\n            action: \"one\".into(),\n            values: json!({ \"id\": \"unique-id-001\" }),\n        },]\n    );\n\n    assert!(\n        Entity::insert_many::<ActiveModel, _>([])\n            .exec_with_returning(db)\n            .await\n            .unwrap()\n            .is_empty()\n    );\n\n    let result = Entity::insert_many([\n        ActiveModel {\n            id: NotSet,\n            action: Set(\"two\".into()),\n            values: Set(json!({ \"id\": \"unique-id-002\" })),\n        },\n        ActiveModel {\n            id: NotSet,\n            action: Set(\"three\".into()),\n            values: Set(json!({ \"id\": \"unique-id-003\" })),\n        },\n    ])\n    .exec_with_returning(db)\n    .await;\n\n    if db.support_returning() {\n        assert_eq!(\n            result.unwrap(),\n            [\n                Model {\n                    id: 2,\n                    action: \"two\".into(),\n                    values: json!({ \"id\": \"unique-id-002\" }),\n                },\n                Model {\n                    id: 3,\n                    action: \"three\".into(),\n                    values: json!({ \"id\": \"unique-id-003\" }),\n                },\n            ]\n        );\n    } else {\n        assert!(matches!(result, Err(DbErr::BackendNotSupported { .. })));\n    }\n\n    assert!(\n        Entity::insert_many::<ActiveModel, _>([])\n            .exec_with_returning_keys(db)\n            .await\n            .unwrap()\n            .is_empty()\n    );\n\n    let result = Entity::insert_many([\n        ActiveModel {\n            id: NotSet,\n            action: Set(\"four\".into()),\n            values: Set(json!({ \"id\": \"unique-id-004\" })),\n        },\n        ActiveModel {\n            id: NotSet,\n            action: Set(\"five\".into()),\n            values: Set(json!({ \"id\": \"unique-id-005\" })),\n        },\n    ])\n    .exec_with_returning_keys(db)\n    .await;\n\n    if db.support_returning() {\n        assert_eq!(result.unwrap(), [4, 5]);\n    } else {\n        assert!(matches!(result, Err(DbErr::BackendNotSupported { .. })));\n    }\n}\n\n#[sea_orm_macros::test]\nasync fn insert_many_composite_key() {\n    use bakery_chain::{baker, cake, cakes_bakers};\n    pub use common::{TestContext, features::*};\n\n    let ctx = TestContext::new(\"returning_tests_insert_many_composite_key\").await;\n    let db = &ctx.db;\n\n    bakery_chain::create_bakery_table(db).await.unwrap();\n    bakery_chain::create_baker_table(db).await.unwrap();\n    bakery_chain::create_cake_table(db).await.unwrap();\n    bakery_chain::create_cakes_bakers_table(db).await.unwrap();\n\n    baker::Entity::insert_many([\n        baker::ActiveModel {\n            id: NotSet,\n            name: Set(\"Baker 1\".to_owned()),\n            contact_details: Set(json!(null)),\n            bakery_id: Set(None),\n        },\n        baker::ActiveModel {\n            id: NotSet,\n            name: Set(\"Baker 2\".to_owned()),\n            contact_details: Set(json!(null)),\n            bakery_id: Set(None),\n        },\n    ])\n    .exec(db)\n    .await\n    .unwrap();\n\n    cake::Entity::insert_many([\n        cake::ActiveModel {\n            id: NotSet,\n            name: Set(\"Cake 1\".to_owned()),\n            price: Set(Default::default()),\n            bakery_id: Set(None),\n            gluten_free: Set(false),\n            serial: Set(Default::default()),\n        },\n        cake::ActiveModel {\n            id: NotSet,\n            name: Set(\"Cake 2\".to_owned()),\n            price: Set(Default::default()),\n            bakery_id: Set(None),\n            gluten_free: Set(false),\n            serial: Set(Default::default()),\n        },\n    ])\n    .exec(db)\n    .await\n    .unwrap();\n\n    let result = cakes_bakers::Entity::insert_many([\n        cakes_bakers::ActiveModel {\n            cake_id: Set(1),\n            baker_id: Set(2),\n        },\n        cakes_bakers::ActiveModel {\n            cake_id: Set(2),\n            baker_id: Set(1),\n        },\n    ])\n    .exec_with_returning_keys(db)\n    .await;\n\n    if db.support_returning() {\n        assert_eq!(result.unwrap(), [(1, 2), (2, 1)]);\n    } else {\n        assert!(matches!(result, Err(DbErr::BackendNotSupported { .. })));\n    }\n}\n\n#[sea_orm_macros::test]\nasync fn update_many() -> Result<(), DbErr> {\n    pub use common::{TestContext, features::*};\n    use edit_log::*;\n\n    let ctx = TestContext::new(\"returning_tests_update_many\").await;\n    let db = &ctx.db;\n\n    create_edit_log_table(db).await?;\n\n    Entity::insert(\n        Model {\n            id: 1,\n            action: \"before_save\".into(),\n            values: json!({ \"id\": \"unique-id-001\" }),\n        }\n        .into_active_model(),\n    )\n    .exec(db)\n    .await?;\n\n    Entity::insert(\n        Model {\n            id: 2,\n            action: \"before_save\".into(),\n            values: json!({ \"id\": \"unique-id-002\" }),\n        }\n        .into_active_model(),\n    )\n    .exec(db)\n    .await?;\n\n    Entity::insert(\n        Model {\n            id: 3,\n            action: \"before_save\".into(),\n            values: json!({ \"id\": \"unique-id-003\" }),\n        }\n        .into_active_model(),\n    )\n    .exec(db)\n    .await?;\n\n    assert_eq!(\n        Entity::find().all(db).await?,\n        [\n            Model {\n                id: 1,\n                action: \"before_save\".into(),\n                values: json!({ \"id\": \"unique-id-001\" }),\n            },\n            Model {\n                id: 2,\n                action: \"before_save\".into(),\n                values: json!({ \"id\": \"unique-id-002\" }),\n            },\n            Model {\n                id: 3,\n                action: \"before_save\".into(),\n                values: json!({ \"id\": \"unique-id-003\" }),\n            },\n        ]\n    );\n\n    // Update many with returning\n    let result = Entity::update_many()\n        .col_expr(\n            Column::Values,\n            Expr::value(json!({ \"remarks\": \"save log\" })),\n        )\n        .filter(Column::Action.eq(\"before_save\"))\n        .exec_with_returning(db)\n        .await;\n\n    if db.support_returning() {\n        assert_eq!(\n            result.unwrap(),\n            [\n                Model {\n                    id: 1,\n                    action: \"before_save\".into(),\n                    values: json!({ \"remarks\": \"save log\" }),\n                },\n                Model {\n                    id: 2,\n                    action: \"before_save\".into(),\n                    values: json!({ \"remarks\": \"save log\" }),\n                },\n                Model {\n                    id: 3,\n                    action: \"before_save\".into(),\n                    values: json!({ \"remarks\": \"save log\" }),\n                },\n            ]\n        );\n    } else {\n        assert!(matches!(result, Err(DbErr::BackendNotSupported { .. })));\n    }\n\n    // No-op\n    assert_eq!(\n        Entity::update_many()\n            .filter(Column::Action.eq(\"before_save\"))\n            .exec_with_returning(db)\n            .await?,\n        []\n    );\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\nasync fn delete_many() -> Result<(), DbErr> {\n    pub use common::{TestContext, features::*};\n    use edit_log::*;\n\n    let ctx = TestContext::new(\"returning_tests_delete_many\").await;\n    let db = &ctx.db;\n\n    create_edit_log_table(db).await?;\n\n    let inserted_models = [\n        Model {\n            id: 1,\n            action: \"before_save\".to_string(),\n            values: json!({ \"id\": \"unique-id-001\" }),\n        },\n        Model {\n            id: 2,\n            action: \"before_save\".to_string(),\n            values: json!({ \"id\": \"unique-id-002\" }),\n        },\n    ];\n\n    if db.support_returning() {\n        assert_eq!(\n            Entity::insert_many(vec![\n                ActiveModel {\n                    id: NotSet,\n                    action: Set(\"before_save\".to_string()),\n                    values: Set(json!({ \"id\": \"unique-id-001\" })),\n                },\n                ActiveModel {\n                    id: NotSet,\n                    action: Set(\"before_save\".to_string()),\n                    values: Set(json!({ \"id\": \"unique-id-002\" })),\n                },\n            ])\n            .exec_with_returning(db)\n            .await\n            .unwrap(),\n            inserted_models\n        );\n    } else {\n        Entity::insert_many(vec![\n            ActiveModel {\n                id: NotSet,\n                action: Set(\"before_save\".to_string()),\n                values: Set(json!({ \"id\": \"unique-id-001\" })),\n            },\n            ActiveModel {\n                id: NotSet,\n                action: Set(\"before_save\".to_string()),\n                values: Set(json!({ \"id\": \"unique-id-002\" })),\n            },\n        ])\n        .exec(db)\n        .await\n        .unwrap();\n    }\n\n    if db.support_returning() {\n        assert_eq!(\n            Entity::delete_many()\n                .filter(Column::Action.eq(\"before_save\"))\n                .exec_with_returning(db)\n                .await\n                .unwrap(),\n            inserted_models\n        );\n    } else {\n        assert_eq!(\n            Entity::delete_many().exec(db).await.unwrap().rows_affected,\n            2\n        );\n    }\n\n    let inserted_model_3 = Model {\n        id: 3,\n        action: \"before_save\".to_string(),\n        values: json!({ \"id\": \"unique-id-003\" }),\n    };\n\n    Entity::insert(ActiveModel {\n        id: NotSet,\n        action: Set(\"before_save\".to_string()),\n        values: Set(json!({ \"id\": \"unique-id-003\" })),\n    })\n    .exec(db)\n    .await?;\n\n    // Delete one\n    if db.support_returning() {\n        assert_eq!(\n            Entity::delete(ActiveModel {\n                id: Set(3),\n                ..Default::default()\n            })\n            .exec_with_returning(db)\n            .await\n            .unwrap(),\n            Some(inserted_model_3)\n        );\n    } else {\n        assert_eq!(\n            Entity::delete(ActiveModel {\n                id: Set(3),\n                ..Default::default()\n            })\n            .exec(db)\n            .await\n            .unwrap()\n            .rows_affected,\n            1\n        );\n    }\n\n    // No-op\n    if db.support_returning() {\n        assert_eq!(\n            Entity::delete_many().exec_with_returning(db).await.unwrap(),\n            []\n        );\n    } else {\n        assert_eq!(\n            Entity::delete_many().exec(db).await.unwrap().rows_affected,\n            0\n        );\n    }\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/schema_sync_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse crate::common::TestContext;\nuse sea_orm::{\n    DatabaseConnection, DbErr,\n    entity::*,\n    query::*,\n    sea_query::{Condition, Expr, Query},\n};\n\n// Scenario 1: table is first synced with a `#[sea_orm(unique)]` column already\n// present. Repeated syncs must not drop the column-level unique constraint.\nmod item_v1 {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sync_item\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub name: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// Scenario 2a: initial version of the table — no unique column yet.\nmod product_v1 {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sync_product\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// Scenario 2b: updated version — a unique column is added.\nmod product_v2 {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sync_product\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub sku: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// Scenario 4a: initial version — column has UNIQUE.\nmod order_v1 {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sync_order\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub ref_no: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// Scenario 4b: UNIQUE removed from the column.\nmod order_v2 {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sync_order\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub ref_no: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// Scenario 3a: initial version — column exists without UNIQUE.\nmod user_v1 {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sync_user\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub email: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n// Scenario 3b: updated version — the existing column is made unique.\nmod user_v2 {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sync_user\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub email: String,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n/// Regression test for <https://github.com/SeaQL/sea-orm/issues/2970>.\n///\n/// A table with a `#[sea_orm(unique)]` column is created on the first sync.\n/// The subsequent sync must not attempt to drop the column-level unique index.\n#[sea_orm_macros::test]\nasync fn test_sync_unique_column_no_drop() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"test_sync_unique_column_no_drop\").await;\n    let db = &ctx.db;\n\n    #[cfg(feature = \"schema-sync\")]\n    {\n        // First sync: creates the table with the unique column\n        db.get_schema_builder()\n            .register(item_v1::Entity)\n            .sync(db)\n            .await?;\n\n        // Second sync: must not try to drop the column-level unique index\n        db.get_schema_builder()\n            .register(item_v1::Entity)\n            .sync(db)\n            .await?;\n\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert!(\n            pg_index_exists(db, \"sync_item\", \"sync_item_name_key\").await?,\n            \"unique index on `sync_item.name` should still exist after repeated sync\"\n        );\n    }\n\n    Ok(())\n}\n\n/// Regression test for <https://github.com/SeaQL/sea-orm/issues/2970>.\n///\n/// A unique column is added to an existing table via sync (ALTER TABLE ADD\n/// COLUMN … UNIQUE), which creates a column-level unique index. A subsequent\n/// sync must not attempt to drop that index.\n#[sea_orm_macros::test]\n#[cfg(not(any(feature = \"sqlx-sqlite\", feature = \"rusqlite\")))]\nasync fn test_sync_add_unique_column_no_drop() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"test_sync_add_unique_column_no_drop\").await;\n    let db = &ctx.db;\n\n    #[cfg(feature = \"schema-sync\")]\n    {\n        // First sync: creates the table without the unique column\n        db.get_schema_builder()\n            .register(product_v1::Entity)\n            .sync(db)\n            .await?;\n\n        // Second sync: adds the unique column via ALTER TABLE ADD COLUMN … UNIQUE\n        db.get_schema_builder()\n            .register(product_v2::Entity)\n            .sync(db)\n            .await?;\n\n        // Third sync: must not try to drop the unique index created above\n        db.get_schema_builder()\n            .register(product_v2::Entity)\n            .sync(db)\n            .await?;\n\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert!(\n            pg_index_exists(db, \"sync_product\", \"sync_product_sku_key\").await?,\n            \"unique index on `sync_product.sku` should still exist after repeated sync\"\n        );\n    }\n\n    Ok(())\n}\n\n/// Scenario 3: an existing column is made unique in a later sync.\n///\n/// When a column that already exists in the DB is annotated with\n/// `#[sea_orm(unique)]`, the sync must create a unique index for it.\n#[sea_orm_macros::test]\nasync fn test_sync_make_existing_column_unique() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"test_sync_make_existing_column_unique\").await;\n    let db = &ctx.db;\n\n    #[cfg(feature = \"schema-sync\")]\n    {\n        // First sync: creates the table with a plain (non-unique) email column\n        db.get_schema_builder()\n            .register(user_v1::Entity)\n            .sync(db)\n            .await?;\n\n        // Second sync: email is now marked unique — should create the unique index\n        db.get_schema_builder()\n            .register(user_v2::Entity)\n            .sync(db)\n            .await?;\n\n        // Third sync: must not try to drop or re-create the index\n        db.get_schema_builder()\n            .register(user_v2::Entity)\n            .sync(db)\n            .await?;\n\n        #[cfg(feature = \"sqlx-postgres\")]\n        assert!(\n            pg_index_exists(db, \"sync_user\", \"idx-sync_user-email\").await?,\n            \"unique index on `sync_user.email` should be created when column is made unique\"\n        );\n    }\n\n    Ok(())\n}\n\n/// Regression test for <https://github.com/SeaQL/sea-orm/issues/2994>.\n///\n/// A column marked `#[sea_orm(unique)]` is synced, then the unique attribute is\n/// removed. The second sync must drop the PostgreSQL constraint without error.\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-postgres\")]\nasync fn test_sync_drop_unique_constraint() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"test_sync_drop_unique_constraint\").await;\n    let db = &ctx.db;\n\n    #[cfg(feature = \"schema-sync\")]\n    {\n        // First sync: creates the table with the unique constraint\n        db.get_schema_builder()\n            .register(order_v1::Entity)\n            .sync(db)\n            .await?;\n\n        assert!(\n            pg_index_exists(db, \"sync_order\", \"sync_order_ref_no_key\").await?,\n            \"unique constraint should exist after first sync\"\n        );\n\n        // Second sync: unique is removed — must not error on PostgreSQL\n        db.get_schema_builder()\n            .register(order_v2::Entity)\n            .sync(db)\n            .await?;\n\n        assert!(\n            !pg_index_exists(db, \"sync_order\", \"sync_order_ref_no_key\").await?,\n            \"unique constraint should be gone after second sync\"\n        );\n    }\n\n    Ok(())\n}\n\n#[cfg(feature = \"sqlx-postgres\")]\nasync fn pg_index_exists(db: &DatabaseConnection, table: &str, index: &str) -> Result<bool, DbErr> {\n    db.query_one(\n        Query::select()\n            .expr(Expr::cust(\"COUNT(*) > 0\"))\n            .from(\"pg_indexes\")\n            .cond_where(\n                Condition::all()\n                    .add(Expr::cust(\"schemaname = CURRENT_SCHEMA()\"))\n                    .add(Expr::col(\"tablename\").eq(table))\n                    .add(Expr::col(\"indexname\").eq(index)),\n            ),\n    )\n    .await?\n    .unwrap()\n    .try_get_by_index(0)\n    .map_err(DbErr::from)\n}\n"
  },
  {
    "path": "tests/self_join_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DbBackend, IntoActiveModel, QueryOrder, entity::prelude::*, query::*};\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"self_join_tests\").await;\n    create_self_join_table(&ctx.db).await?;\n    create_metadata(&ctx.db).await?;\n    ctx.delete().await;\n    find_linked_001();\n    find_also_linked_001();\n\n    Ok(())\n}\n\npub async fn create_metadata(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let model = self_join::Model {\n        uuid: Uuid::new_v4(),\n        uuid_ref: None,\n        time: Some(Time::from_hms_opt(1, 00, 00).unwrap()),\n    };\n\n    model.clone().into_active_model().insert(db).await?;\n\n    let linked_model = self_join::Model {\n        uuid: Uuid::new_v4(),\n        uuid_ref: Some(model.clone().uuid),\n        time: Some(Time::from_hms_opt(2, 00, 00).unwrap()),\n    };\n\n    linked_model.clone().into_active_model().insert(db).await?;\n\n    let not_linked_model = self_join::Model {\n        uuid: Uuid::new_v4(),\n        uuid_ref: None,\n        time: Some(Time::from_hms_opt(3, 00, 00).unwrap()),\n    };\n\n    not_linked_model\n        .clone()\n        .into_active_model()\n        .insert(db)\n        .await?;\n\n    assert_eq!(\n        model\n            .find_linked(self_join::SelfReferencingLink)\n            .all(db)\n            .await?,\n        Vec::<self_join::Model>::new()\n    );\n\n    assert_eq!(\n        linked_model\n            .find_linked(self_join::SelfReferencingLink)\n            .all(db)\n            .await?,\n        [model.clone()]\n    );\n\n    assert_eq!(\n        not_linked_model\n            .find_linked(self_join::SelfReferencingLink)\n            .all(db)\n            .await?,\n        Vec::<self_join::Model>::new()\n    );\n\n    assert_eq!(\n        self_join::Entity::find()\n            .find_also_linked(self_join::SelfReferencingLink)\n            .order_by_asc(self_join::Column::Time)\n            .all(db)\n            .await?,\n        [\n            (model.clone(), None),\n            (linked_model, Some(model)),\n            (not_linked_model, None),\n        ]\n    );\n\n    Ok(())\n}\n\nfn find_linked_001() {\n    use self_join::*;\n\n    let self_join_model = Model {\n        uuid: Uuid::default(),\n        uuid_ref: None,\n        time: None,\n    };\n\n    assert_eq!(\n        self_join_model\n            .find_linked(SelfReferencingLink)\n            .build(DbBackend::MySql)\n            .to_string(),\n        [\n            r\"SELECT `self_join`.`uuid`, `self_join`.`uuid_ref`, `self_join`.`time`\",\n            r\"FROM `self_join`\",\n            r\"INNER JOIN `self_join` AS `r0` ON `r0`.`uuid_ref` = `self_join`.`uuid`\",\n            r\"WHERE `r0`.`uuid` = '00000000-0000-0000-0000-000000000000'\",\n        ]\n        .join(\" \")\n    );\n}\n\nfn find_also_linked_001() {\n    use self_join::*;\n\n    assert_eq!(\n        Entity::find()\n            .find_also_linked(SelfReferencingLink)\n            .build(DbBackend::MySql)\n            .to_string(),\n        [\n            r\"SELECT `self_join`.`uuid` AS `A_uuid`, `self_join`.`uuid_ref` AS `A_uuid_ref`, `self_join`.`time` AS `A_time`,\",\n            r\"`r0`.`uuid` AS `B_uuid`, `r0`.`uuid_ref` AS `B_uuid_ref`, `r0`.`time` AS `B_time`\",\n            r\"FROM `self_join`\",\n            r\"LEFT JOIN `self_join` AS `r0` ON `self_join`.`uuid_ref` = `r0`.`uuid`\",\n        ]\n        .join(\" \")\n    );\n}\n"
  },
  {
    "path": "tests/sequential_op_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse common::{TestContext, bakery_chain::*, setup::*};\nuse rust_decimal::prelude::*;\nuse sea_orm::{DatabaseConnection, FromQueryResult, entity::*, prelude::ChronoUtc, query::*};\nuse uuid::Uuid;\n\n// Run the test locally:\n// DATABASE_URL=\"mysql://root:@localhost\" cargo test --features sqlx-mysql,runtime-async-std --test sequential_op_tests\n#[sea_orm_macros::test]\n#[cfg(any(feature = \"sqlx-mysql\", feature = \"sqlx-postgres\"))]\npub async fn test_multiple_operations() {\n    let ctx = TestContext::new(\"multiple_sequential_operations\").await;\n\n    create_tables(&ctx.db).await.unwrap();\n    seed_data(&ctx.db).await;\n    let baker_least_sales = find_baker_least_sales(&ctx.db).await.unwrap();\n    assert_eq!(baker_least_sales.name, \"Baker 2\");\n\n    let new_cake = create_cake(&ctx.db, baker_least_sales).await.unwrap();\n    create_order(&ctx.db, new_cake).await;\n\n    let baker_least_sales = find_baker_least_sales(&ctx.db).await.unwrap();\n    assert_eq!(baker_least_sales.name, \"Baker 1\");\n\n    ctx.delete().await;\n}\n\nasync fn seed_data(db: &DatabaseConnection) {\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    let baker_1 = baker::ActiveModel {\n        name: Set(\"Baker 1\".to_owned()),\n        contact_details: Set(serde_json::json!({})),\n        bakery_id: Set(Some(bakery.id.clone().unwrap())),\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert baker\");\n\n    let _baker_2 = baker::ActiveModel {\n        name: Set(\"Baker 2\".to_owned()),\n        contact_details: Set(serde_json::json!({})),\n        bakery_id: Set(Some(bakery.id.clone().unwrap())),\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert baker\");\n\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Mud Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(bakery.id.clone().unwrap())),\n        ..Default::default()\n    };\n\n    let mud_cake = Cake::insert(mud_cake)\n        .exec(db)\n        .await\n        .expect(\"could not insert cake\");\n\n    let choc_cake = cake::ActiveModel {\n        name: Set(\"Choc Cake\".to_owned()),\n        price: Set(rust_dec(9.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(bakery.id.clone().unwrap())),\n        ..Default::default()\n    };\n\n    let choc_cake = Cake::insert(choc_cake)\n        .exec(db)\n        .await\n        .expect(\"could not insert cake\");\n\n    let cake_baker = cakes_bakers::ActiveModel {\n        cake_id: Set(mud_cake.last_insert_id),\n        baker_id: Set(baker_1.id.clone().unwrap()),\n    };\n\n    let cake_baker_res = CakesBakers::insert(cake_baker.clone())\n        .exec(db)\n        .await\n        .expect(\"could not insert cake_baker\");\n    assert_eq!(\n        cake_baker_res.last_insert_id,\n        (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())\n    );\n\n    let customer_kate = customer::ActiveModel {\n        name: Set(\"Kate\".to_owned()),\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let kate_order_1 = order::ActiveModel {\n        bakery_id: Set(bakery.id.clone().unwrap()),\n        customer_id: Set(customer_kate.id.clone().unwrap()),\n        total: Set(rust_dec(99.95)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert order\");\n\n    let _lineitem = lineitem::ActiveModel {\n        cake_id: Set(mud_cake.last_insert_id),\n        price: Set(rust_dec(10.00)),\n        quantity: Set(12),\n        order_id: Set(kate_order_1.id.clone().unwrap()),\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert order\");\n\n    let _lineitem2 = lineitem::ActiveModel {\n        cake_id: Set(choc_cake.last_insert_id),\n        price: Set(rust_dec(50.00)),\n        quantity: Set(2),\n        order_id: Set(kate_order_1.id.clone().unwrap()),\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert order\");\n\n    assert!(\n        lineitem::ActiveModel {\n            cake_id: Set(choc_cake.last_insert_id),\n            price: Set(rust_dec(50.00)),\n            quantity: Set(2),\n            order_id: Set(kate_order_1.id.clone().unwrap()),\n            ..Default::default()\n        }\n        .save(db)\n        .await\n        .is_err()\n    ); // violates unique key\n}\n\nasync fn find_baker_least_sales(db: &DatabaseConnection) -> Option<baker::Model> {\n    #[cfg(any(feature = \"sqlx-postgres\"))]\n    type Type = i64;\n    #[cfg(not(any(feature = \"sqlx-postgres\")))]\n    type Type = Decimal;\n\n    #[derive(Debug, FromQueryResult)]\n    struct SelectResult {\n        id: i32,\n        cakes_sold_opt: Option<Type>,\n    }\n\n    #[derive(Debug)]\n    struct LeastSalesBakerResult {\n        id: i32,\n        cakes_sold: Decimal,\n    }\n\n    let rel: RelationDef = cakes_bakers::Entity::belongs_to(baker::Entity)\n        .from(cakes_bakers::Column::BakerId)\n        .to(baker::Column::Id)\n        .into();\n\n    let rel2: RelationDef = cakes_bakers::Entity::belongs_to(cake::Entity)\n        .from(cakes_bakers::Column::CakeId)\n        .to(cake::Column::Id)\n        .into();\n\n    let rel3: RelationDef = cake::Entity::has_many(lineitem::Entity)\n        .from(cake::Column::Id)\n        .to(lineitem::Column::CakeId)\n        .into();\n\n    let select = cakes_bakers::Entity::find()\n        .join(JoinType::RightJoin, rel)\n        .join(JoinType::LeftJoin, rel2)\n        .join(JoinType::LeftJoin, rel3)\n        .select_only()\n        .column(baker::Column::Id)\n        .column_as(lineitem::Column::Quantity.sum(), \"cakes_sold_opt\")\n        .group_by(baker::Column::Id);\n\n    let mut results: Vec<LeastSalesBakerResult> = select\n        .into_model::<SelectResult>()\n        .all(db)\n        .await\n        .unwrap()\n        .into_iter()\n        .map(|b| LeastSalesBakerResult {\n            id: b.id,\n            cakes_sold: b.cakes_sold_opt.unwrap_or_default().into(),\n        })\n        .collect();\n\n    results.sort_by(|a, b| b.cakes_sold.cmp(&a.cakes_sold));\n\n    Baker::find_by_id(results.last().unwrap().id)\n        .one(db)\n        .await\n        .unwrap()\n}\n\nasync fn create_cake(db: &DatabaseConnection, baker: baker::Model) -> Option<cake::Model> {\n    let new_cake = cake::ActiveModel {\n        name: Set(\"New Cake\".to_owned()),\n        price: Set(rust_dec(8.00)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(baker.bakery_id.unwrap())),\n        ..Default::default()\n    };\n\n    let cake_insert_res = Cake::insert(new_cake)\n        .exec(db)\n        .await\n        .expect(\"could not insert cake\");\n\n    let cake_baker = cakes_bakers::ActiveModel {\n        cake_id: Set(cake_insert_res.last_insert_id),\n        baker_id: Set(baker.id),\n    };\n\n    let cake_baker_res = CakesBakers::insert(cake_baker.clone())\n        .exec(db)\n        .await\n        .expect(\"could not insert cake_baker\");\n    assert_eq!(\n        cake_baker_res.last_insert_id,\n        (cake_baker.cake_id.unwrap(), cake_baker.baker_id.unwrap())\n    );\n\n    Cake::find_by_id(cake_insert_res.last_insert_id)\n        .one(db)\n        .await\n        .unwrap()\n}\n\nasync fn create_order(db: &DatabaseConnection, cake: cake::Model) {\n    let another_customer = customer::ActiveModel {\n        name: Set(\"John\".to_owned()),\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert customer\");\n\n    let order = order::ActiveModel {\n        bakery_id: Set(cake.bakery_id.unwrap()),\n        customer_id: Set(another_customer.id.clone().unwrap()),\n        total: Set(rust_dec(200.00)),\n        placed_at: Set(ChronoUtc::now()),\n\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert order\");\n\n    let _lineitem = lineitem::ActiveModel {\n        cake_id: Set(cake.id),\n        price: Set(rust_dec(10.00)),\n        quantity: Set(300),\n        order_id: Set(order.id.clone().unwrap()),\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert order\");\n}\n\npub async fn test_delete_bakery(db: &DatabaseConnection) {\n    let initial_bakeries = Bakery::find().all(db).await.unwrap().len();\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(db)\n    .await\n    .expect(\"could not insert bakery\");\n\n    assert_eq!(\n        Bakery::find().all(db).await.unwrap().len(),\n        initial_bakeries + 1\n    );\n\n    let _result = bakery.delete(db).await.expect(\"failed to delete bakery\");\n\n    assert_eq!(\n        Bakery::find().all(db).await.unwrap().len(),\n        initial_bakeries\n    );\n}\n"
  },
  {
    "path": "tests/sql_err_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\npub use common::{TestContext, bakery_chain::*, setup::*};\npub use sea_orm::{\n    ConnectionTrait, DatabaseConnection, DbBackend, EntityName, ExecResult, entity::*,\n    error::DbErr, error::SqlErr, tests_cfg,\n};\nuse uuid::Uuid;\n\n#[sea_orm_macros::test]\nasync fn main() {\n    let ctx = TestContext::new(\"bakery_chain_sql_err_tests\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n    create_cake_table(&ctx.db).await.unwrap();\n    test_error(&ctx.db).await;\n    ctx.delete().await;\n}\n\npub async fn test_error(db: &DatabaseConnection) {\n    let mud_cake = cake::ActiveModel {\n        name: Set(\"Moldy Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(None),\n        ..Default::default()\n    };\n\n    let cake = mud_cake.save(db).await.expect(\"could not insert cake\");\n\n    // if compiling without sqlx, this assignment will complain,\n    // but the whole test is useless in that case anyway.\n    #[allow(unused_variables)]\n    let error: DbErr = cake\n        .into_active_model()\n        .insert(db)\n        .await\n        .expect_err(\"inserting should fail due to duplicate primary key\");\n\n    assert!(matches!(\n        error.sql_err(),\n        Some(SqlErr::UniqueConstraintViolation(_))\n    ));\n\n    let fk_cake = cake::ActiveModel {\n        name: Set(\"fk error Cake\".to_owned()),\n        price: Set(rust_dec(10.25)),\n        gluten_free: Set(false),\n        serial: Set(Uuid::new_v4()),\n        bakery_id: Set(Some(1000)),\n        ..Default::default()\n    };\n\n    let fk_error = fk_cake\n        .insert(db)\n        .await\n        .expect_err(\"create foreign key should fail with non-primary key\");\n\n    assert!(matches!(\n        fk_error.sql_err(),\n        Some(SqlErr::ForeignKeyConstraintViolation(_))\n    ));\n\n    let invalid_error = DbErr::Custom(\"random error\".to_string());\n    assert_eq!(invalid_error.sql_err(), None)\n}\n"
  },
  {
    "path": "tests/stream_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\npub use sea_orm::entity::*;\npub use sea_orm::{ConnectionTrait, DbErr, QueryFilter};\n\n#[sea_orm_macros::test]\npub async fn stream() -> Result<(), DbErr> {\n    use futures_util::StreamExt;\n\n    let ctx = TestContext::new(\"stream\").await;\n    create_bakery_table(&ctx.db).await?;\n\n    let bakery = bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n    .save(&ctx.db)\n    .await?;\n\n    let result = Bakery::find_by_id(bakery.id.clone().unwrap())\n        .stream(&ctx.db)\n        .await?\n        .next()\n        .await\n        .unwrap()?;\n\n    assert_eq!(result.id, bakery.id.unwrap());\n\n    ctx.delete().await;\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/string_primary_key_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, TryInsertResult, entity::prelude::*, entity::*};\nuse serde_json::json;\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"features_schema_string_primary_key_tests\").await;\n    create_repository_table(&ctx.db).await?;\n    create_edit_log_table(&ctx.db).await?;\n    create_and_update_repository(&ctx.db).await?;\n    insert_and_delete_repository(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn insert_and_delete_repository(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let repository = repository::Model {\n        id: \"unique-id-001\".to_owned(),\n        owner: \"GC\".to_owned(),\n        name: \"G.C.\".to_owned(),\n        description: None,\n    }\n    .into_active_model();\n\n    let result = repository.clone().insert(db).await?;\n\n    assert_eq!(\n        result,\n        repository::Model {\n            id: \"unique-id-001\".to_owned(),\n            owner: \"GC\".to_owned(),\n            name: \"G.C.\".to_owned(),\n            description: None,\n        }\n    );\n\n    #[cfg(any(feature = \"sqlx-sqlite\", feature = \"sqlx-postgres\"))]\n    {\n        use sea_orm::sea_query::OnConflict;\n\n        let err = Repository::insert(repository.clone())\n            // MySQL does not support DO NOTHING, we might workaround that later\n            .on_conflict(OnConflict::new().do_nothing().to_owned())\n            .exec(db)\n            .await;\n\n        assert_eq!(err.err(), Some(DbErr::RecordNotInserted));\n    }\n\n    result.delete(db).await?;\n\n    assert_eq!(\n        edit_log::Entity::find().all(db).await?,\n        [\n            edit_log::Model {\n                id: 1,\n                action: \"before_save\".into(),\n                values: json!({\n                    \"description\": null,\n                    \"id\": \"unique-id-001\",\n                    \"name\": \"G.C.\",\n                    \"owner\": \"GC\",\n                }),\n            },\n            edit_log::Model {\n                id: 2,\n                action: \"after_save\".into(),\n                values: json!({\n                    \"description\": null,\n                    \"id\": \"unique-id-001\",\n                    \"name\": \"G.C.\",\n                    \"owner\": \"GC\",\n                }),\n            },\n            edit_log::Model {\n                id: 3,\n                action: \"before_delete\".into(),\n                values: json!({\n                    \"description\": null,\n                    \"id\": \"unique-id-001\",\n                    \"name\": \"G.C.\",\n                    \"owner\": \"GC\",\n                }),\n            },\n            edit_log::Model {\n                id: 4,\n                action: \"after_delete\".into(),\n                values: json!({\n                    \"description\": null,\n                    \"id\": \"unique-id-001\",\n                    \"name\": \"G.C.\",\n                    \"owner\": \"GC\",\n                }),\n            },\n        ]\n    );\n\n    #[cfg(any(feature = \"sqlx-sqlite\", feature = \"sqlx-postgres\"))]\n    {\n        let result = Repository::insert_many([\n            repository::Model {\n                id: \"unique-id-002\".to_owned(), // conflict\n                owner: \"GC\".to_owned(),\n                name: \"G.C.\".to_owned(),\n                description: None,\n            }\n            .into_active_model(),\n            repository::Model {\n                id: \"unique-id-003\".to_owned(), // insert succeed\n                owner: \"GC\".to_owned(),\n                name: \"G.C.\".to_owned(),\n                description: None,\n            }\n            .into_active_model(),\n        ])\n        .on_conflict_do_nothing()\n        .exec_with_returning_many(db)\n        .await?;\n\n        match result {\n            TryInsertResult::Inserted(inserted) => {\n                assert_eq!(inserted.len(), 1);\n                assert_eq!(inserted[0].id, \"unique-id-003\");\n            }\n            _ => panic!(\"{result:?}\"),\n        }\n    }\n\n    Ok(())\n}\n\npub async fn create_and_update_repository(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let repository = repository::Model {\n        id: \"unique-id-002\".to_owned(),\n        owner: \"GC\".to_owned(),\n        name: \"G.C.\".to_owned(),\n        description: None,\n    };\n\n    let res = Repository::insert(repository.clone().into_active_model())\n        .exec(db)\n        .await?;\n\n    assert_eq!(Repository::find().one(db).await?, Some(repository.clone()));\n\n    assert_eq!(res.last_insert_id, repository.id);\n\n    let updated_active_model = repository::ActiveModel {\n        description: Set(Some(\"description...\".to_owned())),\n        ..repository.clone().into_active_model()\n    };\n\n    let update_res = Repository::update(updated_active_model.clone())\n        .validate()?\n        .filter(repository::Column::Id.eq(\"not-exists-id\".to_owned()))\n        .exec(db)\n        .await;\n\n    assert_eq!(update_res, Err(DbErr::RecordNotUpdated));\n\n    let update_res = Repository::update(updated_active_model)\n        .validate()?\n        .filter(repository::Column::Id.eq(\"unique-id-002\".to_owned()))\n        .exec(db)\n        .await?;\n\n    assert_eq!(\n        update_res,\n        repository::Model {\n            id: \"unique-id-002\".to_owned(),\n            owner: \"GC\".to_owned(),\n            name: \"G.C.\".to_owned(),\n            description: Some(\"description...\".to_owned()),\n        }\n    );\n\n    let updated_active_model = repository::ActiveModel {\n        description: Set(None),\n        ..repository.clone().into_active_model()\n    };\n\n    let update_res = Repository::update(updated_active_model.clone())\n        .validate()?\n        .filter(repository::Column::Id.eq(\"unique-id-002\".to_owned()))\n        .exec(db)\n        .await?;\n\n    assert_eq!(\n        update_res,\n        repository::Model {\n            id: \"unique-id-002\".to_owned(),\n            owner: \"GC\".to_owned(),\n            name: \"G.C.\".to_owned(),\n            description: None,\n        }\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/text_uuid_tests.rs",
    "content": "pub mod common;\nuse common::{TestContext, features::*, setup::*};\nuse sea_orm::{DatabaseConnection, IntoActiveModel, NotSet, Set, entity::prelude::*};\nuse uuid::Uuid;\n\nmod sample {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"sample\")]\n    pub struct Model {\n        #[sea_orm(primary_key, auto_increment = false)]\n        pub id: TextUuid,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[sea_orm_macros::test]\nasync fn text_uuid_test() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"text_uuid_test\").await;\n    let db = &ctx.db;\n\n    let uuid = Uuid::new_v4();\n\n    db.get_schema_builder()\n        .register(sample::Entity)\n        .apply(db)\n        .await?;\n\n    let entry = sample::ActiveModel {\n        id: Set(uuid.into()),\n    }\n    .insert(db)\n    .await?;\n\n    assert_eq!(*entry.id, uuid);\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/time_crate_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, IntoActiveModel, entity::prelude::*};\nuse serde_json::json;\nuse time::macros::{date, time};\n\n#[sea_orm_macros::test]\nasync fn main() {\n    let ctx = TestContext::new(\"time_crate_tests\").await;\n    create_transaction_log_table(&ctx.db).await.unwrap();\n    create_transaction_log(&ctx.db).await.unwrap();\n\n    ctx.delete().await;\n}\n\npub async fn create_transaction_log(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let transaction_log = transaction_log::Model {\n        id: 1,\n        date: date!(2022 - 03 - 13),\n        time: time!(16:24:00),\n        date_time: date!(2022 - 03 - 13).with_time(time!(16:24:00)),\n        date_time_tz: date!(2022 - 03 - 13)\n            .with_time(time!(16:24:00))\n            .assume_utc(),\n    };\n\n    let res = TransactionLog::insert(transaction_log.clone().into_active_model())\n        .exec(db)\n        .await?;\n\n    assert_eq!(transaction_log.id, res.last_insert_id);\n    assert_eq!(\n        TransactionLog::find().one(db).await?,\n        Some(transaction_log.clone())\n    );\n\n    let json = TransactionLog::find().into_json().one(db).await?.unwrap();\n\n    #[cfg(feature = \"sqlx-postgres\")]\n    assert_eq!(\n        json,\n        json!({\n            \"id\": 1,\n            \"date\": \"2022-03-13\",\n            \"time\": \"16:24:00\",\n            \"date_time\": \"2022-03-13T16:24:00\",\n            \"date_time_tz\": \"2022-03-13T16:24:00Z\",\n        })\n    );\n\n    #[cfg(feature = \"sqlx-mysql\")]\n    assert_eq!(\n        json,\n        json!({\n            \"id\": 1,\n            \"date\": \"2022-03-13\",\n            \"time\": \"16:24:00\",\n            \"date_time\": \"2022-03-13T16:24:00\",\n            \"date_time_tz\": \"2022-03-13T16:24:00Z\",\n        })\n    );\n\n    #[cfg(all(not(feature = \"sync\"), feature = \"sqlx-sqlite\"))]\n    assert_eq!(\n        json,\n        json!({\n            \"id\": 1,\n            \"date\": \"2022-03-13\",\n            \"time\": \"16:24:00.0\",\n            \"date_time\": \"2022-03-13 16:24:00.0\",\n            \"date_time_tz\": \"2022-03-13T16:24:00Z\",\n        })\n    );\n\n    #[cfg(feature = \"rusqlite\")]\n    assert_eq!(\n        json,\n        json!({\n            \"id\": 1,\n            \"date\": \"2022-03-13\",\n            \"time\": \"16:24:00.0\",\n            \"date_time\": \"2022-03-13 16:24:00.0\",\n            \"date_time_tz\": \"2022-03-13 16:24:00.0+00:00\",\n        })\n    );\n\n    assert_ne!(json, \"\");\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/timestamp_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, IntoActiveModel, NotSet, Set, entity::prelude::*};\n\n#[sea_orm_macros::test]\nasync fn bakery_chain_schema_timestamp_tests() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"bakery_chain_schema_timestamp_tests\").await;\n    create_log_table(&ctx.db).await?;\n    create_satellites_table(&ctx.db).await?;\n    create_applog(&ctx.db).await?;\n    create_satellites_log(&ctx.db).await?;\n\n    ctx.delete().await;\n\n    Ok(())\n}\n\nmod access_log {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"access_log\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        pub ts: ChronoUnixTimestamp,\n        pub ms: ChronoUnixTimestampMillis,\n        pub tts: TimeUnixTimestamp,\n        pub tms: TimeUnixTimestampMillis,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\n#[sea_orm_macros::test]\nasync fn entity_timestamp_test() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"entity_timestamp_test\").await;\n    let db = &ctx.db;\n\n    db.get_schema_builder()\n        .register(access_log::Entity)\n        .apply(db)\n        .await?;\n\n    let now = sea_orm::prelude::ChronoUtc::now();\n    let time_now = sea_orm::prelude::TimeDateTimeWithTimeZone::from_unix_timestamp_nanos(\n        now.timestamp_nanos_opt().unwrap() as i128,\n    )\n    .unwrap();\n\n    let log = access_log::ActiveModel {\n        id: NotSet,\n        ts: Set(now.into()),\n        ms: Set(ChronoUnixTimestampMillis(now)),\n        tts: Set(TimeUnixTimestamp(time_now)),\n        tms: Set(time_now.into()),\n    }\n    .insert(db)\n    .await?;\n\n    assert_eq!(log.ts.timestamp(), now.timestamp());\n    assert_eq!(log.ms.timestamp_millis(), now.timestamp_millis());\n\n    assert_eq!(log.tts.unix_timestamp(), now.timestamp());\n    assert_eq!(\n        log.tms.unix_timestamp_nanos() / 1_000_000,\n        now.timestamp_millis() as i128\n    );\n\n    #[derive(DerivePartialModel)]\n    #[sea_orm(entity = \"access_log::Entity\")]\n    struct AccessLog {\n        ts: i64,\n        ms: i64,\n        tts: i64,\n        tms: i64,\n    }\n\n    let log: AccessLog = access_log::Entity::find()\n        .into_partial_model()\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(log.ts, now.timestamp());\n    assert_eq!(log.ms, now.timestamp_millis());\n    assert_eq!(log.tts, now.timestamp());\n    assert_eq!(log.tms, now.timestamp_millis());\n\n    Ok(())\n}\n\npub async fn create_applog(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let log = applog::Model {\n        id: 1,\n        action: \"Testing\".to_owned(),\n        json: Json::String(\"HI\".to_owned()),\n        created_at: \"2021-09-17T17:50:20+08:00\".parse().unwrap(),\n    };\n\n    let res = Applog::insert(log.clone().into_active_model())\n        .exec(db)\n        .await?;\n\n    assert_eq!(log.id, res.last_insert_id);\n    assert_eq!(Applog::find().one(db).await?, Some(log.clone()));\n\n    #[cfg(all(not(feature = \"sync\"), feature = \"sqlx-sqlite\"))]\n    assert_eq!(\n        Applog::find().into_json().one(db).await?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"action\": \"Testing\",\n            \"json\": r#\"\"HI\"\"#,\n            \"created_at\": \"2021-09-17T17:50:20+08:00\",\n        }))\n    );\n    #[cfg(feature = \"rusqlite\")]\n    assert_eq!(\n        Applog::find().into_json().one(db)?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"action\": \"Testing\",\n            \"json\": r#\"\"HI\"\"#,\n            \"created_at\": \"2021-09-17 17:50:20+08:00\",\n        }))\n    );\n    #[cfg(feature = \"sqlx-mysql\")]\n    assert_eq!(\n        Applog::find().into_json().one(db).await?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"action\": \"Testing\",\n            \"json\": \"HI\",\n            \"created_at\": \"2021-09-17T09:50:20Z\",\n        }))\n    );\n    #[cfg(feature = \"sqlx-postgres\")]\n    assert_eq!(\n        Applog::find().into_json().one(db).await?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"action\": \"Testing\",\n            \"json\": \"HI\",\n            \"created_at\": \"2021-09-17T09:50:20Z\",\n        }))\n    );\n\n    Ok(())\n}\n\npub async fn create_satellites_log(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let archive = satellite::Model {\n        id: 1,\n        satellite_name: \"Sea-00001-2022\".to_owned(),\n        launch_date: \"2022-01-07T12:11:23Z\".parse().unwrap(),\n        deployment_date: \"2022-01-07T12:11:23Z\".parse().unwrap(),\n    };\n\n    let res = Satellite::insert(archive.clone().into_active_model())\n        .exec(db)\n        .await?;\n\n    assert_eq!(archive.id, res.last_insert_id);\n    assert_eq!(Satellite::find().one(db).await?, Some(archive.clone()));\n\n    #[cfg(all(not(feature = \"sync\"), feature = \"sqlx-sqlite\"))]\n    assert_eq!(\n        Satellite::find().into_json().one(db).await?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"satellite_name\": \"Sea-00001-2022\",\n            \"launch_date\": \"2022-01-07T12:11:23+00:00\",\n            \"deployment_date\": \"2022-01-07T12:11:23Z\".parse::<DateTimeLocal>().unwrap().to_rfc3339(),\n        }))\n    );\n    #[cfg(feature = \"rusqlite\")]\n    assert_eq!(\n        Satellite::find().into_json().one(db)?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"satellite_name\": \"Sea-00001-2022\",\n            \"launch_date\": \"2022-01-07 12:11:23+00:00\",\n            \"deployment_date\": \"2022-01-07 12:11:23+00:00\"\n        }))\n    );\n    #[cfg(feature = \"sqlx-mysql\")]\n    assert_eq!(\n        Satellite::find().into_json().one(db).await?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"satellite_name\": \"Sea-00001-2022\",\n            \"launch_date\": \"2022-01-07T12:11:23Z\",\n            \"deployment_date\": \"2022-01-07T12:11:23Z\",\n        }))\n    );\n    #[cfg(feature = \"sqlx-postgres\")]\n    assert_eq!(\n        Satellite::find().into_json().one(db).await?,\n        Some(serde_json::json!({\n            \"id\": 1,\n            \"satellite_name\": \"Sea-00001-2022\",\n            \"launch_date\": \"2022-01-07T12:11:23Z\",\n            \"deployment_date\": \"2022-01-07T12:11:23Z\",\n        }))\n    );\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/transaction_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, bakery_chain::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{\n    AccessMode, DatabaseTransaction, IsolationLevel, Set, SqliteTransactionMode,\n    TransactionOptions, TransactionTrait, prelude::*,\n};\n\n#[cfg(not(feature = \"sync\"))]\ntype FutureResult<'a> =\n    std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), DbErr>> + Send + 'a>>;\n#[cfg(feature = \"sync\")]\ntype FutureResult<'a> = Result<(), DbErr>;\n\nfn seaside_bakery() -> bakery::ActiveModel {\n    bakery::ActiveModel {\n        name: Set(\"SeaSide Bakery\".to_owned()),\n        profit_margin: Set(10.4),\n        ..Default::default()\n    }\n}\n\nfn top_bakery() -> bakery::ActiveModel {\n    bakery::ActiveModel {\n        name: Set(\"Top Bakery\".to_owned()),\n        profit_margin: Set(15.0),\n        ..Default::default()\n    }\n}\n\n#[sea_orm_macros::test]\npub async fn transaction() {\n    let ctx = TestContext::new(\"transaction_test\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    ctx.db\n        .transaction::<_, _, DbErr>(|txn| {\n            Box::pin(async move {\n                let _ = seaside_bakery().save(txn).await?;\n                let _ = top_bakery().save(txn).await?;\n\n                let bakeries = Bakery::find()\n                    .filter(bakery::Column::Name.contains(\"Bakery\"))\n                    .all(txn)\n                    .await?;\n\n                assert_eq!(bakeries.len(), 2);\n\n                Ok(())\n            })\n        })\n        .await\n        .unwrap();\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"rbac\")]\npub async fn rbac_transaction() {\n    use sea_orm::rbac::{RbacEngine, RbacSnapshot, RbacUserId};\n\n    let ctx = TestContext::new(\"rbac_transaction_test\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    ctx.db.replace_rbac(RbacEngine::from_snapshot(\n        RbacSnapshot::danger_unrestricted(),\n    ));\n    let db = ctx.db.restricted_for(RbacUserId(0)).unwrap();\n\n    db.transaction::<_, _, DbErr>(|txn| {\n        Box::pin(async move {\n            let _ = seaside_bakery().save(txn).await?;\n            let _ = top_bakery().save(txn).await?;\n\n            let bakeries = Bakery::find()\n                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                .all(txn)\n                .await?;\n\n            assert_eq!(bakeries.len(), 2);\n\n            Ok(())\n        })\n    })\n    .await\n    .unwrap();\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn transaction_with_reference() {\n    let ctx = TestContext::new(\"transaction_with_reference_test\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let name1 = \"SeaSide Bakery\";\n    let name2 = \"Top Bakery\";\n    let search_name = \"Bakery\";\n    ctx.db\n        .transaction(|txn| _transaction_with_reference(txn, name1, name2, search_name))\n        .await\n        .unwrap();\n\n    ctx.delete().await;\n}\n\nfn _transaction_with_reference<'a>(\n    txn: &'a DatabaseTransaction,\n    name1: &'a str,\n    name2: &'a str,\n    search_name: &'a str,\n) -> FutureResult<'a> {\n    Box::pin(async move {\n        let _ = bakery::ActiveModel {\n            name: Set(name1.to_owned()),\n            profit_margin: Set(10.4),\n            ..Default::default()\n        }\n        .save(txn)\n        .await?;\n\n        let _ = bakery::ActiveModel {\n            name: Set(name2.to_owned()),\n            profit_margin: Set(15.0),\n            ..Default::default()\n        }\n        .save(txn)\n        .await?;\n\n        let bakeries = Bakery::find()\n            .filter(bakery::Column::Name.contains(search_name))\n            .all(txn)\n            .await?;\n\n        assert_eq!(bakeries.len(), 2);\n\n        Ok(())\n    })\n}\n\n#[sea_orm_macros::test]\npub async fn transaction_begin_out_of_scope() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_begin_out_of_scope_test\").await;\n    create_bakery_table(&ctx.db).await?;\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db).await?.len(), 0);\n\n    {\n        // Transaction begin in this scope\n        let txn = ctx.db.begin().await?;\n\n        seaside_bakery().save(&txn).await?;\n\n        assert_eq!(bakery::Entity::find().all(&txn).await?.len(), 1);\n\n        top_bakery().save(&txn).await?;\n\n        assert_eq!(bakery::Entity::find().all(&txn).await?.len(), 2);\n\n        // The scope ended and transaction is dropped without commit\n    }\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db).await?.len(), 0);\n\n    ctx.delete().await;\n    Ok(())\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"rbac\")]\npub async fn rbac_transaction_begin_out_of_scope() -> Result<(), DbErr> {\n    use sea_orm::rbac::{RbacEngine, RbacSnapshot, RbacUserId};\n\n    let ctx = TestContext::new(\"rbac_transaction_begin_out_of_scope_test\").await;\n    create_bakery_table(&ctx.db).await?;\n\n    ctx.db.replace_rbac(RbacEngine::from_snapshot(\n        RbacSnapshot::danger_unrestricted(),\n    ));\n    let db = ctx.db.restricted_for(RbacUserId(0)).unwrap();\n\n    assert_eq!(bakery::Entity::find().all(&db).await?.len(), 0);\n\n    {\n        // Transaction begin in this scope\n        let txn = db.begin().await?;\n\n        seaside_bakery().save(&txn).await?;\n\n        assert_eq!(bakery::Entity::find().all(&txn).await?.len(), 1);\n\n        top_bakery().save(&txn).await?;\n\n        assert_eq!(bakery::Entity::find().all(&txn).await?.len(), 2);\n\n        // The scope ended and transaction is dropped without commit\n    }\n\n    assert_eq!(bakery::Entity::find().all(&db).await?.len(), 0);\n\n    ctx.delete().await;\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub async fn transaction_begin_commit() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_begin_commit_test\").await;\n    create_bakery_table(&ctx.db).await?;\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db).await?.len(), 0);\n\n    {\n        // Transaction begin in this scope\n        let txn = ctx.db.begin().await?;\n\n        seaside_bakery().save(&txn).await?;\n\n        assert_eq!(bakery::Entity::find().all(&txn).await?.len(), 1);\n\n        top_bakery().save(&txn).await?;\n\n        assert_eq!(bakery::Entity::find().all(&txn).await?.len(), 2);\n\n        // Commit changes before the end of scope\n        txn.commit().await?;\n    }\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db).await?.len(), 2);\n\n    ctx.delete().await;\n    Ok(())\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"rbac\")]\npub async fn rbac_transaction_begin_commit() -> Result<(), DbErr> {\n    use sea_orm::rbac::{RbacEngine, RbacSnapshot, RbacUserId};\n\n    let ctx = TestContext::new(\"rbac_transaction_begin_commit_test\").await;\n    create_bakery_table(&ctx.db).await?;\n\n    ctx.db.replace_rbac(RbacEngine::from_snapshot(\n        RbacSnapshot::danger_unrestricted(),\n    ));\n    let db = ctx.db.restricted_for(RbacUserId(0)).unwrap();\n\n    assert_eq!(bakery::Entity::find().all(&db).await?.len(), 0);\n\n    {\n        // Transaction begin in this scope\n        let txn = db.begin().await?;\n\n        seaside_bakery().save(&txn).await?;\n\n        assert_eq!(bakery::Entity::find().all(&txn).await?.len(), 1);\n\n        top_bakery().save(&txn).await?;\n\n        assert_eq!(bakery::Entity::find().all(&txn).await?.len(), 2);\n\n        // Commit changes before the end of scope\n        txn.commit().await?;\n    }\n\n    assert_eq!(bakery::Entity::find().all(&db).await?.len(), 2);\n\n    ctx.delete().await;\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub async fn transaction_begin_rollback() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_begin_rollback_test\").await;\n    create_bakery_table(&ctx.db).await?;\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db).await?.len(), 0);\n\n    {\n        // Transaction begin in this scope\n        let txn = ctx.db.begin().await?;\n\n        seaside_bakery().save(&txn).await?;\n\n        assert_eq!(bakery::Entity::find().all(&txn).await?.len(), 1);\n\n        top_bakery().save(&txn).await?;\n\n        assert_eq!(bakery::Entity::find().all(&txn).await?.len(), 2);\n\n        // Rollback changes before the end of scope\n        txn.rollback().await?;\n    }\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db).await?.len(), 0);\n\n    ctx.delete().await;\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub async fn transaction_closure_commit() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_closure_commit_test\").await;\n    create_bakery_table(&ctx.db).await?;\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db).await?.len(), 0);\n\n    let res = ctx\n        .db\n        .transaction::<_, _, DbErr>(|txn| {\n            Box::pin(async move {\n                seaside_bakery().save(txn).await?;\n\n                assert_eq!(bakery::Entity::find().all(txn).await?.len(), 1);\n\n                top_bakery().save(txn).await?;\n\n                assert_eq!(bakery::Entity::find().all(txn).await?.len(), 2);\n\n                Ok(())\n            })\n        })\n        .await;\n\n    assert!(res.is_ok());\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db).await?.len(), 2);\n\n    ctx.delete().await;\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub async fn transaction_closure_rollback() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_closure_rollback_test\").await;\n    create_bakery_table(&ctx.db).await?;\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db).await?.len(), 0);\n\n    let res = ctx\n        .db\n        .transaction::<_, _, DbErr>(|txn| {\n            Box::pin(async move {\n                seaside_bakery().save(txn).await?;\n\n                assert_eq!(bakery::Entity::find().all(txn).await?.len(), 1);\n\n                top_bakery().save(txn).await?;\n\n                assert_eq!(bakery::Entity::find().all(txn).await?.len(), 2);\n\n                bakery::ActiveModel {\n                    id: Set(1),\n                    name: Set(\"Duplicated primary key\".to_owned()),\n                    profit_margin: Set(20.0),\n                }\n                .insert(txn)\n                .await?; // Throw error and rollback\n\n                // This line won't be reached\n                unreachable!();\n\n                #[allow(unreachable_code)]\n                Ok(())\n            })\n        })\n        .await;\n\n    assert!(res.is_err());\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db).await?.len(), 0);\n\n    ctx.delete().await;\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub async fn transaction_with_active_model_behaviour() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_with_active_model_behaviour_test\").await;\n    create_bakery_table(&ctx.db).await?;\n    create_cake_table(&ctx.db).await?;\n\n    if let Ok(txn) = ctx.db.begin().await {\n        assert_eq!(\n            cake::ActiveModel {\n                name: Set(\"Cake with invalid price\".to_owned()),\n                price: Set(rust_dec(0)),\n                gluten_free: Set(false),\n                ..Default::default()\n            }\n            .save(&txn)\n            .await,\n            Err(DbErr::Custom(\n                \"[before_save] Invalid Price, insert: true\".to_owned()\n            ))\n        );\n\n        assert_eq!(cake::Entity::find().all(&txn).await?.len(), 0);\n\n        assert_eq!(\n            cake::ActiveModel {\n                name: Set(\"Cake with invalid price\".to_owned()),\n                price: Set(rust_dec(-10)),\n                gluten_free: Set(false),\n                ..Default::default()\n            }\n            .save(&txn)\n            .await,\n            Err(DbErr::Custom(\n                \"[after_save] Invalid Price, insert: true\".to_owned()\n            ))\n        );\n\n        assert_eq!(cake::Entity::find().all(&txn).await?.len(), 1);\n\n        let readonly_cake_1 = cake::ActiveModel {\n            name: Set(\"Readonly cake (err_on_before_delete)\".to_owned()),\n            price: Set(rust_dec(10)),\n            gluten_free: Set(true),\n            ..Default::default()\n        }\n        .save(&txn)\n        .await?;\n\n        assert_eq!(cake::Entity::find().all(&txn).await?.len(), 2);\n\n        assert_eq!(\n            readonly_cake_1.delete(&txn).await.err(),\n            Some(DbErr::Custom(\n                \"[before_delete] Cannot be deleted\".to_owned()\n            ))\n        );\n\n        assert_eq!(cake::Entity::find().all(&txn).await?.len(), 2);\n\n        let readonly_cake_2 = cake::ActiveModel {\n            name: Set(\"Readonly cake (err_on_after_delete)\".to_owned()),\n            price: Set(rust_dec(10)),\n            gluten_free: Set(true),\n            ..Default::default()\n        }\n        .save(&txn)\n        .await?;\n\n        assert_eq!(cake::Entity::find().all(&txn).await?.len(), 3);\n\n        assert_eq!(\n            readonly_cake_2.delete(&txn).await.err(),\n            Some(DbErr::Custom(\"[after_delete] Cannot be deleted\".to_owned()))\n        );\n\n        assert_eq!(cake::Entity::find().all(&txn).await?.len(), 2);\n    }\n\n    assert_eq!(cake::Entity::find().all(&ctx.db).await?.len(), 0);\n\n    ctx.delete().await;\n    Ok(())\n}\n\n#[sea_orm_macros::test]\npub async fn transaction_nested() {\n    let ctx = TestContext::new(\"transaction_nested_test\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    ctx.db\n        .transaction::<_, _, DbErr>(|txn| {\n            Box::pin(async move {\n                let _ = seaside_bakery().save(txn).await?;\n\n                let _ = top_bakery().save(txn).await?;\n\n                // Try nested transaction committed\n                txn.transaction::<_, _, DbErr>(|txn| {\n                    Box::pin(async move {\n                        let _ = bakery::ActiveModel {\n                            name: Set(\"Nested Bakery\".to_owned()),\n                            profit_margin: Set(88.88),\n                            ..Default::default()\n                        }\n                        .save(txn)\n                        .await?;\n\n                        let bakeries = Bakery::find()\n                            .filter(bakery::Column::Name.contains(\"Bakery\"))\n                            .all(txn)\n                            .await?;\n\n                        assert_eq!(bakeries.len(), 3);\n\n                        // Try nested-nested transaction rollbacked\n                        let is_err = txn\n                            .transaction::<_, _, DbErr>(|txn| {\n                                Box::pin(async move {\n                                    let _ = bakery::ActiveModel {\n                                        name: Set(\"Rock n Roll Bakery\".to_owned()),\n                                        profit_margin: Set(28.8),\n                                        ..Default::default()\n                                    }\n                                    .save(txn)\n                                    .await?;\n\n                                    let bakeries = Bakery::find()\n                                        .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                        .all(txn)\n                                        .await?;\n\n                                    assert_eq!(bakeries.len(), 4);\n\n                                    if true {\n                                        Err(DbErr::Query(RuntimeErr::Internal(\n                                            \"Force Rollback!\".to_owned(),\n                                        )))\n                                    } else {\n                                        Ok(())\n                                    }\n                                })\n                            })\n                            .await\n                            .is_err();\n\n                        assert!(is_err);\n\n                        let bakeries = Bakery::find()\n                            .filter(bakery::Column::Name.contains(\"Bakery\"))\n                            .all(txn)\n                            .await?;\n\n                        assert_eq!(bakeries.len(), 3);\n\n                        // Try nested-nested transaction committed\n                        txn.transaction::<_, _, DbErr>(|txn| {\n                            Box::pin(async move {\n                                let _ = bakery::ActiveModel {\n                                    name: Set(\"Rock n Roll Bakery\".to_owned()),\n                                    profit_margin: Set(28.8),\n                                    ..Default::default()\n                                }\n                                .save(txn)\n                                .await?;\n\n                                let bakeries = Bakery::find()\n                                    .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                    .all(txn)\n                                    .await?;\n\n                                assert_eq!(bakeries.len(), 4);\n\n                                Ok(())\n                            })\n                        })\n                        .await\n                        .unwrap();\n\n                        let bakeries = Bakery::find()\n                            .filter(bakery::Column::Name.contains(\"Bakery\"))\n                            .all(txn)\n                            .await?;\n\n                        assert_eq!(bakeries.len(), 4);\n\n                        Ok(())\n                    })\n                })\n                .await\n                .unwrap();\n\n                // Try nested transaction rollbacked\n                let is_err = txn\n                    .transaction::<_, _, DbErr>(|txn| {\n                        Box::pin(async move {\n                            let _ = bakery::ActiveModel {\n                                name: Set(\"Rock n Roll Bakery\".to_owned()),\n                                profit_margin: Set(28.8),\n                                ..Default::default()\n                            }\n                            .save(txn)\n                            .await?;\n\n                            let bakeries = Bakery::find()\n                                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                .all(txn)\n                                .await?;\n\n                            assert_eq!(bakeries.len(), 5);\n\n                            // Try nested-nested transaction committed\n                            txn.transaction::<_, _, DbErr>(|txn| {\n                                Box::pin(async move {\n                                    let _ = bakery::ActiveModel {\n                                        name: Set(\"Rock n Roll Bakery\".to_owned()),\n                                        profit_margin: Set(28.8),\n                                        ..Default::default()\n                                    }\n                                    .save(txn)\n                                    .await?;\n\n                                    let bakeries = Bakery::find()\n                                        .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                        .all(txn)\n                                        .await?;\n\n                                    assert_eq!(bakeries.len(), 6);\n\n                                    Ok(())\n                                })\n                            })\n                            .await\n                            .unwrap();\n\n                            let bakeries = Bakery::find()\n                                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                .all(txn)\n                                .await?;\n\n                            assert_eq!(bakeries.len(), 6);\n\n                            // Try nested-nested transaction rollbacked\n                            let is_err = txn\n                                .transaction::<_, _, DbErr>(|txn| {\n                                    Box::pin(async move {\n                                        let _ = bakery::ActiveModel {\n                                            name: Set(\"Rock n Roll Bakery\".to_owned()),\n                                            profit_margin: Set(28.8),\n                                            ..Default::default()\n                                        }\n                                        .save(txn)\n                                        .await?;\n\n                                        let bakeries = Bakery::find()\n                                            .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                            .all(txn)\n                                            .await?;\n\n                                        assert_eq!(bakeries.len(), 7);\n\n                                        if true {\n                                            Err(DbErr::Query(RuntimeErr::Internal(\n                                                \"Force Rollback!\".to_owned(),\n                                            )))\n                                        } else {\n                                            Ok(())\n                                        }\n                                    })\n                                })\n                                .await\n                                .is_err();\n\n                            assert!(is_err);\n\n                            let bakeries = Bakery::find()\n                                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                .all(txn)\n                                .await?;\n\n                            assert_eq!(bakeries.len(), 6);\n\n                            if true {\n                                Err(DbErr::Query(RuntimeErr::Internal(\n                                    \"Force Rollback!\".to_owned(),\n                                )))\n                            } else {\n                                Ok(())\n                            }\n                        })\n                    })\n                    .await\n                    .is_err();\n\n                assert!(is_err);\n\n                let bakeries = Bakery::find()\n                    .filter(bakery::Column::Name.contains(\"Bakery\"))\n                    .all(txn)\n                    .await?;\n\n                assert_eq!(bakeries.len(), 4);\n\n                Ok(())\n            })\n        })\n        .await\n        .unwrap();\n\n    let bakeries = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Bakery\"))\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(bakeries.len(), 4);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn transaction_manager_nested() -> Result<(), sea_orm::DbErr> {\n    let ctx = TestContext::new(\"transaction_manager_nested\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    let txn = ctx.db.begin().await?;\n    let _ = seaside_bakery().save(&txn).await?;\n    let _ = top_bakery().save(&txn).await?;\n\n    // Try nested transaction committed\n    {\n        let txn = txn.begin().await?;\n        let _ = bakery::ActiveModel {\n            name: Set(\"Nested Bakery\".to_owned()),\n            profit_margin: Set(88.88),\n            ..Default::default()\n        }\n        .save(&txn)\n        .await?;\n\n        let bakeries = Bakery::find()\n            .filter(bakery::Column::Name.contains(\"Bakery\"))\n            .all(&txn)\n            .await?;\n\n        assert_eq!(bakeries.len(), 3);\n\n        // Try nested-nested transaction rollbacked\n        {\n            let txn = txn.begin().await?;\n            let _ = bakery::ActiveModel {\n                name: Set(\"Rock n Roll Bakery\".to_owned()),\n                profit_margin: Set(28.8),\n                ..Default::default()\n            }\n            .save(&txn)\n            .await?;\n\n            let bakeries = Bakery::find()\n                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                .all(&txn)\n                .await?;\n\n            assert_eq!(bakeries.len(), 4);\n        }\n\n        let bakeries = Bakery::find()\n            .filter(bakery::Column::Name.contains(\"Bakery\"))\n            .all(&txn)\n            .await?;\n\n        assert_eq!(bakeries.len(), 3);\n\n        // Try nested-nested transaction committed\n        {\n            let txn = txn.begin().await?;\n            let _ = bakery::ActiveModel {\n                name: Set(\"Rock n Roll Bakery\".to_owned()),\n                profit_margin: Set(28.8),\n                ..Default::default()\n            }\n            .save(&txn)\n            .await?;\n\n            let bakeries = Bakery::find()\n                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                .all(&txn)\n                .await?;\n\n            assert_eq!(bakeries.len(), 4);\n            txn.commit().await?;\n        }\n\n        txn.commit().await?;\n    }\n\n    // Try nested transaction rollbacked\n    {\n        let txn = txn.begin().await?;\n        let _ = bakery::ActiveModel {\n            name: Set(\"Rock n Roll Bakery\".to_owned()),\n            profit_margin: Set(28.8),\n            ..Default::default()\n        }\n        .save(&txn)\n        .await?;\n\n        let bakeries = Bakery::find()\n            .filter(bakery::Column::Name.contains(\"Bakery\"))\n            .all(&txn)\n            .await?;\n\n        assert_eq!(bakeries.len(), 5);\n\n        // Try nested-nested transaction committed\n        {\n            let txn = txn.begin().await?;\n            let _ = bakery::ActiveModel {\n                name: Set(\"Rock n Roll Bakery\".to_owned()),\n                profit_margin: Set(28.8),\n                ..Default::default()\n            }\n            .save(&txn)\n            .await?;\n\n            let bakeries = Bakery::find()\n                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                .all(&txn)\n                .await?;\n\n            assert_eq!(bakeries.len(), 6);\n            txn.commit().await?;\n        }\n\n        let bakeries = Bakery::find()\n            .filter(bakery::Column::Name.contains(\"Bakery\"))\n            .all(&txn)\n            .await?;\n\n        assert_eq!(bakeries.len(), 6);\n    }\n\n    let bakeries = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Bakery\"))\n        .all(&txn)\n        .await?;\n\n    assert_eq!(bakeries.len(), 4);\n\n    txn.commit().await?;\n\n    let bakeries = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Bakery\"))\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(bakeries.len(), 4);\n\n    ctx.delete().await;\n\n    Ok(())\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"rbac\")]\npub async fn rbac_transaction_nested() {\n    use sea_orm::rbac::{RbacEngine, RbacSnapshot, RbacUserId};\n\n    let ctx = TestContext::new(\"rbac_transaction_nested_test\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    ctx.db.replace_rbac(RbacEngine::from_snapshot(\n        RbacSnapshot::danger_unrestricted(),\n    ));\n    let db = ctx.db.restricted_for(RbacUserId(0)).unwrap();\n\n    db.transaction::<_, _, DbErr>(|txn| {\n        Box::pin(async move {\n            let _ = seaside_bakery().save(txn).await?;\n\n            let _ = top_bakery().save(txn).await?;\n\n            // Try nested transaction committed\n            txn.transaction::<_, _, DbErr>(|txn| {\n                Box::pin(async move {\n                    let _ = bakery::ActiveModel {\n                        name: Set(\"Nested Bakery\".to_owned()),\n                        profit_margin: Set(88.88),\n                        ..Default::default()\n                    }\n                    .save(txn)\n                    .await?;\n\n                    let bakeries = Bakery::find()\n                        .filter(bakery::Column::Name.contains(\"Bakery\"))\n                        .all(txn)\n                        .await?;\n\n                    assert_eq!(bakeries.len(), 3);\n\n                    // Try nested-nested transaction committed\n                    txn.transaction::<_, _, DbErr>(|txn| {\n                        Box::pin(async move {\n                            let _ = bakery::ActiveModel {\n                                name: Set(\"Rock n Roll Bakery\".to_owned()),\n                                profit_margin: Set(28.8),\n                                ..Default::default()\n                            }\n                            .save(txn)\n                            .await?;\n\n                            let bakeries = Bakery::find()\n                                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                                .all(txn)\n                                .await?;\n\n                            assert_eq!(bakeries.len(), 4);\n\n                            Ok(())\n                        })\n                    })\n                    .await\n                    .unwrap();\n\n                    let bakeries = Bakery::find()\n                        .filter(bakery::Column::Name.contains(\"Bakery\"))\n                        .all(txn)\n                        .await?;\n\n                    assert_eq!(bakeries.len(), 4);\n\n                    Ok(())\n                })\n            })\n            .await\n            .unwrap();\n\n            let bakeries = Bakery::find()\n                .filter(bakery::Column::Name.contains(\"Bakery\"))\n                .all(txn)\n                .await?;\n\n            assert_eq!(bakeries.len(), 4);\n\n            Ok(())\n        })\n    })\n    .await\n    .unwrap();\n\n    let bakeries = Bakery::find()\n        .filter(bakery::Column::Name.contains(\"Bakery\"))\n        .all(&ctx.db)\n        .await\n        .unwrap();\n\n    assert_eq!(bakeries.len(), 4);\n\n    ctx.delete().await;\n}\n\n#[sea_orm_macros::test]\npub async fn transaction_with_config() {\n    let ctx = TestContext::new(\"transaction_with_config\").await;\n    create_bakery_table(&ctx.db).await.unwrap();\n\n    for (i, (isolation_level, access_mode)) in [\n        (IsolationLevel::RepeatableRead, None),\n        (IsolationLevel::ReadCommitted, None),\n        (IsolationLevel::ReadUncommitted, Some(AccessMode::ReadWrite)),\n        (IsolationLevel::Serializable, Some(AccessMode::ReadWrite)),\n    ]\n    .into_iter()\n    .enumerate()\n    {\n        let name1 = format!(\"SeaSide Bakery {}\", i);\n        let name2 = format!(\"Top Bakery {}\", i);\n        let search_name = format!(\"Bakery {}\", i);\n        ctx.db\n            .transaction_with_config(\n                |txn| _transaction_with_config(txn, name1, name2, search_name),\n                Some(isolation_level),\n                access_mode,\n            )\n            .await\n            .unwrap();\n    }\n\n    ctx.db\n        .transaction_with_config::<_, _, DbErr>(\n            |txn| {\n                Box::pin(async move {\n                    let bakeries = Bakery::find()\n                        .filter(bakery::Column::Name.contains(\"Bakery\"))\n                        .all(txn)\n                        .await?;\n\n                    assert_eq!(bakeries.len(), 8);\n\n                    Ok(())\n                })\n            },\n            None,\n            Some(AccessMode::ReadOnly),\n        )\n        .await\n        .unwrap();\n\n    ctx.delete().await;\n}\n\nfn _transaction_with_config<'a>(\n    txn: &'a DatabaseTransaction,\n    name1: String,\n    name2: String,\n    search_name: String,\n) -> FutureResult<'a> {\n    Box::pin(async move {\n        let _ = bakery::ActiveModel {\n            name: Set(name1),\n            profit_margin: Set(10.4),\n            ..Default::default()\n        }\n        .save(txn)\n        .await?;\n\n        let _ = bakery::ActiveModel {\n            name: Set(name2),\n            profit_margin: Set(15.0),\n            ..Default::default()\n        }\n        .save(txn)\n        .await?;\n\n        let bakeries = Bakery::find()\n            .filter(bakery::Column::Name.contains(&search_name))\n            .all(txn)\n            .await?;\n\n        assert_eq!(bakeries.len(), 2);\n\n        Ok(())\n    })\n}\n\n#[sea_orm_macros::test]\npub async fn transaction_begin_with_options() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"transaction_begin_with_options_test\").await;\n    create_tables(&ctx.db).await?;\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db).await?.len(), 0);\n\n    {\n        // Transaction begin in this scope\n        let txn = ctx\n            .db\n            .begin_with_options(TransactionOptions {\n                sqlite_transaction_mode: Some(SqliteTransactionMode::Immediate),\n                ..Default::default()\n            })\n            .await?;\n\n        seaside_bakery().save(&txn).await?;\n\n        assert_eq!(bakery::Entity::find().all(&txn).await?.len(), 1);\n\n        top_bakery().save(&txn).await?;\n\n        assert_eq!(bakery::Entity::find().all(&txn).await?.len(), 2);\n\n        // Commit changes before the end of scope\n        txn.commit().await?;\n    }\n\n    assert_eq!(bakery::Entity::find().all(&ctx.db).await?.len(), 2);\n\n    ctx.delete().await;\n    Ok(())\n}\n"
  },
  {
    "path": "tests/type_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse sea_orm::{IntoActiveValue, TryFromU64, TryGetable, Value};\n\n/*\n\nWhen supporting a new type in SeaORM we should implement the following traits for it:\n  - `IntoActiveValue`, given that it implemented `Into<Value>` already\n  - `TryGetable`\n  - `TryFromU64`\n\nAlso, we need to update `impl FromQueryResult for JsonValue` at `src/query/json.rs`\nto correctly serialize the type as `serde_json::Value`.\n\n*/\n\npub fn it_impl_into_active_value<T: IntoActiveValue<V>, V: Into<Value>>() {}\n\npub fn it_impl_try_getable<T: TryGetable>() {}\n\npub fn it_impl_try_from_u64<T: TryFromU64>() {}\n\n#[allow(unused_macros)]\nmacro_rules! it_impl_traits {\n    ( $ty: ty ) => {\n        it_impl_into_active_value::<$ty, $ty>();\n        it_impl_into_active_value::<Option<$ty>, $ty>();\n        it_impl_into_active_value::<Option<Option<$ty>>, Option<$ty>>();\n\n        it_impl_try_getable::<$ty>();\n        it_impl_try_getable::<Option<$ty>>();\n\n        it_impl_try_from_u64::<$ty>();\n    };\n}\n\n#[sea_orm_macros::test]\n#[cfg(feature = \"sqlx-dep\")]\nfn main() {\n    it_impl_traits!(i8);\n    it_impl_traits!(i16);\n    it_impl_traits!(i32);\n    it_impl_traits!(i64);\n    it_impl_traits!(u8);\n    it_impl_traits!(u16);\n    it_impl_traits!(u32);\n    it_impl_traits!(u64);\n    it_impl_traits!(bool);\n    it_impl_traits!(f32);\n    it_impl_traits!(f64);\n    it_impl_traits!(Vec<u8>);\n    it_impl_traits!(String);\n    it_impl_traits!(serde_json::Value);\n    it_impl_traits!(chrono::NaiveDate);\n    it_impl_traits!(chrono::NaiveTime);\n    it_impl_traits!(chrono::NaiveDateTime);\n    it_impl_traits!(chrono::DateTime<chrono::FixedOffset>);\n    it_impl_traits!(chrono::DateTime<chrono::Utc>);\n    it_impl_traits!(chrono::DateTime<chrono::Local>);\n    it_impl_traits!(time::Date);\n    it_impl_traits!(time::Time);\n    it_impl_traits!(time::PrimitiveDateTime);\n    it_impl_traits!(time::OffsetDateTime);\n    it_impl_traits!(rust_decimal::Decimal);\n    it_impl_traits!(uuid::Uuid);\n    #[cfg(feature = \"with-ipnetwork\")]\n    it_impl_traits!(ipnetwork::IpNetwork);\n    it_impl_traits!(common::features::value_type::MyUserId);\n}\n"
  },
  {
    "path": "tests/upsert_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::TryInsertResult;\nuse sea_orm::entity::prelude::*;\nuse sea_orm::{Set, sea_query::OnConflict};\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"upsert_tests\").await;\n    create_insert_default_table(&ctx.db).await?;\n    create_insert_default(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn create_insert_default(db: &DatabaseConnection) -> Result<(), DbErr> {\n    use insert_default::*;\n\n    let res = Entity::insert_many::<ActiveModel, _>([]).exec(db).await;\n\n    assert_eq!(res?.last_insert_id, None);\n\n    let res = Entity::insert_many([ActiveModel { id: Set(1) }, ActiveModel { id: Set(2) }])\n        .exec(db)\n        .await;\n\n    assert_eq!(res?.last_insert_id, Some(2));\n\n    let on_conflict = OnConflict::column(Column::Id)\n        .do_nothing_on([Column::Id])\n        .to_owned();\n\n    let res = Entity::insert_many([\n        ActiveModel { id: Set(1) },\n        ActiveModel { id: Set(2) },\n        ActiveModel { id: Set(3) },\n    ])\n    .on_conflict(on_conflict.clone())\n    .exec(db)\n    .await;\n\n    assert_eq!(res?.last_insert_id, Some(3));\n\n    let res = Entity::insert_many([\n        ActiveModel { id: Set(1) },\n        ActiveModel { id: Set(2) },\n        ActiveModel { id: Set(3) },\n        ActiveModel { id: Set(4) },\n    ])\n    .on_conflict(on_conflict.clone())\n    .exec(db)\n    .await;\n\n    assert_eq!(res?.last_insert_id, Some(4));\n\n    let res = Entity::insert_many([ActiveModel { id: Set(3) }, ActiveModel { id: Set(4) }])\n        .exec(db)\n        .await;\n\n    assert!(matches!(res, Err(DbErr::Query(_) | DbErr::Exec(_))));\n\n    let res = Entity::insert_many([ActiveModel { id: Set(3) }, ActiveModel { id: Set(4) }])\n        .on_conflict(on_conflict.clone())\n        .exec(db)\n        .await;\n\n    assert!(matches!(res, Err(DbErr::RecordNotInserted)));\n\n    let res = Entity::insert_many([ActiveModel { id: Set(3) }, ActiveModel { id: Set(4) }])\n        .on_conflict_do_nothing_on([Column::Id])\n        .exec(db)\n        .await;\n\n    assert!(matches!(res, Ok(TryInsertResult::Conflicted)));\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/uuid_fmt_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, FromQueryResult, entity::prelude::*, entity::*};\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"uuid_fmt_tests\").await;\n    create_uuid_fmt_table(&ctx.db).await?;\n    insert_uuid_fmt(&ctx.db).await?;\n    test_text_uuid(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn insert_uuid_fmt(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let uuid = Uuid::new_v4();\n\n    let uuid_fmt = uuid_fmt::Model {\n        id: 1,\n        uuid,\n        uuid_braced: uuid.braced(),\n        uuid_hyphenated: uuid.hyphenated(),\n        uuid_simple: uuid.simple(),\n        uuid_urn: uuid.urn(),\n    };\n\n    let result = uuid_fmt.clone().into_active_model().insert(db).await?;\n\n    assert_eq!(result, uuid_fmt);\n\n    Ok(())\n}\n\nmod uuid_fmt_more {\n    use sea_orm::entity::prelude::*;\n\n    #[sea_orm::model]\n    #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]\n    #[sea_orm(table_name = \"uuid_fmt_more\")]\n    pub struct Model {\n        #[sea_orm(primary_key)]\n        pub id: i32,\n        #[sea_orm(unique)]\n        pub iden: TextUuid,\n    }\n\n    impl ActiveModelBehavior for ActiveModel {}\n}\n\npub async fn test_text_uuid(db: &DatabaseConnection) -> Result<(), DbErr> {\n    // ensure that column is typed\n    let _iden: sea_orm::TextUuidColumn<uuid_fmt_more::Entity> = uuid_fmt_more::COLUMN.iden;\n\n    db.get_schema_builder()\n        .register(uuid_fmt_more::Entity)\n        .apply(db)\n        .await?;\n\n    #[derive(FromQueryResult)]\n    struct UuidFmtMore {\n        id: i32,\n        iden: String, // no casting needed\n    }\n\n    let uuid = Uuid::new_v4();\n    let model = uuid_fmt_more::ActiveModel {\n        iden: Set(uuid.into()),\n        ..Default::default()\n    };\n\n    let result = model.insert(db).await?;\n    assert_eq!(result.iden.0, uuid);\n\n    let result: UuidFmtMore = uuid_fmt_more::Entity::find_by_id(result.id)\n        .into_model()\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(result.iden, uuid.to_string());\n\n    uuid_fmt_more::ActiveModel {\n        iden: Set(Uuid::new_v4().into()),\n        ..Default::default()\n    }\n    .insert(db)\n    .await?;\n\n    let result = uuid_fmt_more::Entity::find_by_iden(uuid)\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(result.iden.0, uuid);\n\n    let result = uuid_fmt_more::Entity::find()\n        .filter(uuid_fmt_more::COLUMN.iden.eq(uuid))\n        .one(db)\n        .await?\n        .unwrap();\n\n    assert_eq!(result.iden.0, uuid);\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/uuid_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\npub use common::{TestContext, features::*, setup::*};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{DatabaseConnection, entity::prelude::*, entity::*};\nuse serde_json::json;\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    let ctx = TestContext::new(\"bakery_chain_uuid_tests\").await;\n    create_metadata_table(&ctx.db).await?;\n    create_and_update_metadata(&ctx.db).await?;\n    insert_metadata(&ctx.db).await?;\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn insert_metadata(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let metadata = metadata::Model {\n        uuid: Uuid::new_v4(),\n        ty: \"Type\".to_owned(),\n        key: \"markup\".to_owned(),\n        value: \"1.18\".to_owned(),\n        bytes: vec![1, 2, 3],\n        date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()),\n        time: Some(Time::from_hms_opt(11, 32, 55).unwrap()),\n    };\n\n    let result = metadata.clone().into_active_model().insert(db).await?;\n\n    assert_eq!(result, metadata);\n\n    let mut json = metadata::Entity::find()\n        .filter(metadata::Column::Uuid.eq(metadata.uuid))\n        .into_json()\n        .one(db)\n        .await?;\n\n    #[cfg(feature = \"rusqlite\")]\n    {\n        json.as_mut()\n            .unwrap()\n            .as_object_mut()\n            .unwrap()\n            .remove(\"uuid\");\n        // rusqlite current has no rich type info to properly deserialize a uuid\n        assert_eq!(\n            json,\n            Some(json!({\n                \"type\": metadata.ty,\n                \"key\": metadata.key,\n                \"value\": metadata.value,\n                \"bytes\": metadata.bytes,\n                \"date\": metadata.date,\n                \"time\": metadata.time,\n            }))\n        );\n    }\n    #[cfg(not(feature = \"rusqlite\"))]\n    {\n        assert_eq!(\n            json,\n            Some(json!({\n                \"uuid\": metadata.uuid,\n                \"type\": metadata.ty,\n                \"key\": metadata.key,\n                \"value\": metadata.value,\n                \"bytes\": metadata.bytes,\n                \"date\": metadata.date,\n                \"time\": metadata.time,\n            }))\n        );\n    }\n\n    Ok(())\n}\n\npub async fn create_and_update_metadata(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let metadata = metadata::Model {\n        uuid: Uuid::new_v4(),\n        ty: \"Type\".to_owned(),\n        key: \"markup\".to_owned(),\n        value: \"1.18\".to_owned(),\n        bytes: vec![1, 2, 3],\n        date: Some(Date::from_ymd_opt(2021, 9, 27).unwrap()),\n        time: Some(Time::from_hms_opt(11, 32, 55).unwrap()),\n    };\n\n    let res = Metadata::insert(metadata.clone().into_active_model())\n        .exec(db)\n        .await?;\n\n    assert_eq!(Metadata::find().one(db).await?, Some(metadata.clone()));\n\n    assert_eq!(res.last_insert_id, metadata.uuid);\n\n    let update_res = Metadata::update(metadata::ActiveModel {\n        value: Set(\"0.22\".to_owned()),\n        ..metadata.clone().into_active_model()\n    })\n    .validate()?\n    .filter(metadata::Column::Uuid.eq(Uuid::default()))\n    .exec(db)\n    .await;\n\n    assert_eq!(update_res, Err(DbErr::RecordNotUpdated));\n\n    Ok(())\n}\n"
  },
  {
    "path": "tests/value_type_tests.rs",
    "content": "#![allow(unused_imports, dead_code)]\n\npub mod common;\n\nuse std::sync::Arc;\nuse std::vec;\n\npub use common::{\n    TestContext,\n    features::{\n        value_type::{\n            MyInteger, StringVec, Tag1, Tag2, Tag3, Tag4, Tag5, value_type_general, value_type_pg,\n            value_type_pk,\n        },\n        *,\n    },\n    setup::*,\n};\nuse pretty_assertions::assert_eq;\nuse sea_orm::{\n    DatabaseConnection, DbBackend, QuerySelect,\n    entity::{prelude::*, *},\n};\nuse sea_query::{ArrayType, ColumnType, PostgresQueryBuilder, Value, ValueType, ValueTypeErr};\n\n#[sea_orm_macros::test]\nasync fn main() -> Result<(), DbErr> {\n    type_test();\n    conversion_test();\n\n    let ctx = TestContext::new(\"value_type_tests\").await;\n\n    create_value_type_table(&ctx.db).await?;\n    insert_value_general(&ctx.db).await?;\n    insert_value_pk(&ctx.db).await?;\n\n    if cfg!(feature = \"sqlx-postgres\") {\n        create_value_type_postgres_table(&ctx.db).await?;\n        insert_value_postgres(&ctx.db).await?;\n    }\n\n    ctx.delete().await;\n\n    Ok(())\n}\n\npub async fn insert_value_general(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let model = value_type_general::Model {\n        id: 1,\n        number: 48.into(),\n        tag_1: Tag1::Hard,\n        tag_2: Tag2::Grey,\n    };\n    let result = model.clone().into_active_model().insert(db).await?;\n    assert_eq!(result, model);\n\n    Ok(())\n}\n\npub async fn insert_value_pk(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let model = value_type_pk::Model {\n        id: MyInteger(1),\n        val: MyInteger(2),\n    };\n    let result = model.clone().into_active_model().insert(db).await?;\n    assert_eq!(result, model);\n\n    let mut model = result.into_active_model();\n    model.val = Set(MyInteger(3));\n    model.save(db).await?;\n    assert_eq!(\n        value_type_pk::Entity::find_by_id(MyInteger(1))\n            .one(db)\n            .await?\n            .unwrap()\n            .val,\n        MyInteger(3)\n    );\n\n    Ok(())\n}\n\npub async fn insert_value_postgres(db: &DatabaseConnection) -> Result<(), DbErr> {\n    let model = value_type_pg::Model {\n        id: 1,\n        number: 48.into(),\n        str_vec: StringVec(vec![\"ab\".to_string(), \"cd\".to_string()]),\n    };\n    let result = model.clone().into_active_model().insert(db).await?;\n    assert_eq!(result, model);\n\n    let query = sea_query::Query::select()\n        .from(value_type_pg::Entity)\n        .column((value_type_pg::Entity, value_type_pg::Column::Number))\n        .and_where(value_type_pg::Column::Id.eq(1))\n        .take();\n\n    let row = db.query_one(&query).await?.unwrap();\n    let value: u32 = row.try_get(\"\", \"number\").unwrap();\n    assert_eq!(value, 48u32);\n\n    Ok(())\n}\n\npub fn type_test() {\n    assert_eq!(MyInteger::type_name(), \"MyInteger\");\n    assert_eq!(StringVec::type_name(), \"StringVec\");\n\n    assert_eq!(MyInteger::column_type(), ColumnType::Integer);\n    assert_eq!(MyInteger::array_type(), ArrayType::Int);\n\n    assert!(matches!(Tag1::column_type(), ColumnType::String(_)));\n    assert_eq!(Tag1::array_type(), ArrayType::String);\n\n    assert!(matches!(Tag3::column_type(), ColumnType::String(_)));\n    assert_eq!(Tag3::array_type(), ArrayType::String);\n\n    assert!(matches!(Tag4::column_type(), ColumnType::String(_)));\n    assert_eq!(Tag4::array_type(), ArrayType::String);\n\n    assert!(matches!(Tag5::column_type(), ColumnType::String(_)));\n    assert_eq!(Tag5::array_type(), ArrayType::String);\n\n    let tag_3 = Tag3 { i: 22 };\n    let tag_3_val: Value = tag_3.into();\n    assert_eq!(tag_3_val, \"22\".into());\n    let tag_3_: Tag3 = ValueType::try_from(tag_3_val).unwrap();\n    assert_eq!(tag_3_, tag_3);\n\n    let tag_4 = Tag4(22);\n    let tag_4_val: Value = tag_4.into();\n    assert_eq!(tag_4_val, \"22\".into());\n    let tag_4_: Tag4 = ValueType::try_from(tag_4_val).unwrap();\n    assert_eq!(tag_4_, tag_4);\n\n    let tag_5 = Tag5(std::path::PathBuf::from(\"foo/bar\"));\n    let tag_5_val: Value = tag_5.clone().into();\n    assert_eq!(tag_5_val, \"foo/bar\".into());\n    let tag_5_: Tag5 = ValueType::try_from(tag_5_val).unwrap();\n    assert_eq!(tag_5_, tag_5);\n\n    assert_eq!(\n        StringVec::column_type(),\n        ColumnType::Array(Arc::new(ColumnType::String(StringLen::None)))\n    );\n    assert_eq!(StringVec::array_type(), ArrayType::String);\n}\n\npub fn conversion_test() {\n    let stringvec = StringVec(vec![\"ab\".to_string(), \"cd\".to_string()]);\n    let string: Value = stringvec.into();\n    let expected: Value = vec![\"ab\".to_string(), \"cd\".to_string()].into();\n    assert_eq!(string, expected);\n\n    let value_random_int = Value::Int(Some(523));\n    let unwrap_int = MyInteger::unwrap(value_random_int.clone());\n    let try_from_int =\n        <MyInteger as ValueType>::try_from(value_random_int).expect(\"should be ok to convert\");\n\n    // tests for unwrap and try_from\n    let direct_int: MyInteger = 523.into();\n    assert_eq!(direct_int, unwrap_int);\n    assert_eq!(direct_int, try_from_int);\n\n    // test for error\n    let try_from_string_vec = <StringVec as ValueType>::try_from(Value::Char(Some('a')))\n        .expect_err(\"should not be ok to convert char to stringvec\");\n    assert_eq!(try_from_string_vec.to_string(), ValueTypeErr.to_string());\n}\n"
  }
]